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