• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) International Business Machines  Corp., 2001
3  *
4  * This program is free software;  you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  *  This program is distributed in the hope that it will be useful,
10  *  but WITHOUT ANY WARRANTY;  without even the implied warranty of
11  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12  *  the GNU General Public License for more details.
13  *
14  *  You should have received a copy of the GNU General Public License
15  *  along with this program. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*  DESCRIPTION
19  *  This test will verify that new directory created by mkdir(2) inherites
20  *  the group ID from the parent directory and S_ISGID bit, if the S_ISGID
21  *  bit is set in the parent directory.
22  */
23 
24 #include <errno.h>
25 #include <sys/stat.h>
26 #include <sys/types.h>
27 #include <pwd.h>
28 #include <sys/wait.h>
29 #include <unistd.h>
30 #include <stdlib.h>
31 #include "tst_test.h"
32 
33 #define TESTDIR1	"testdir1"
34 #define TESTDIR2	"testdir1/testdir2"
35 
36 static uid_t nobody_uid, bin_uid;
37 static gid_t nobody_gid, bin_gid;
38 
verify_mkdir(void)39 static void verify_mkdir(void)
40 {
41 	struct stat buf1, buf2;
42 	pid_t pid;
43 	int fail = 0;
44 
45 	pid = SAFE_FORK();
46 	if (pid == 0) {
47 		SAFE_SETREGID(bin_gid, bin_gid);
48 		SAFE_SETREUID(bin_uid, bin_uid);
49 		SAFE_MKDIR(TESTDIR2, 0777);
50 
51 		SAFE_STAT(TESTDIR2, &buf2);
52 		SAFE_STAT(TESTDIR1, &buf1);
53 
54 		if (buf2.st_gid != buf1.st_gid) {
55 			tst_res(TFAIL,
56 				"New dir FAILED to inherit GID have %d expected %d",
57 				buf2.st_gid, buf1.st_gid);
58 			fail = 1;
59 		}
60 
61 		if (!(buf2.st_mode & S_ISGID)) {
62 			tst_res(TFAIL, "New dir FAILED to inherit S_ISGID");
63 			fail = 1;
64 		}
65 
66 		if (!fail)
67 			tst_res(TPASS, "New dir inherited GID and S_ISGID");
68 
69 		exit(0);
70 	}
71 
72 	tst_reap_children();
73 	SAFE_RMDIR(TESTDIR2);
74 }
75 
76 
setup(void)77 static void setup(void)
78 {
79 	struct passwd *pw;
80 	struct stat buf;
81 	pid_t pid;
82 
83 	pw = SAFE_GETPWNAM("nobody");
84 	nobody_uid = pw->pw_uid;
85 	nobody_gid = pw->pw_gid;
86 	pw = SAFE_GETPWNAM("bin");
87 	bin_uid = pw->pw_uid;
88 	bin_gid = pw->pw_gid;
89 
90 	umask(0);
91 
92 	pid = SAFE_FORK();
93 	if (pid == 0) {
94 		SAFE_SETREGID(nobody_gid, nobody_gid);
95 		SAFE_SETREUID(nobody_uid, nobody_uid);
96 		SAFE_MKDIR(TESTDIR1, 0777);
97 		SAFE_STAT(TESTDIR1, &buf);
98 		SAFE_CHMOD(TESTDIR1, buf.st_mode | S_ISGID);
99 		exit(0);
100 	}
101 
102 	tst_reap_children();
103 }
104 
105 static struct tst_test test = {
106 	.setup = setup,
107 	.needs_tmpdir = 1,
108 	.needs_root = 1,
109 	.test_all = verify_mkdir,
110 	.forks_child = 1,
111 };
112