1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Copyright (c) International Business Machines Corp., 2001
4 */
5
6/*\
7 * [Description]
8 *
9 * Verify that new directory created by mkdir(2) inherites the group ID from
10 * the parent directory and S_ISGID bit, if the S_ISGID bit is set in the
11 * parent directory.
12 */
13
14#include <sys/stat.h>
15#include <sys/types.h>
16#include <pwd.h>
17#include "tst_test.h"
18#include "tst_uid.h"
19
20#define TESTDIR1	"testdir1"
21#define TESTDIR2	"testdir1/testdir2"
22
23static gid_t free_gid;
24
25static void verify_mkdir(void)
26{
27	struct stat statbuf;
28	int fail = 0;
29
30	SAFE_MKDIR(TESTDIR2, 0777);
31	SAFE_STAT(TESTDIR2, &statbuf);
32
33	if (statbuf.st_gid != free_gid) {
34		tst_res(TFAIL,
35			"New dir FAILED to inherit GID: has %d, expected %d",
36			statbuf.st_gid, free_gid);
37		fail = 1;
38	}
39
40	if (!(statbuf.st_mode & S_ISGID)) {
41		tst_res(TFAIL, "New dir FAILED to inherit S_ISGID");
42		fail = 1;
43	}
44
45	if (!fail)
46		tst_res(TPASS, "New dir inherited GID and S_ISGID");
47
48	SAFE_RMDIR(TESTDIR2);
49}
50
51
52static void setup(void)
53{
54	struct passwd *pw = SAFE_GETPWNAM("nobody");
55
56	free_gid = tst_get_free_gid(pw->pw_gid);
57
58	umask(0);
59	SAFE_MKDIR(TESTDIR1, 0777);
60	SAFE_CHMOD(TESTDIR1, 0777 | S_ISGID);
61	SAFE_CHOWN(TESTDIR1, getuid(), free_gid);
62
63	SAFE_SETREGID(pw->pw_gid, pw->pw_gid);
64	SAFE_SETREUID(pw->pw_uid, pw->pw_uid);
65}
66
67static struct tst_test test = {
68	.setup = setup,
69	.needs_tmpdir = 1,
70	.needs_root = 1,
71	.test_all = verify_mkdir,
72};
73