On Wed, Apr 05, 2017 at 04:48:34PM -0700, Steve Beattie wrote: > Bug: https://bugs.launchpad.net/bugs/1674245 > > Signed-off-by: Steve Beattie <[email protected]>
Acked-by: Seth Arnold <[email protected]> Thanks > --- > tests/regression/apparmor/readdir.c | 129 > ++++++++++++++++++++++++++++------- > tests/regression/apparmor/readdir.sh | 21 ++++- > 2 files changed, 120 insertions(+), 30 deletions(-) > > Index: b/tests/regression/apparmor/readdir.c > =================================================================== > --- a/tests/regression/apparmor/readdir.c > +++ b/tests/regression/apparmor/readdir.c > @@ -1,14 +1,20 @@ > /* > * Copyright (C) 2002-2006 Novell/SUSE > + * Copyright (C) 2017 Canonical, Ltd. > * > * This program is free software; you can redistribute it and/or > * modify it under the terms of the GNU General Public License as > * published by the Free Software Foundation, version 2 of the > * License. > + * > + * We attempt to test both getdents() and getdents64() here, but > + * some architectures like aarch64 only support getdents64(). > */ > #define _GNU_SOURCE > > #include <stdio.h> > +#include <stdlib.h> > +#include <stdarg.h> > #include <unistd.h> > #include <errno.h> > #include <fcntl.h> > @@ -18,45 +24,118 @@ > #include <string.h> > #include <sys/syscall.h> > > -int main(int argc, char *argv[]) > +/* error if neither SYS_getdents or SYS_getdents64 is defined */ > +#if !defined(SYS_getdents) && !defined(SYS_getdents64) > + #error "Neither SYS_getdents or SYS_getdents64 is defined, something has > gone wrong!" > +#endif > + > +/* define DEBUG to enable debugging statements i.e. gcc -DDEBUG */ > +#ifdef DEBUG > +void pdebug(const char *format, ...) > { > - int fd; > -#if defined(SYS_getdents64) > - struct dirent64 dir; > + va_list arg; > + > + va_start(arg, format); > + vprintf(format, arg); > + va_end(arg); > +} > #else > - struct dirent dir; > +void pdebug(const char *format, ...) { return; } > #endif > > - if (argc != 2){ > - fprintf(stderr, "usage: %s dir\n", > - argv[0]); > - return 1; > +#ifdef SYS_getdents > +int my_readdir(char *dirname) > +{ > + int fd; > + struct dirent dir; > + > + fd = open(dirname, O_RDONLY, 0); > + if (fd == -1) { > + pdebug("open failed: %s\n", strerror(errno)); > + return errno; > } > > - fd = open(argv[1], O_RDONLY, 0); > - if (fd == -1){ > - printf("FAIL - open %s\n", strerror(errno)); > - return 1; > + /* getdents isn't exported by glibc, so must use syscall() */ > + if (syscall(SYS_getdents, fd, &dir, sizeof(dir)) == -1){ > + pdebug("getdents failed: %s\n", strerror(errno)); > + close(fd); > + return errno; > } > > - /* > - if (fchdir(fd) == -1){ > - printf("FAIL - fchdir %s\n", strerror(errno)); > - return 1; > + close(fd); > + return 0; > +} > +#endif > + > +#ifdef SYS_getdents64 > +int my_readdir64(char *dirname) > +{ > + int fd; > + struct dirent64 dir; > + > + fd = open(dirname, O_RDONLY, 0); > + if (fd == -1) { > + pdebug("open failed: %s\n", strerror(errno)); > + return errno; > } > - */ > > /* getdents isn't exported by glibc, so must use syscall() */ > -#if defined(SYS_getdents64) > - if (syscall(SYS_getdents64, fd, &dir, sizeof(struct dirent64)) == -1){ > -#else > - if (syscall(SYS_getdents, fd, &dir, sizeof(struct dirent)) == -1){ > + if (syscall(SYS_getdents64, fd, &dir, sizeof(dir)) == -1){ > + pdebug("getdents64 failed: %s\n", strerror(errno)); > + close(fd); > + return errno; > + } > + > + close(fd); > + return 0; > +} > #endif > - printf("FAIL - getdents %s\n", strerror(errno)); > - return 1; > + > +int main(int argc, char *argv[]) > +{ > + int rc = 0, err = 0; > + char *dirpath, *endptr; > + int expected; > + > + if (argc != 3) { > + fprintf(stderr, "usage: %s [dir] [expected retval]\n", > + argv[0]); > + err = 1; > + goto err; > } > > + dirpath = argv[1]; > + > + errno = 0; > + expected = (int) strtol(argv[2], &endptr, 10); > + if (errno != 0 || endptr == argv[2]) { > + fprintf(stderr, "ERROR: couldn't convert '%s' to an integer\n", > + argv[2]); > + err = 1; > + goto err; > + } > + pdebug("expected = %d\n", expected); > + > +#ifdef SYS_getdents > + rc = my_readdir(dirpath); > + if (rc != expected) { > + printf("FAIL - my_readdir returned %d, expected %d\n", rc, > expected); > + err = rc; > + goto err; > + } > +#endif > + > +#ifdef SYS_getdents64 > + rc = my_readdir64(argv[1]); > + if (rc != expected) { > + printf("FAIL - my_readdir64 returned %d, expected %d\n", rc, > expected); > + err = rc; > + goto err; > + } > +#endif > + > printf("PASS\n"); > > - return 0; > +err: > + return err; > } > Index: b/tests/regression/apparmor/readdir.sh > =================================================================== > --- a/tests/regression/apparmor/readdir.sh > +++ b/tests/regression/apparmor/readdir.sh > @@ -1,5 +1,6 @@ > #! /bin/bash > # Copyright (C) 2002-2005 Novell/SUSE > +# Copyright (C) 2017 Canonical, Ltd. > # > # This program is free software; you can redistribute it and/or > # modify it under the terms of the GNU General Public License as > @@ -8,7 +9,7 @@ > > #=NAME readdir > #=DESCRIPTION > -# AppArmor requires 'r' permission on a directory in order for a confined > task > +# AppArmor requires 'r' permission on a directory in order for a confined > task > # to be able to read the directory contents. This test verifies this. > #=END > > @@ -26,20 +27,30 @@ badperm=ix > > mkdir $dir > > +# The readdir utility expects the return value to be passed as the > +# second argument and returns success if the succeeding or failing calls > +# match the expected value. It will fail the test if they don't, so for > +# example the result differs acrorss getdents() and getdents64() this > +# will be detected. > + > # READDIR TEST > genprofile $dir/:$okperm > -runchecktest "READDIR" pass $dir > +runchecktest "READDIR" pass $dir 0 > > # READDIR TEST (no perm) > genprofile $dir/:$badperm > -runchecktest "READDIR (no perm)" fail $dir > +runchecktest "READDIR (no perm)" pass $dir 13 > + > +# READDIR TEST (write perm) - ensure write perm isn't sufficient > +genprofile $dir/:w > +runchecktest "READDIR (write perm)" pass $dir 13 > > # this test is to make sure the raw 'file' rule allows access > # to directories > genprofile file > -runchecktest "READDIR 'file' dir" pass $dir > +runchecktest "READDIR 'file' dir" pass $dir 0 > > # this test is to make sure the raw 'file' rule allows access > # to '/' > genprofile file > -runchecktest "READDIR 'file' '/'" pass '/' > +runchecktest "READDIR 'file' '/'" pass '/' 0 >
signature.asc
Description: PGP signature
-- AppArmor mailing list [email protected] Modify settings or unsubscribe at: https://lists.ubuntu.com/mailman/listinfo/apparmor
