• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
4  *   AUTHOR		: William Roske
5  */
6 /*
7  * Basic test for access(2) using F_OK, R_OK, W_OK and X_OK
8  */
9 #include <errno.h>
10 #include <unistd.h>
11 #include <sys/types.h>
12 #include <pwd.h>
13 #include "tst_test.h"
14 
15 #define FNAME_RWX "accessfile_rwx"
16 #define FNAME_R   "accessfile_r"
17 #define FNAME_W   "accessfile_w"
18 #define FNAME_X   "accessfile_x"
19 
20 #define DNAME_R   "accessdir_r"
21 #define DNAME_W   "accessdir_w"
22 #define DNAME_X   "accessdir_x"
23 #define DNAME_RW  "accessdir_rw"
24 #define DNAME_RX  "accessdir_rx"
25 #define DNAME_WX  "accessdir_wx"
26 
27 static uid_t uid;
28 
29 static struct tcase {
30 	const char *fname;
31 	int mode;
32 	char *name;
33 	int exp_errno;
34 	/* 1: nobody expected  2: root expected 3: both */
35 	int exp_user;
36 } tcases[] = {
37 	{FNAME_RWX, F_OK, "F_OK", 0, 3},
38 	{FNAME_RWX, X_OK, "X_OK", 0, 3},
39 	{FNAME_RWX, W_OK, "W_OK", 0, 3},
40 	{FNAME_RWX, R_OK, "R_OK", 0, 3},
41 
42 	{FNAME_RWX, R_OK|W_OK, "R_OK|W_OK", 0, 3},
43 	{FNAME_RWX, R_OK|X_OK, "R_OK|X_OK", 0, 3},
44 	{FNAME_RWX, W_OK|X_OK, "W_OK|X_OK", 0, 3},
45 	{FNAME_RWX, R_OK|W_OK|X_OK, "R_OK|W_OK|X_OK", 0, 3},
46 
47 	{FNAME_X, X_OK, "X_OK", 0, 3},
48 	{FNAME_W, W_OK, "W_OK", 0, 3},
49 	{FNAME_R, R_OK, "R_OK", 0, 3},
50 
51 	{FNAME_R, X_OK, "X_OK", EACCES, 3},
52 	{FNAME_R, W_OK, "W_OK", EACCES, 1},
53 	{FNAME_W, R_OK, "R_OK", EACCES, 1},
54 	{FNAME_W, X_OK, "X_OK", EACCES, 3},
55 	{FNAME_X, R_OK, "R_OK", EACCES, 1},
56 	{FNAME_X, W_OK, "W_OK", EACCES, 1},
57 
58 	{FNAME_R, W_OK|X_OK, "W_OK|X_OK", EACCES, 3},
59 	{FNAME_R, R_OK|X_OK, "R_OK|X_OK", EACCES, 3},
60 	{FNAME_R, R_OK|W_OK, "R_OK|W_OK", EACCES, 1},
61 	{FNAME_R, R_OK|W_OK|X_OK, "R_OK|W_OK|X_OK", EACCES, 3},
62 
63 	{FNAME_W, W_OK|X_OK, "W_OK|X_OK", EACCES, 3},
64 	{FNAME_W, R_OK|X_OK, "R_OK|X_OK", EACCES, 3},
65 	{FNAME_W, R_OK|W_OK, "R_OK|W_OK", EACCES, 1},
66 	{FNAME_W, R_OK|W_OK|X_OK, "R_OK|W_OK|X_OK", EACCES, 3},
67 
68 	{FNAME_X, W_OK|X_OK, "W_OK|X_OK", EACCES, 1},
69 	{FNAME_X, R_OK|X_OK, "R_OK|X_OK", EACCES, 1},
70 	{FNAME_X, R_OK|W_OK, "R_OK|W_OK", EACCES, 1},
71 	{FNAME_X, R_OK|W_OK|X_OK, "R_OK|W_OK|X_OK", EACCES, 1},
72 
73 	{FNAME_R, W_OK, "W_OK", 0, 2},
74 	{FNAME_R, R_OK|W_OK, "R_OK|W_OK", 0, 2},
75 
76 	{FNAME_W, R_OK, "R_OK", 0, 2},
77 	{FNAME_W, R_OK|W_OK, "R_OK|W_OK", 0, 2},
78 
79 	{FNAME_X, R_OK, "R_OK", 0, 2},
80 	{FNAME_X, W_OK, "W_OK", 0, 2},
81 	{FNAME_X, R_OK|W_OK, "R_OK|W_OK", 0, 2},
82 
83 	{DNAME_R"/"FNAME_R, F_OK, "F_OK", 0, 2},
84 	{DNAME_R"/"FNAME_R, R_OK, "R_OK", 0, 2},
85 	{DNAME_R"/"FNAME_R, W_OK, "W_OK", 0, 2},
86 
87 	{DNAME_R"/"FNAME_W, F_OK, "F_OK", 0, 2},
88 	{DNAME_R"/"FNAME_W, R_OK, "R_OK", 0, 2},
89 	{DNAME_R"/"FNAME_W, W_OK, "W_OK", 0, 2},
90 
91 	{DNAME_R"/"FNAME_X, F_OK, "F_OK", 0, 2},
92 	{DNAME_R"/"FNAME_X, R_OK, "R_OK", 0, 2},
93 	{DNAME_R"/"FNAME_X, W_OK, "W_OK", 0, 2},
94 	{DNAME_R"/"FNAME_X, X_OK, "X_OK", 0, 2},
95 
96 	{DNAME_W"/"FNAME_R, F_OK, "F_OK", 0, 2},
97 	{DNAME_W"/"FNAME_R, R_OK, "R_OK", 0, 2},
98 	{DNAME_W"/"FNAME_R, W_OK, "W_OK", 0, 2},
99 
100 	{DNAME_W"/"FNAME_W, F_OK, "F_OK", 0, 2},
101 	{DNAME_W"/"FNAME_W, R_OK, "R_OK", 0, 2},
102 	{DNAME_W"/"FNAME_W, W_OK, "W_OK", 0, 2},
103 
104 	{DNAME_W"/"FNAME_X, F_OK, "F_OK", 0, 2},
105 	{DNAME_W"/"FNAME_X, R_OK, "R_OK", 0, 2},
106 	{DNAME_W"/"FNAME_X, W_OK, "W_OK", 0, 2},
107 	{DNAME_W"/"FNAME_X, X_OK, "X_OK", 0, 2},
108 
109 	{DNAME_X"/"FNAME_R, F_OK, "F_OK", 0, 3},
110 	{DNAME_X"/"FNAME_R, R_OK, "R_OK", 0, 3},
111 	{DNAME_X"/"FNAME_R, W_OK, "W_OK", 0, 2},
112 
113 	{DNAME_X"/"FNAME_W, F_OK, "F_OK", 0, 3},
114 	{DNAME_X"/"FNAME_W, R_OK, "R_OK", 0, 2},
115 	{DNAME_X"/"FNAME_W, W_OK, "W_OK", 0, 3},
116 
117 	{DNAME_X"/"FNAME_X, F_OK, "F_OK", 0, 3},
118 	{DNAME_X"/"FNAME_X, R_OK, "R_OK", 0, 2},
119 	{DNAME_X"/"FNAME_X, W_OK, "W_OK", 0, 2},
120 	{DNAME_X"/"FNAME_X, X_OK, "X_OK", 0, 3},
121 
122 	{DNAME_RW"/"FNAME_R, F_OK, "F_OK", 0, 2},
123 	{DNAME_RW"/"FNAME_R, R_OK, "R_OK", 0, 2},
124 	{DNAME_RW"/"FNAME_R, W_OK, "W_OK", 0, 2},
125 
126 	{DNAME_RW"/"FNAME_W, F_OK, "F_OK", 0, 2},
127 	{DNAME_RW"/"FNAME_W, R_OK, "R_OK", 0, 2},
128 	{DNAME_RW"/"FNAME_W, W_OK, "W_OK", 0, 2},
129 
130 	{DNAME_RW"/"FNAME_X, F_OK, "F_OK", 0, 2},
131 	{DNAME_RW"/"FNAME_X, R_OK, "R_OK", 0, 2},
132 	{DNAME_RW"/"FNAME_X, W_OK, "W_OK", 0, 2},
133 	{DNAME_RW"/"FNAME_X, X_OK, "X_OK", 0, 2},
134 
135 	{DNAME_RX"/"FNAME_R, F_OK, "F_OK", 0, 3},
136 	{DNAME_RX"/"FNAME_R, R_OK, "R_OK", 0, 3},
137 	{DNAME_RX"/"FNAME_R, W_OK, "W_OK", 0, 2},
138 
139 	{DNAME_RX"/"FNAME_W, F_OK, "F_OK", 0, 3},
140 	{DNAME_RX"/"FNAME_W, R_OK, "R_OK", 0, 2},
141 	{DNAME_RX"/"FNAME_W, W_OK, "W_OK", 0, 3},
142 
143 	{DNAME_RX"/"FNAME_X, F_OK, "F_OK", 0, 3},
144 	{DNAME_RX"/"FNAME_X, R_OK, "R_OK", 0, 2},
145 	{DNAME_RX"/"FNAME_X, W_OK, "W_OK", 0, 2},
146 	{DNAME_RX"/"FNAME_X, X_OK, "X_OK", 0, 3},
147 
148 	{DNAME_WX"/"FNAME_R, F_OK, "F_OK", 0, 3},
149 	{DNAME_WX"/"FNAME_R, R_OK, "R_OK", 0, 3},
150 	{DNAME_WX"/"FNAME_R, W_OK, "W_OK", 0, 2},
151 
152 	{DNAME_WX"/"FNAME_W, F_OK, "F_OK", 0, 3},
153 	{DNAME_WX"/"FNAME_W, R_OK, "R_OK", 0, 2},
154 	{DNAME_WX"/"FNAME_W, W_OK, "W_OK", 0, 3},
155 
156 	{DNAME_WX"/"FNAME_X, F_OK, "F_OK", 0, 3},
157 	{DNAME_WX"/"FNAME_X, R_OK, "R_OK", 0, 2},
158 	{DNAME_WX"/"FNAME_X, W_OK, "W_OK", 0, 2},
159 	{DNAME_WX"/"FNAME_X, X_OK, "X_OK", 0, 3},
160 
161 	{DNAME_R"/"FNAME_R, F_OK, "F_OK", EACCES, 1},
162 	{DNAME_R"/"FNAME_R, R_OK, "R_OK", EACCES, 1},
163 	{DNAME_R"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
164 	{DNAME_R"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
165 
166 	{DNAME_R"/"FNAME_W, F_OK, "F_OK", EACCES, 1},
167 	{DNAME_R"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
168 	{DNAME_R"/"FNAME_W, W_OK, "W_OK", EACCES, 1},
169 	{DNAME_R"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
170 
171 	{DNAME_R"/"FNAME_X, F_OK, "F_OK", EACCES, 1},
172 	{DNAME_R"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
173 	{DNAME_R"/"FNAME_X, W_OK, "W_OK", EACCES, 1},
174 	{DNAME_R"/"FNAME_X, X_OK, "X_OK", EACCES, 1},
175 
176 	{DNAME_W"/"FNAME_R, F_OK, "F_OK", EACCES, 1},
177 	{DNAME_W"/"FNAME_R, R_OK, "R_OK", EACCES, 1},
178 	{DNAME_W"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
179 	{DNAME_W"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
180 
181 	{DNAME_W"/"FNAME_W, F_OK, "F_OK", EACCES, 1},
182 	{DNAME_W"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
183 	{DNAME_W"/"FNAME_W, W_OK, "W_OK", EACCES, 1},
184 	{DNAME_W"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
185 
186 	{DNAME_W"/"FNAME_X, F_OK, "F_OK", EACCES, 1},
187 	{DNAME_W"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
188 	{DNAME_W"/"FNAME_X, W_OK, "W_OK", EACCES, 1},
189 	{DNAME_W"/"FNAME_X, X_OK, "X_OK", EACCES, 1},
190 
191 	{DNAME_X"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
192 	{DNAME_X"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
193 
194 	{DNAME_X"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
195 	{DNAME_X"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
196 
197 	{DNAME_X"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
198 	{DNAME_X"/"FNAME_X, W_OK, "W_OK", EACCES, 1},
199 
200 	{DNAME_RW"/"FNAME_R, F_OK, "F_OK", EACCES, 1},
201 	{DNAME_RW"/"FNAME_R, R_OK, "R_OK", EACCES, 1},
202 	{DNAME_RW"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
203 	{DNAME_RW"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
204 
205 	{DNAME_RW"/"FNAME_W, F_OK, "F_OK", EACCES, 1},
206 	{DNAME_RW"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
207 	{DNAME_RW"/"FNAME_W, W_OK, "W_OK", EACCES, 1},
208 	{DNAME_RW"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
209 
210 	{DNAME_RW"/"FNAME_X, F_OK, "F_OK", EACCES, 1},
211 	{DNAME_RW"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
212 	{DNAME_RW"/"FNAME_X, W_OK, "W_OK", EACCES, 1},
213 	{DNAME_RW"/"FNAME_X, X_OK, "X_OK", EACCES, 1},
214 
215 	{DNAME_RX"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
216 	{DNAME_RX"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
217 
218 	{DNAME_RX"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
219 	{DNAME_RX"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
220 
221 	{DNAME_RX"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
222 	{DNAME_RX"/"FNAME_X, W_OK, "W_OK", EACCES, 1},
223 
224 	{DNAME_WX"/"FNAME_R, W_OK, "W_OK", EACCES, 1},
225 	{DNAME_WX"/"FNAME_R, X_OK, "X_OK", EACCES, 3},
226 
227 	{DNAME_WX"/"FNAME_W, R_OK, "R_OK", EACCES, 1},
228 	{DNAME_WX"/"FNAME_W, X_OK, "X_OK", EACCES, 3},
229 
230 	{DNAME_WX"/"FNAME_X, R_OK, "R_OK", EACCES, 1},
231 	{DNAME_WX"/"FNAME_X, W_OK, "W_OK", EACCES, 1}
232 };
233 
access_test(struct tcase * tc,const char * user)234 static void access_test(struct tcase *tc, const char *user)
235 {
236 	if (tc->exp_errno) {
237 		TST_EXP_FAIL(access(tc->fname, tc->mode), tc->exp_errno,
238 		             "access(%s, %s) as %s", tc->fname, tc->name, user);
239 	} else {
240 		TST_EXP_PASS(access(tc->fname, tc->mode),
241 		             "access(%s, %s) as %s", tc->fname, tc->name, user);
242 	}
243 }
244 
verify_access(unsigned int n)245 static void verify_access(unsigned int n)
246 {
247 	struct tcase *tc = tcases + n;
248 	pid_t pid;
249 
250 	if (tc->exp_user & 0x02)
251 		access_test(tc, "root");
252 
253 	if (tc->exp_user & 0x01) {
254 		pid = SAFE_FORK();
255 		if (pid) {
256 			SAFE_WAITPID(pid, NULL, 0);
257 		} else {
258 			SAFE_SETUID(uid);
259 			access_test(tc, "nobody");
260 		}
261 	}
262 }
263 
setup(void)264 static void setup(void)
265 {
266 	struct passwd *pw;
267 
268 	umask(0022);
269 
270 	pw = SAFE_GETPWNAM("nobody");
271 
272 	uid = pw->pw_uid;
273 
274 	SAFE_TOUCH(FNAME_RWX, 0777, NULL);
275 	SAFE_TOUCH(FNAME_R, 0444, NULL);
276 	SAFE_TOUCH(FNAME_W, 0222, NULL);
277 	SAFE_TOUCH(FNAME_X, 0111, NULL);
278 
279 	SAFE_MKDIR(DNAME_R, 0444);
280 	SAFE_MKDIR(DNAME_W, 0222);
281 	SAFE_MKDIR(DNAME_X, 0111);
282 	SAFE_MKDIR(DNAME_RW, 0666);
283 	SAFE_MKDIR(DNAME_RX, 0555);
284 	SAFE_MKDIR(DNAME_WX, 0333);
285 
286 	SAFE_TOUCH(DNAME_R"/"FNAME_R, 0444, NULL);
287 	SAFE_TOUCH(DNAME_R"/"FNAME_W, 0222, NULL);
288 	SAFE_TOUCH(DNAME_R"/"FNAME_X, 0111, NULL);
289 
290 	SAFE_TOUCH(DNAME_W"/"FNAME_R, 0444, NULL);
291 	SAFE_TOUCH(DNAME_W"/"FNAME_W, 0222, NULL);
292 	SAFE_TOUCH(DNAME_W"/"FNAME_X, 0111, NULL);
293 
294 	SAFE_TOUCH(DNAME_X"/"FNAME_R, 0444, NULL);
295 	SAFE_TOUCH(DNAME_X"/"FNAME_W, 0222, NULL);
296 	SAFE_TOUCH(DNAME_X"/"FNAME_X, 0111, NULL);
297 
298 	SAFE_TOUCH(DNAME_RW"/"FNAME_R, 0444, NULL);
299 	SAFE_TOUCH(DNAME_RW"/"FNAME_W, 0222, NULL);
300 	SAFE_TOUCH(DNAME_RW"/"FNAME_X, 0111, NULL);
301 
302 	SAFE_TOUCH(DNAME_RX"/"FNAME_R, 0444, NULL);
303 	SAFE_TOUCH(DNAME_RX"/"FNAME_W, 0222, NULL);
304 	SAFE_TOUCH(DNAME_RX"/"FNAME_X, 0111, NULL);
305 
306 	SAFE_TOUCH(DNAME_WX"/"FNAME_R, 0444, NULL);
307 	SAFE_TOUCH(DNAME_WX"/"FNAME_W, 0222, NULL);
308 	SAFE_TOUCH(DNAME_WX"/"FNAME_X, 0111, NULL);
309 }
310 
311 static struct tst_test test = {
312 	.needs_tmpdir = 1,
313 	.needs_root = 1,
314 	.forks_child = 1,
315 	.setup = setup,
316 	.test = verify_access,
317 	.tcnt = ARRAY_SIZE(tcases),
318 };
319