• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) International Business Machines Corp., 2001
4  */
5 
6 /*
7  * DESCRIPTION
8  *   check rmdir() fails with EPERM or EACCES
9  *
10  *	1. Create a directory tstdir1 and set the sticky bit, then
11  *         create directory tstdir2 under tstdir1. Call rmdir(),
12  *         set to be user nobody. Pass tstdir2 to rmdir(2), verify
13  *         the return value is not 0 and the errno is EPERM or EACCES.
14  *
15  *	2. Create a directory tstdir1 and doesn't give execute/search
16  *         permission to nobody, then create directory tstdir2 under
17  *         tstdir1. Call rmdir(), set to be user nobody. Pass
18  *         tstdir2 to rmdir(2), verify the return value is not 0 and
19  *         the errno is EACCES.
20  */
21 #include <errno.h>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <pwd.h>
25 #include <unistd.h>
26 #include "tst_test.h"
27 
28 #define DIR_MODE    0777
29 #define NOEXCUTE_MODE 0766
30 #define TESTDIR     "testdir"
31 #define TESTDIR2    "testdir/testdir2"
32 #define TESTDIR3    "testdir3"
33 #define TESTDIR4    "testdir3/testdir4"
34 
35 static struct testcase {
36 	mode_t dir_mode;
37 	char *subdir;
38 } tcases[] =  {
39 	{DIR_MODE | S_ISVTX, TESTDIR2},
40 	{NOEXCUTE_MODE, TESTDIR4},
41 };
42 
do_rmdir(unsigned int n)43 static void do_rmdir(unsigned int n)
44 {
45 	struct testcase *tc = &tcases[n];
46 
47 	TEST(rmdir(tc->subdir));
48 	if (TST_RET != -1) {
49 		tst_res(TFAIL, "rmdir() succeeded unexpectedly");
50 		return;
51 	}
52 
53 	if (TST_ERR != EACCES) {
54 		if (tc->dir_mode & S_ISVTX && TST_ERR == EPERM)
55 			tst_res(TPASS | TTERRNO, "rmdir() got expected errno");
56 		else
57 			tst_res(TFAIL | TTERRNO, "expected EPERM, but got");
58 		return;
59 	}
60 
61 	tst_res(TPASS | TTERRNO, "rmdir() got expected errno");
62 }
63 
64 
setup(void)65 static void setup(void)
66 {
67 	struct passwd *pw;
68 	pw = SAFE_GETPWNAM("nobody");
69 
70 	umask(0);
71 
72 	SAFE_MKDIR(TESTDIR, DIR_MODE | S_ISVTX);
73 	SAFE_MKDIR(TESTDIR2, DIR_MODE);
74 	SAFE_MKDIR(TESTDIR3, NOEXCUTE_MODE);
75 	SAFE_MKDIR(TESTDIR4, DIR_MODE);
76 
77 	SAFE_SETEUID(pw->pw_uid);
78 }
79 
cleanup(void)80 static void cleanup(void)
81 {
82 	SAFE_SETEUID(0);
83 }
84 
85 static struct tst_test test = {
86 	.setup = setup,
87 	.cleanup = cleanup,
88 	.tcnt = ARRAY_SIZE(tcases),
89 	.test = do_rmdir,
90 	.needs_root = 1,
91 	.needs_tmpdir = 1,
92 };
93 
94