[LTP] [PATCH 3/3] syscalls/rmdir03: Cleanup && Convert to new API
yang xu
xuyang.jy@cn.fujitsu.com
Tue Feb 13 17:01:36 CET 2018
1) Take use of some safe macros
2) Don't need to fork child processes
Signed-off-by: yang xu <xuyang.jy@cn.fujitsu.com>
---
testcases/kernel/syscalls/rmdir/rmdir03.c | 373 ++++++-----------------------
1 files changed, 70 insertions(+), 303 deletions(-)
diff --git a/testcases/kernel/syscalls/rmdir/rmdir03.c b/testcases/kernel/syscalls/rmdir/rmdir03.c
index 2bdc8ba..c4e80ff 100644
--- a/testcases/kernel/syscalls/rmdir/rmdir03.c
+++ b/testcases/kernel/syscalls/rmdir/rmdir03.c
@@ -1,338 +1,105 @@
/*
+ * Copyright (c) International Business Machines Corp., 2001
*
- * Copyright (c) International Business Machines Corp., 2001
+ * 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; either version 2 of the License, or
+ * (at your option) any later version.
*
- * 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; either version 2 of the License, or
- * (at your option) any later version.
+ * This program 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 General Public License for more details.
*
- * This program 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 General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
/*
- * NAME
- * rmdir03
- *
* DESCRIPTION
- * check rmdir() fails with EPERM or EACCES
- *
- * ALGORITHM
- * Setup:
- * Setup signal handling.
- * Pause for SIGUSR1 if option specified.
- * Create temporary directory.
- *
- * Test:
- * Loop if the proper options are given.
- * 1. create a directory tstdir1 and set the sticky bit, then
- * create directory tstdir2 under tstdir1. Fork a
- * child , set to be user nobody. Pass tstdir2 to rmdir(2).
- * Verify the return value is not 0 and the errno is EPERM
- * or EACCES.
- * 2. Fork a child, set to be user nobody. Create a directory
- * tstdir1 and only give write permission to nobody.
- * Create directory tstdir2 under tstdir1. Fork the second
- * child , set to be user nobody. Pass tstdir2 to rmdir(2).
- * Verify the return value is not 0 and the errno is EACCES.
- *
- * Cleanup:
- * Print errno log and/or timing stats if options given
- * Delete the temporary directory created.
+ * check rmdir() fails with EPERM or EACCES
*
- * USAGE
- * rmdir03 [-c n] [-e] [-i n] [-I x] [-P x] [-t]
- * where, -c n : Run n copies concurrently.
- * -e : Turn on errno logging.
- * -i n : Execute test n times.
- * -I x : Execute test for x seconds.
- * -P x : Pause for x seconds between iterations.
- * -t : Turn on syscall timing.
- *
- * HISTORY
- * 07/2001 Ported by Wayne Boyer
- *
- * RESTRICTIONS
- * Test must be run as root.
+ * 1. Create a directory tstdir1 and set the sticky bit, then
+ * create directory tstdir2 under tstdir1. Call dormdir(),
+ * set to be user nobody. Pass tstdir2 to rmdir(2), verify
+ * the return value is not 0 and the errno is EPERO or EACCES.
*
+ * 2. Create a directory tstdir1 and doesn't give execute/search
+ * permission to nobody, then create directory tstdir2 under
+ * tstdir1. Call dormdir(), set to be user nobody. Pass
+ * tstdir2 to rmdir(2), verify the return value is not 0 and
+ * the errno is EACCES.
*/
#include <errno.h>
-#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
-#include <sys/wait.h>
-#include <fcntl.h>
#include <pwd.h>
#include <unistd.h>
-
-#include "test.h"
-#include "safe_macros.h"
-
-void dochild1();
-void dochild2();
-void setup();
-void cleanup();
-
-#define PERMS 0777
-
-static uid_t nobody_uid;
-
-char *TCID = "rmdir03";
-int TST_TOTAL = 1;
-
-char tstdir1[255];
-char tstdir2[255];
-char tstdir3[255];
-char tstdir4[255];
-
-int main(int ac, char **av)
+#include "tst_test.h"
+
+#define DIR_MODE 0777
+#define NOEXCUTE_MODE 0766
+#define TESTDIR "testdir"
+#define TESTDIR2 "testdir/testdir2"
+#define TESTDIR3 "testdir3"
+#define TESTDIR4 "testdir3/testdir4"
+
+static struct testcase {
+ mode_t dir_mode;
+ char *subdir;
+} tcases[] = {
+ {DIR_MODE | S_ISVTX, TESTDIR2},
+ {NOEXCUTE_MODE, TESTDIR4},
+};
+
+static void do_rmdir(unsigned int n)
{
- int lc;
- pid_t pid;
- struct stat buf1;
- int e_code, status, status2;
-
- /*
- * parse standard options
- */
- tst_parse_opts(ac, av, NULL, NULL);
-#ifdef UCLINUX
- maybe_run_child(&dochild1, "ns", 1, tstdir2);
- maybe_run_child(&dochild2, "ns", 2, tstdir4);
-#endif
-
- /*
- * perform global setup for test
- */
- setup();
-
- /*
- * check looping state if -i option given
- */
- for (lc = 0; TEST_LOOPING(lc); lc++) {
-
- tst_count = 0;
-
-//test1: $
- /*
- * attempt to rmdir a file whose parent directory has
- * the sticky bit set without the root right
- * or effective uid
- */
-
- if (stat(tstdir1, &buf1) != -1) {
- tst_brkm(TBROK, cleanup,
- "tmp directory %s found!", tstdir1);
- }
- /* create a directory */
- SAFE_MKDIR(cleanup, tstdir1, PERMS);
- if (stat(tstdir1, &buf1) == -1) {
- perror("stat");
- tst_brkm(TBROK, cleanup, "failed to stat directory %s "
- "in rmdir()", tstdir1);
-
- }
- /* set the sticky bit */
- if (chmod(tstdir1, buf1.st_mode | S_ISVTX) != 0) {
- perror("chmod");
- tst_brkm(TBROK, cleanup,
- "failed to set the S_ISVTX bit");
-
- }
- /* create a sub directory under tstdir1 */
- SAFE_MKDIR(cleanup, tstdir2, PERMS);
-
- if ((pid = FORK_OR_VFORK()) == -1) {
- tst_brkm(TBROK, cleanup, "fork() failed");
- }
-
- if (pid == 0) { /* first child */
-#ifdef UCLINUX
- if (self_exec(av[0], "ns", 1, tstdir2) < 0) {
- tst_brkm(TBROK, cleanup, "self_exec failed");
- }
-#else
- dochild1();
-#endif
- }
- /* Parent */
-
-//test2: $
- /* create the a directory with 0700 permits */
- SAFE_MKDIR(cleanup, tstdir3, 0700);
- /* create the a directory with 0700 permits */
- SAFE_MKDIR(cleanup, tstdir4, 0777);
-
- if ((pid = FORK_OR_VFORK()) == -1) {
- tst_brkm(TBROK, cleanup, "fork() failed");
- }
-
- if (pid == 0) { /* child */
-#ifdef UCLINUX
- if (self_exec(av[0], "ns", 2, tstdir4) < 0) {
- tst_brkm(TBROK, cleanup, "self_exec failed");
- }
-#else
- dochild2();
-#endif
- } else { /* parent */
- /* wait for the child to finish */
- wait(&status);
- wait(&status2);
- /* make sure the child returned a good exit status */
- e_code = status >> 8;
- if (e_code != 0) {
- tst_resm(TFAIL, "Failures reported above");
- } else {
- /* No error in the 1st one, check the 2nd */
- e_code = status2 >> 8;
- if (e_code != 0) {
- tst_resm(TFAIL,
- "Failures reported above");
- }
- }
- }
-
- /* clean up things in case we are looping */
-
- (void)rmdir(tstdir2);
- (void)rmdir(tstdir1);
- (void)rmdir(tstdir4);
- (void)rmdir(tstdir3);
-
- }
-
- /*
- * cleanup and exit
- */
- cleanup();
- tst_exit();
-
-}
-
-/*
- * dochild1()
- */
-void dochild1(void)
-{
- int retval = 0;
-
- /* set to nobody */
- if (seteuid(nobody_uid) == -1) {
- retval = 1;
- tst_brkm(TBROK, cleanup, "setreuid failed to "
- "set effective uid to %d", nobody_uid);
- }
-
- /* rmdir tstdir2 */
- TEST(rmdir(tstdir2));
-
- if (TEST_ERRNO) {
- }
+ struct testcase *tc = &tcases[n];
+ TEST(rmdir(tc->subdir));
if (TEST_RETURN != -1) {
- retval = 1;
- tst_resm(TFAIL, "call succeeded unexpectedly");
- } else if ((TEST_ERRNO != EPERM) && (TEST_ERRNO != EACCES)) {
- retval = 1;
- tst_resm(TFAIL, "Expected EPERM or EACCES, got %d", TEST_ERRNO);
- } else {
- tst_resm(TPASS, "rmdir() produced EPERM or EACCES");
- }
-
- if (seteuid(0) == -1) {
- retval = 1;
- tst_brkm(TBROK, cleanup, "seteuid(0) failed");
+ tst_res(TFAIL, "rmdir() succeeded unexpectedly");
+ return;
}
- exit(retval);
- /* END of child 1 (test1) */
-}
-
-/*
- * dochild1()
- */
-void dochild2(void)
-{
- int retval = 0;
- /* set to nobody */
- if (seteuid(nobody_uid) == -1) {
- retval = 1;
- tst_brkm(TBROK, cleanup, "setreuid failed to "
- "set effective uid to %d", nobody_uid);
+ if (TEST_ERRNO != EACCES) {
+ if (tc->dir_mode & S_ISVTX && TEST_ERRNO == EPERM)
+ tst_res(TPASS | TTERRNO, "rmdir() got expected errno");
+ else
+ tst_res(TFAIL | TTERRNO, "expected EPERM, but got");
+ return;
}
- /* rmdir tstdir4 */
- TEST(rmdir(tstdir4));
-
- if (TEST_ERRNO) {
- }
-
- if (TEST_RETURN != -1) {
- retval = 1;
- tst_resm(TFAIL, "call succeeded unexpectedly");
- } else if (TEST_ERRNO != EACCES) {
- retval = 1;
- tst_resm(TFAIL, "Expected EACCES got %d", TEST_ERRNO);
- } else {
- tst_resm(TPASS, "rmdir() produced EACCES");
- }
-
- if (seteuid(0) == -1) {
- retval = 1;
- tst_brkm(TBROK, cleanup, "seteuid(0) failed");
- }
- exit(retval);
+ tst_res(TPASS | TTERRNO, "rmdir() got expected errno");
}
-/*
- * setup() - performs all ONE TIME setup for this test.
- */
-void setup(void)
+
+static void setup(void)
{
struct passwd *pw;
-
- tst_require_root();
-
- pw = SAFE_GETPWNAM(NULL, "nobody");
- nobody_uid = pw->pw_uid;
-
- tst_sig(FORK, DEF_HANDLER, cleanup);
-
- TEST_PAUSE;
-
- /* Create a temporary directory and make it current. */
- tst_tmpdir();
+ pw = SAFE_GETPWNAM("nobody");
umask(0);
- sprintf(tstdir1, "./tstdir1_%d", getpid());
- sprintf(tstdir2, "%s/tstdir2_%d", tstdir1, getpid());
- sprintf(tstdir3, "./tstdir3_%d", getpid());
- sprintf(tstdir4, "%s/tstdir3_%d", tstdir3, getpid());
+ SAFE_MKDIR(TESTDIR, DIR_MODE | S_ISVTX);
+ SAFE_MKDIR(TESTDIR2, DIR_MODE);
+ SAFE_MKDIR(TESTDIR3, NOEXCUTE_MODE);
+ SAFE_MKDIR(TESTDIR4, DIR_MODE);
+
+ SAFE_SETEUID(pw->pw_uid);
}
-/*
- * cleanup() - performs all ONE TIME cleanup for this test at
- * completion or premature exit.
- */
-void cleanup(void)
+static void cleanup(void)
{
+ SAFE_SETEUID(0);
+}
- /*
- * Remove the temporary directory.
- */
- tst_rmdir();
-
- /*
- * Exit with return code appropriate for results.
- */
+static struct tst_test test = {
+ .setup = setup,
+ .cleanup = cleanup,
+ .tcnt = ARRAY_SIZE(tcases),
+ .test = do_rmdir,
+ .needs_root = 1,
+ .needs_tmpdir = 1,
+};
-}
--
1.7.1
More information about the ltp
mailing list