• 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 /*  DESCRIPTION
7  *  This test will verify that new directory created by mkdir(2) inherites
8  *  the group ID from the parent directory and S_ISGID bit, if the S_ISGID
9  *  bit is set in the parent directory.
10  */
11 
12 #include <errno.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include <pwd.h>
16 #include <sys/wait.h>
17 #include <unistd.h>
18 #include <stdlib.h>
19 #include "tst_test.h"
20 
21 #define TESTDIR1	"testdir1"
22 #define TESTDIR2	"testdir1/testdir2"
23 
24 static uid_t nobody_uid, bin_uid;
25 static gid_t nobody_gid, bin_gid;
26 
verify_mkdir(void)27 static void verify_mkdir(void)
28 {
29 	struct stat buf1, buf2;
30 	pid_t pid;
31 	int fail = 0;
32 
33 	pid = SAFE_FORK();
34 	if (pid == 0) {
35 		SAFE_SETREGID(bin_gid, bin_gid);
36 		SAFE_SETREUID(bin_uid, bin_uid);
37 		SAFE_MKDIR(TESTDIR2, 0777);
38 
39 		SAFE_STAT(TESTDIR2, &buf2);
40 		SAFE_STAT(TESTDIR1, &buf1);
41 
42 		if (buf2.st_gid != buf1.st_gid) {
43 			tst_res(TFAIL,
44 				"New dir FAILED to inherit GID have %d expected %d",
45 				buf2.st_gid, buf1.st_gid);
46 			fail = 1;
47 		}
48 
49 		if (!(buf2.st_mode & S_ISGID)) {
50 			tst_res(TFAIL, "New dir FAILED to inherit S_ISGID");
51 			fail = 1;
52 		}
53 
54 		if (!fail)
55 			tst_res(TPASS, "New dir inherited GID and S_ISGID");
56 
57 		exit(0);
58 	}
59 
60 	tst_reap_children();
61 	SAFE_RMDIR(TESTDIR2);
62 }
63 
64 
setup(void)65 static void setup(void)
66 {
67 	struct passwd *pw;
68 	struct stat buf;
69 	pid_t pid;
70 
71 	pw = SAFE_GETPWNAM("nobody");
72 	nobody_uid = pw->pw_uid;
73 	nobody_gid = pw->pw_gid;
74 	pw = SAFE_GETPWNAM("bin");
75 	bin_uid = pw->pw_uid;
76 	bin_gid = pw->pw_gid;
77 
78 	umask(0);
79 
80 	pid = SAFE_FORK();
81 	if (pid == 0) {
82 		SAFE_SETREGID(nobody_gid, nobody_gid);
83 		SAFE_SETREUID(nobody_uid, nobody_uid);
84 		SAFE_MKDIR(TESTDIR1, 0777);
85 		SAFE_STAT(TESTDIR1, &buf);
86 		SAFE_CHMOD(TESTDIR1, buf.st_mode | S_ISGID);
87 		exit(0);
88 	}
89 
90 	tst_reap_children();
91 }
92 
93 static struct tst_test test = {
94 	.setup = setup,
95 	.needs_tmpdir = 1,
96 	.needs_root = 1,
97 	.test_all = verify_mkdir,
98 	.forks_child = 1,
99 };
100