1*49cdfc7eSAndroid Build Coastguard Worker // SPDX-License-Identifier: GPL-2.0-or-later
2*49cdfc7eSAndroid Build Coastguard Worker /*
3*49cdfc7eSAndroid Build Coastguard Worker * Copyright (c) 2022 FUJITSU LIMITED. All rights reserved.
4*49cdfc7eSAndroid Build Coastguard Worker * Author: Yang Xu <[email protected]>
5*49cdfc7eSAndroid Build Coastguard Worker */
6*49cdfc7eSAndroid Build Coastguard Worker
7*49cdfc7eSAndroid Build Coastguard Worker /*\
8*49cdfc7eSAndroid Build Coastguard Worker * [Description]
9*49cdfc7eSAndroid Build Coastguard Worker *
10*49cdfc7eSAndroid Build Coastguard Worker * Check setgid strip logic whether works correctly when creating tmpfile under
11*49cdfc7eSAndroid Build Coastguard Worker * filesystem without POSIX ACL supported(by using noacl mount option). Test it
12*49cdfc7eSAndroid Build Coastguard Worker * with umask S_IXGRP and also check file mode whether has filtered S_IXGRP.
13*49cdfc7eSAndroid Build Coastguard Worker *
14*49cdfc7eSAndroid Build Coastguard Worker * Fixed in:
15*49cdfc7eSAndroid Build Coastguard Worker *
16*49cdfc7eSAndroid Build Coastguard Worker * commit ac6800e279a22b28f4fc21439843025a0d5bf03e
17*49cdfc7eSAndroid Build Coastguard Worker * Author: Yang Xu <[email protected]>
18*49cdfc7eSAndroid Build Coastguard Worker * Date: Thu July 14 14:11:26 2022 +0800
19*49cdfc7eSAndroid Build Coastguard Worker *
20*49cdfc7eSAndroid Build Coastguard Worker * fs: Add missing umask strip in vfs_tmpfile
21*49cdfc7eSAndroid Build Coastguard Worker *
22*49cdfc7eSAndroid Build Coastguard Worker * The most code is pasted form creat09.c.
23*49cdfc7eSAndroid Build Coastguard Worker */
24*49cdfc7eSAndroid Build Coastguard Worker
25*49cdfc7eSAndroid Build Coastguard Worker #define _GNU_SOURCE
26*49cdfc7eSAndroid Build Coastguard Worker #include <stdlib.h>
27*49cdfc7eSAndroid Build Coastguard Worker #include <sys/types.h>
28*49cdfc7eSAndroid Build Coastguard Worker #include <pwd.h>
29*49cdfc7eSAndroid Build Coastguard Worker #include <sys/mount.h>
30*49cdfc7eSAndroid Build Coastguard Worker #include <unistd.h>
31*49cdfc7eSAndroid Build Coastguard Worker #include <stdio.h>
32*49cdfc7eSAndroid Build Coastguard Worker #include "tst_test.h"
33*49cdfc7eSAndroid Build Coastguard Worker #include "lapi/fcntl.h"
34*49cdfc7eSAndroid Build Coastguard Worker #include "tst_uid.h"
35*49cdfc7eSAndroid Build Coastguard Worker #include "tst_safe_file_at.h"
36*49cdfc7eSAndroid Build Coastguard Worker
37*49cdfc7eSAndroid Build Coastguard Worker #define MODE_RWX 0777
38*49cdfc7eSAndroid Build Coastguard Worker #define MODE_SGID (S_ISGID|0777)
39*49cdfc7eSAndroid Build Coastguard Worker #define MNTPOINT "mntpoint"
40*49cdfc7eSAndroid Build Coastguard Worker #define WORKDIR MNTPOINT "/testdir"
41*49cdfc7eSAndroid Build Coastguard Worker #define OPEN_FILE "open.tmp"
42*49cdfc7eSAndroid Build Coastguard Worker
43*49cdfc7eSAndroid Build Coastguard Worker static gid_t free_gid;
44*49cdfc7eSAndroid Build Coastguard Worker static int tmpfile_fd = -1, dir_fd = -1, mount_flag;
45*49cdfc7eSAndroid Build Coastguard Worker static struct passwd *ltpuser;
46*49cdfc7eSAndroid Build Coastguard Worker
do_mount(const char * source,const char * target,const char * filesystemtype,unsigned long mountflags,const void * data)47*49cdfc7eSAndroid Build Coastguard Worker static void do_mount(const char *source, const char *target,
48*49cdfc7eSAndroid Build Coastguard Worker const char *filesystemtype, unsigned long mountflags,
49*49cdfc7eSAndroid Build Coastguard Worker const void *data)
50*49cdfc7eSAndroid Build Coastguard Worker {
51*49cdfc7eSAndroid Build Coastguard Worker TEST(mount(source, target, filesystemtype, mountflags, data));
52*49cdfc7eSAndroid Build Coastguard Worker
53*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1 && TST_ERR == EINVAL)
54*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF, "Kernel does not support noacl feature");
55*49cdfc7eSAndroid Build Coastguard Worker
56*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1) {
57*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "mount(%s, %s, %s, %lu, %p) failed",
58*49cdfc7eSAndroid Build Coastguard Worker source, target, filesystemtype, mountflags, data);
59*49cdfc7eSAndroid Build Coastguard Worker }
60*49cdfc7eSAndroid Build Coastguard Worker
61*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET)
62*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK, "Invalid mount return value %ld", TST_RET);
63*49cdfc7eSAndroid Build Coastguard Worker
64*49cdfc7eSAndroid Build Coastguard Worker mount_flag = 1;
65*49cdfc7eSAndroid Build Coastguard Worker }
66*49cdfc7eSAndroid Build Coastguard Worker
open_tmpfile_supported(int dirfd)67*49cdfc7eSAndroid Build Coastguard Worker static void open_tmpfile_supported(int dirfd)
68*49cdfc7eSAndroid Build Coastguard Worker {
69*49cdfc7eSAndroid Build Coastguard Worker TEST(openat(dirfd, ".", O_TMPFILE | O_RDWR, S_IXGRP | S_ISGID));
70*49cdfc7eSAndroid Build Coastguard Worker
71*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET == -1) {
72*49cdfc7eSAndroid Build Coastguard Worker if (errno == ENOTSUP)
73*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TCONF, "fs doesn't support O_TMPFILE");
74*49cdfc7eSAndroid Build Coastguard Worker else
75*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK | TTERRNO, "openat(%d, O_TMPFILE) failed", dirfd);
76*49cdfc7eSAndroid Build Coastguard Worker }
77*49cdfc7eSAndroid Build Coastguard Worker
78*49cdfc7eSAndroid Build Coastguard Worker if (TST_RET < 0)
79*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK, "Invalid openat return value %ld", TST_RET);
80*49cdfc7eSAndroid Build Coastguard Worker
81*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(TST_RET);
82*49cdfc7eSAndroid Build Coastguard Worker }
83*49cdfc7eSAndroid Build Coastguard Worker
setup(void)84*49cdfc7eSAndroid Build Coastguard Worker static void setup(void)
85*49cdfc7eSAndroid Build Coastguard Worker {
86*49cdfc7eSAndroid Build Coastguard Worker struct stat buf;
87*49cdfc7eSAndroid Build Coastguard Worker
88*49cdfc7eSAndroid Build Coastguard Worker ltpuser = SAFE_GETPWNAM("nobody");
89*49cdfc7eSAndroid Build Coastguard Worker
90*49cdfc7eSAndroid Build Coastguard Worker do_mount(tst_device->dev, MNTPOINT, tst_device->fs_type, 0, "noacl");
91*49cdfc7eSAndroid Build Coastguard Worker
92*49cdfc7eSAndroid Build Coastguard Worker tst_res(TINFO, "User nobody: uid = %d, gid = %d", (int)ltpuser->pw_uid,
93*49cdfc7eSAndroid Build Coastguard Worker (int)ltpuser->pw_gid);
94*49cdfc7eSAndroid Build Coastguard Worker free_gid = tst_get_free_gid(ltpuser->pw_gid);
95*49cdfc7eSAndroid Build Coastguard Worker
96*49cdfc7eSAndroid Build Coastguard Worker /* Create directories and set permissions */
97*49cdfc7eSAndroid Build Coastguard Worker SAFE_MKDIR(WORKDIR, MODE_RWX);
98*49cdfc7eSAndroid Build Coastguard Worker dir_fd = SAFE_OPEN(WORKDIR, O_RDONLY, O_DIRECTORY);
99*49cdfc7eSAndroid Build Coastguard Worker open_tmpfile_supported(dir_fd);
100*49cdfc7eSAndroid Build Coastguard Worker
101*49cdfc7eSAndroid Build Coastguard Worker SAFE_CHOWN(WORKDIR, ltpuser->pw_uid, free_gid);
102*49cdfc7eSAndroid Build Coastguard Worker SAFE_CHMOD(WORKDIR, MODE_SGID);
103*49cdfc7eSAndroid Build Coastguard Worker SAFE_STAT(WORKDIR, &buf);
104*49cdfc7eSAndroid Build Coastguard Worker
105*49cdfc7eSAndroid Build Coastguard Worker if (!(buf.st_mode & S_ISGID))
106*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK, "%s: Setgid bit not set", WORKDIR);
107*49cdfc7eSAndroid Build Coastguard Worker
108*49cdfc7eSAndroid Build Coastguard Worker if (buf.st_gid != free_gid) {
109*49cdfc7eSAndroid Build Coastguard Worker tst_brk(TBROK, "%s: Incorrect group, %u != %u", WORKDIR,
110*49cdfc7eSAndroid Build Coastguard Worker buf.st_gid, free_gid);
111*49cdfc7eSAndroid Build Coastguard Worker }
112*49cdfc7eSAndroid Build Coastguard Worker
113*49cdfc7eSAndroid Build Coastguard Worker /* Switch user */
114*49cdfc7eSAndroid Build Coastguard Worker SAFE_SETGID(ltpuser->pw_gid);
115*49cdfc7eSAndroid Build Coastguard Worker SAFE_SETREUID(-1, ltpuser->pw_uid);
116*49cdfc7eSAndroid Build Coastguard Worker }
117*49cdfc7eSAndroid Build Coastguard Worker
file_test(int dfd,const char * path,int flags)118*49cdfc7eSAndroid Build Coastguard Worker static void file_test(int dfd, const char *path, int flags)
119*49cdfc7eSAndroid Build Coastguard Worker {
120*49cdfc7eSAndroid Build Coastguard Worker struct stat buf;
121*49cdfc7eSAndroid Build Coastguard Worker
122*49cdfc7eSAndroid Build Coastguard Worker SAFE_FSTATAT(dfd, path, &buf, flags);
123*49cdfc7eSAndroid Build Coastguard Worker
124*49cdfc7eSAndroid Build Coastguard Worker TST_EXP_EQ_LI(buf.st_gid, free_gid);
125*49cdfc7eSAndroid Build Coastguard Worker
126*49cdfc7eSAndroid Build Coastguard Worker if (buf.st_mode & S_ISGID)
127*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "%s: Setgid bit is set", path);
128*49cdfc7eSAndroid Build Coastguard Worker else
129*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "%s: Setgid bit not set", path);
130*49cdfc7eSAndroid Build Coastguard Worker
131*49cdfc7eSAndroid Build Coastguard Worker if (buf.st_mode & S_IXGRP)
132*49cdfc7eSAndroid Build Coastguard Worker tst_res(TFAIL, "%s: S_IXGRP bit is set", path);
133*49cdfc7eSAndroid Build Coastguard Worker else
134*49cdfc7eSAndroid Build Coastguard Worker tst_res(TPASS, "%s: S_IXGRP bit is not set", path);
135*49cdfc7eSAndroid Build Coastguard Worker }
136*49cdfc7eSAndroid Build Coastguard Worker
run(void)137*49cdfc7eSAndroid Build Coastguard Worker static void run(void)
138*49cdfc7eSAndroid Build Coastguard Worker {
139*49cdfc7eSAndroid Build Coastguard Worker char path[PATH_MAX];
140*49cdfc7eSAndroid Build Coastguard Worker
141*49cdfc7eSAndroid Build Coastguard Worker umask(S_IXGRP);
142*49cdfc7eSAndroid Build Coastguard Worker tmpfile_fd = SAFE_OPENAT(dir_fd, ".", O_TMPFILE | O_RDWR, MODE_SGID);
143*49cdfc7eSAndroid Build Coastguard Worker snprintf(path, PATH_MAX, "/proc/self/fd/%d", tmpfile_fd);
144*49cdfc7eSAndroid Build Coastguard Worker SAFE_LINKAT(AT_FDCWD, path, dir_fd, OPEN_FILE, AT_SYMLINK_FOLLOW);
145*49cdfc7eSAndroid Build Coastguard Worker file_test(dir_fd, OPEN_FILE, 0);
146*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(tmpfile_fd);
147*49cdfc7eSAndroid Build Coastguard Worker /* Cleanup between loops */
148*49cdfc7eSAndroid Build Coastguard Worker tst_purge_dir(WORKDIR);
149*49cdfc7eSAndroid Build Coastguard Worker }
150*49cdfc7eSAndroid Build Coastguard Worker
cleanup(void)151*49cdfc7eSAndroid Build Coastguard Worker static void cleanup(void)
152*49cdfc7eSAndroid Build Coastguard Worker {
153*49cdfc7eSAndroid Build Coastguard Worker SAFE_SETREUID(-1, 0);
154*49cdfc7eSAndroid Build Coastguard Worker
155*49cdfc7eSAndroid Build Coastguard Worker if (tmpfile_fd >= 0)
156*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(tmpfile_fd);
157*49cdfc7eSAndroid Build Coastguard Worker if (dir_fd >= 0)
158*49cdfc7eSAndroid Build Coastguard Worker SAFE_CLOSE(dir_fd);
159*49cdfc7eSAndroid Build Coastguard Worker if (mount_flag && tst_umount(MNTPOINT))
160*49cdfc7eSAndroid Build Coastguard Worker tst_res(TWARN | TERRNO, "umount(%s)", MNTPOINT);
161*49cdfc7eSAndroid Build Coastguard Worker }
162*49cdfc7eSAndroid Build Coastguard Worker
163*49cdfc7eSAndroid Build Coastguard Worker static struct tst_test test = {
164*49cdfc7eSAndroid Build Coastguard Worker .test_all = run,
165*49cdfc7eSAndroid Build Coastguard Worker .setup = setup,
166*49cdfc7eSAndroid Build Coastguard Worker .cleanup = cleanup,
167*49cdfc7eSAndroid Build Coastguard Worker .needs_root = 1,
168*49cdfc7eSAndroid Build Coastguard Worker .all_filesystems = 1,
169*49cdfc7eSAndroid Build Coastguard Worker .format_device = 1,
170*49cdfc7eSAndroid Build Coastguard Worker .mntpoint = MNTPOINT,
171*49cdfc7eSAndroid Build Coastguard Worker .skip_filesystems = (const char*[]) {
172*49cdfc7eSAndroid Build Coastguard Worker "exfat",
173*49cdfc7eSAndroid Build Coastguard Worker "ntfs",
174*49cdfc7eSAndroid Build Coastguard Worker "vfat",
175*49cdfc7eSAndroid Build Coastguard Worker NULL
176*49cdfc7eSAndroid Build Coastguard Worker },
177*49cdfc7eSAndroid Build Coastguard Worker .tags = (const struct tst_tag[]) {
178*49cdfc7eSAndroid Build Coastguard Worker {"linux-git", "ac6800e279a2"},
179*49cdfc7eSAndroid Build Coastguard Worker {"linux-git", "426b4ca2d6a5"},
180*49cdfc7eSAndroid Build Coastguard Worker {}
181*49cdfc7eSAndroid Build Coastguard Worker },
182*49cdfc7eSAndroid Build Coastguard Worker };
183