From 726b7b0f5cce9df5dd406a6a38a3e104fac9a070 Mon Sep 17 00:00:00 2001 From: Ulrich Drepper Date: Thu, 26 Oct 2000 08:11:19 +0000 Subject: Update. 2000-10-26 Ulrich Drepper * posix/Makefile (tests): Add tst-chmod. (tst-chmod-ARGS): Define. * posix/tst-chmod.c: New file. * test-skeleton.c: Before calling user-defined function remove parameters from argument list. * posix/tst-exec.c: Adjust to this change. * posix/tst-spawn.c: Likewise. * sysdeps/unix/opendir.c (__opendir): Optimize a bit. Add __builtin_expect. --- posix/Makefile | 4 +- posix/tst-chmod.c | 368 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ posix/tst-exec.c | 21 ++-- posix/tst-spawn.c | 21 ++-- 4 files changed, 392 insertions(+), 22 deletions(-) create mode 100644 posix/tst-chmod.c (limited to 'posix') diff --git a/posix/Makefile b/posix/Makefile index 3430d3c0c5..4329566c0b 100644 --- a/posix/Makefile +++ b/posix/Makefile @@ -68,7 +68,8 @@ aux := init-posix environ tests := tstgetopt testfnm runtests runptests \ tst-preadwrite tst-preadwrite64 test-vfork regexbug1 \ tst-getlogin tst-mmap tst-getaddrinfo tst-truncate \ - tst-truncate64 tst-fork tst-fnmatch tst-regexloc tst-dir + tst-truncate64 tst-fork tst-fnmatch tst-regexloc tst-dir \ + tst-chmod ifeq (yes,$(build-shared)) test-srcs := globtest tests += wordexp-test tst-exec tst-spawn @@ -114,6 +115,7 @@ tstgetopt-ARGS = -a -b -cfoobar --required foobar --optional=bazbug \ tst-exec-ARGS = -- $(built-program-cmd) tst-spawn-ARGS = -- $(built-program-cmd) tst-dir-ARGS = `pwd` "$(objdir)/$(subdir)" "$(common-objdir)" $(objpfx)tst-dir +tst-chmod-ARGS = $(objpfx) tst-fnmatch-ENV = LOCPATH=$(common-objpfx)localedata tst-regexloc-ENV = LOCPATH=$(common-objpfx)localedata diff --git a/posix/tst-chmod.c b/posix/tst-chmod.c new file mode 100644 index 0000000000..f7a37fa3a3 --- /dev/null +++ b/posix/tst-chmod.c @@ -0,0 +1,368 @@ +/* Test for chmod functions. + Copyright (C) 2000 Free Software Foundation, Inc. + Contributed by Ulrich Drepper , 2000. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#define OUT_OF_MEMORY \ + do { \ + puts ("cannot allocate memory"); \ + result = 1; \ + goto fail; \ + } while (0) + +int +do_test (int argc, char *argv[]) +{ + const char *builddir; + struct stat64 st1; + struct stat64 st2; + char *buf; + char *testdir; + char *testfile = NULL; + char *startdir; + size_t buflen; + int fd; + int result = 0; + DIR *dir; + + mtrace (); + + if (argc <= 1) + error (EXIT_FAILURE, 0, "no parameters"); + + /* This is where we will create the test files. */ + builddir = argv[1]; + buflen = strlen (builddir) + 50; + + startdir = getcwd (NULL, 0); + if (startdir == NULL) + { + printf ("cannot get current directory: %m\n"); + exit (EXIT_FAILURE); + } + + /* A buffer large enough for everything we need. */ + buf = (char *) alloca (buflen); + + /* Create the directory name. */ + snprintf (buf, buflen, "%schmoddirXXXXXX", builddir); + + if (mkdtemp (buf) == NULL) + { + printf ("cannot create test directory: %m\n"); + exit (EXIT_FAILURE); + } + + if (chmod ("", 0600) == 0) + { + puts ("chmod(\"\", 0600 didn't fail"); + result = 1; + } + else if (errno != ENOENT) + { + puts ("chmod(\"\",0600) does not set errno to ENOENT"); + result = 1; + } + + /* Create a duplicate. */ + testdir = strdup (buf); + if (testdir == NULL) + OUT_OF_MEMORY; + + if (stat64 (testdir, &st1) != 0) + { + printf ("cannot stat test directory: %m\n"); + exit (1); + } + if (!S_ISDIR (st1.st_mode)) + { + printf ("file not created as directory: %m\n"); + exit (1); + } + + /* We have to wait for a second to make sure the ctime changes. */ + sleep (1); + + /* Remove all access rights from the directory. */ + if (chmod (testdir, 0) != 0) + { + printf ("cannot change mode of test directory: %m\n"); + result = 1; + goto fail; + } + + if (stat64 (testdir, &st2) != 0) + { + printf ("cannot stat test directory: %m\n"); + result = 1; + goto fail; + } + + /* Compare result. */ + if ((st2.st_mode & ALLPERMS) != 0) + { + printf ("chmod(...,0) on directory left bits nonzero: %o\n", + st2.st_mode & ALLPERMS); + result = 1; + } + if (st1.st_ctime >= st2.st_ctime) + { + puts ("chmod(...,0) did not set ctime correctly"); + result = 1; + } + + /* Name of a file in the directory. */ + snprintf (buf, buflen, "%s/file", testdir); + testfile = strdup (buf); + if (testfile == NULL) + OUT_OF_MEMORY; + + fd = creat (testfile, 0); + if (fd != -1) + { + puts ("managed to create test file in protected directory"); + result = 1; + close (fd); + } + if (errno != EACCES) + { + puts ("creat didn't generate correct errno value"); + result = 1; + } + + /* With this mode it still shouldn't be possible to create a file. */ + if (chmod (testdir, 0600) != 0) + { + printf ("cannot change mode of test directory to 0600: %m\n"); + result = 1; + goto fail; + } + + fd = creat (testfile, 0); + if (fd != -1) + { + puts ("managed to create test file in no-x protected directory"); + result = 1; + close (fd); + } + if (errno != EACCES) + { + puts ("creat didn't generate correct errno value"); + result = 1; + } + + /* Change the directory mode back to allow creating a file. This + time with fchmod. */ + dir = opendir (testdir); + if (dir != NULL) + { + if (fchmod (dirfd (dir), 0700) != 0) + { + printf ("cannot change mode of test directory to 0700: %m\n"); + result = 1; + closedir (dir); + goto fail; + } + + closedir (dir); + } + else + { + printf ("cannot open directory: %m\n"); + result = 1; + + if (chmod (testdir, 0700) != 0) + { + printf ("cannot change mode of test directory to 0700: %m\n"); + goto fail; + } + } + + fd = creat (testfile, 0); + if (fd == -1) + { + puts ("still didn't manage to create test file in protected directory"); + result = 1; + goto fail; + } + if (fstat64 (fd, &st1) != 0) + { + printf ("cannot stat new file: %m\n"); + result = 1; + } + else if ((st1.st_mode & ALLPERMS) != 0) + { + puts ("file not created with access mode 0"); + result = 1; + } + close (fd); + + snprintf (buf, buflen, "%s/..", testdir); + chdir (buf); + /* We are now in the directory above the one we create the test + directory in. */ + + sleep (1); + snprintf (buf, buflen, "./%s/../%s/file", + basename (testdir), basename (testdir)); + if (chmod (buf, 0600) != 0) + { + printf ("cannot change mode of file to 0600: %m\n"); + result = 1; + goto fail; + } + snprintf (buf, buflen, "./%s//file", basename (testdir)); + if (stat64 (buf, &st2) != 0) + { + printf ("cannot stat new file: %m\n"); + result = 1; + } + else if ((st2.st_mode & ALLPERMS) != 0600) + { + puts ("file mode not changed to 0600"); + result = 1; + } + else if (st1.st_ctime >= st2.st_ctime) + { + puts ("chmod(\".../file\",0600) did not set ctime correctly"); + result = 1; + } + + if (chmod (buf, 0777 | S_ISUID | S_ISGID) != 0) + { + printf ("cannot change mode of file to %o: %m\n", + 0777 | S_ISUID | S_ISGID); + result = 1; + } + if (stat64 (buf, &st2) != 0) + { + printf ("cannot stat test file: %m\n"); + result = 1; + } + else if ((st2.st_mode & ALLPERMS) != (0777 | S_ISUID | S_ISGID)) + { + puts ("file mode not changed to 0777 | S_ISUID | S_ISGID"); + result = 1; + } + + if (chmod (basename (testdir), 0777 | S_ISUID | S_ISGID | S_ISVTX) != 0) + { + printf ("cannot change mode of test directory to %o: %m\n", + 0777 | S_ISUID | S_ISGID | S_ISVTX); + result = 1; + } + if (stat64 (basename (testdir), &st2) != 0) + { + printf ("cannot stat test directory: %m\n"); + result = 1; + } + else if ((st2.st_mode & ALLPERMS) != (0777 | S_ISUID | S_ISGID | S_ISVTX)) + { + puts ("directory mode not changed to 0777 | S_ISUID | S_ISGID | S_ISGID"); + result = 1; + } + + snprintf (buf, buflen, "./%s/no-such-file", basename (testdir)); + if (chmod (buf, 0600) != -1) + { + puts ("chmod(\".../no-such-file\",0600) did not fail"); + result = 1; + } + else if (errno != ENOENT) + { + puts ("chmod(\".../no-such-file\",0600) does not set errno to ENOENT"); + result = 1; + } + + snprintf (buf, buflen, "%s/", basename (testdir)); + if (chmod (basename (testdir), 0677) != 0) + { + printf ("cannot change mode of test directory to 0677: %m\n"); + result = 1; + } + else + { + snprintf (buf, buflen, "./%s/file", basename (testdir)); + if (chmod (buf, 0600) == 0) + { + puts ("chmod(\".../file\") with no-exec directory succeeded"); + result = 1; + } + else if (errno != EACCES) + { + puts ("chmod(\".../file\") with no-exec directory didn't set EACCES"); + result = 1; + } + } + + if (chmod (basename (testdir), 0777) != 0) + { + printf ("cannot change mode of test directory to 0777: %m\n"); + result = 1; + goto fail; + } + + snprintf (buf, buflen, "%s/file/cannot-be", basename (testdir)); + if (chmod (buf, 0600) == 0) + { + puts ("chmod(\".../file/cannot-be\",0600) did not fail"); + result = 1; + } + else if (errno != ENOTDIR) + { + puts ("chmod(\".../file/cannot-be\",0600) does not set errno to ENOTDIR"); + result = 1; + } + + fail: + chdir (startdir); + + /* Remove all the files. */ + chmod (testdir, 0700); + if (testfile != NULL) + { + chmod (testfile, 0700); + unlink (testfile); + } + rmdir (testdir); + + /* Free the resources. */ + free (testfile); + free (testdir); + free (startdir); + + return result; +} + + +/* We need a few seconds since we have a few sleeps in the code. */ +#define TIMEOUT 20 + + +#include "../test-skeleton.c" diff --git a/posix/tst-exec.c b/posix/tst-exec.c index 0cb988d1de..2c541fcd04 100644 --- a/posix/tst-exec.c +++ b/posix/tst-exec.c @@ -126,24 +126,27 @@ do_test (int argc, char *argv[]) int status; /* We must have - - five parameters left of called initially - + -- + - four parameters left of called initially + path for ld.so + "--library-path" + the library path + the application name - - five parameters left if called through re-execution - + --direct - + --restart + - three parameters left if called through re-execution + file descriptor number which is supposed to be closed + the open file descriptor + the name of the closed desriptor */ - if (argc != 6) - error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc); if (restart) - return handle_restart (argv[3], argv[4], argv[5]); + { + if (argc != 4) + error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc); + + return handle_restart (argv[1], argv[2], argv[3]); + } + + if (argc != 5) + error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc); /* Prepare the test. We are creating two files: one which file descriptor will be marked with FD_CLOEXEC, another which is not. */ @@ -182,7 +185,7 @@ do_test (int argc, char *argv[]) snprintf (fd2name, sizeof fd2name, "%d", fd2); /* This is the child. Construct the command line. */ - execl (argv[2], argv[2], argv[3], argv[4], argv[5], "--direct", + execl (argv[1], argv[1], argv[2], argv[3], argv[4], "--direct", "--restart", fd1name, fd2name, name1, NULL); error (EXIT_FAILURE, errno, "cannot exec"); diff --git a/posix/tst-spawn.c b/posix/tst-spawn.c index 4bc94e0544..663320c2a5 100644 --- a/posix/tst-spawn.c +++ b/posix/tst-spawn.c @@ -171,26 +171,23 @@ do_test (int argc, char *argv[]) char *spargv[12]; /* We must have - - five parameters left of called initially - + -- + - four parameters left of called initially + path for ld.so + "--library-path" + the library path + the application name - - seven parameters left if called through re-execution - + --direct - + --restart + - five parameters left if called through re-execution + file descriptor number which is supposed to be closed + the open file descriptor + the newly opened file descriptor + thhe duped second descriptor + the name of the closed descriptor */ - if (argc != (restart ? 8 : 6)) + if (argc != (restart ? 6 : 5)) error (EXIT_FAILURE, 0, "wrong number of arguments (%d)", argc); if (restart) - return handle_restart (argv[3], argv[4], argv[5], argv[6], argv[7]); + return handle_restart (argv[1], argv[2], argv[3], argv[4], argv[5]); /* Prepare the test. We are creating two files: one which file descriptor will be marked with FD_CLOEXEC, another which is not. */ @@ -238,10 +235,10 @@ do_test (int argc, char *argv[]) snprintf (fd3name, sizeof fd3name, "%d", fd3); snprintf (fd4name, sizeof fd4name, "%d", fd4); - spargv[0] = argv[2]; - spargv[1] = argv[3]; - spargv[2] = argv[4]; - spargv[3] = argv[5]; + spargv[0] = argv[1]; + spargv[1] = argv[2]; + spargv[2] = argv[3]; + spargv[3] = argv[4]; spargv[4] = (char *) "--direct"; spargv[5] = (char *) "--restart"; spargv[6] = fd1name; @@ -251,7 +248,7 @@ do_test (int argc, char *argv[]) spargv[10] = name1; spargv[11] = NULL; - if (posix_spawn (&pid, argv[2], &actions, NULL, spargv, environ) != 0) + if (posix_spawn (&pid, argv[1], &actions, NULL, spargv, environ) != 0) error (EXIT_FAILURE, errno, "posix_spawn"); /* Cleanup. */ -- cgit v1.2.3