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
verify_success(struct tcase * tc,const char * user)234 static void verify_success(struct tcase *tc, const char *user)
235 {
236 if (TST_RET == -1) {
237 tst_res(TFAIL | TTERRNO,
238 "access(%s, %s) as %s failed unexpectedly",
239 tc->fname, tc->name, user);
240 return;
241 }
242
243 tst_res(TPASS, "access(%s, %s) as %s", tc->fname, tc->name, user);
244 }
245
verify_failure(struct tcase * tc,const char * user)246 static void verify_failure(struct tcase *tc, const char *user)
247 {
248 if (TST_RET != -1) {
249 tst_res(TFAIL, "access(%s, %s) as %s succeded unexpectedly",
250 tc->fname, tc->name, user);
251 return;
252 }
253
254 if (TST_ERR != tc->exp_errno) {
255 tst_res(TFAIL | TTERRNO,
256 "access(%s, %s) as %s should fail with %s",
257 tc->fname, tc->name, user,
258 tst_strerrno(tc->exp_errno));
259 return;
260 }
261
262 tst_res(TPASS | TTERRNO, "access(%s, %s) as %s",
263 tc->fname, tc->name, user);
264 }
265
access_test(struct tcase * tc,const char * user)266 static void access_test(struct tcase *tc, const char *user)
267 {
268 TEST(access(tc->fname, tc->mode));
269
270 if (tc->exp_errno)
271 verify_failure(tc, user);
272 else
273 verify_success(tc, user);
274 }
275
verify_access(unsigned int n)276 static void verify_access(unsigned int n)
277 {
278 struct tcase *tc = tcases + n;
279 pid_t pid;
280
281 if (tc->exp_user & 0x02)
282 access_test(tc, "root");
283
284 if (tc->exp_user & 0x01) {
285 pid = SAFE_FORK();
286 if (pid) {
287 SAFE_WAITPID(pid, NULL, 0);
288 } else {
289 SAFE_SETUID(uid);
290 access_test(tc, "nobody");
291 }
292 }
293 }
294
setup(void)295 static void setup(void)
296 {
297 struct passwd *pw;
298
299 umask(0022);
300
301 pw = SAFE_GETPWNAM("nobody");
302
303 uid = pw->pw_uid;
304
305 SAFE_TOUCH(FNAME_RWX, 0777, NULL);
306 SAFE_TOUCH(FNAME_R, 0444, NULL);
307 SAFE_TOUCH(FNAME_W, 0222, NULL);
308 SAFE_TOUCH(FNAME_X, 0111, NULL);
309
310 SAFE_MKDIR(DNAME_R, 0444);
311 SAFE_MKDIR(DNAME_W, 0222);
312 SAFE_MKDIR(DNAME_X, 0111);
313 SAFE_MKDIR(DNAME_RW, 0666);
314 SAFE_MKDIR(DNAME_RX, 0555);
315 SAFE_MKDIR(DNAME_WX, 0333);
316
317 SAFE_TOUCH(DNAME_R"/"FNAME_R, 0444, NULL);
318 SAFE_TOUCH(DNAME_R"/"FNAME_W, 0222, NULL);
319 SAFE_TOUCH(DNAME_R"/"FNAME_X, 0111, NULL);
320
321 SAFE_TOUCH(DNAME_W"/"FNAME_R, 0444, NULL);
322 SAFE_TOUCH(DNAME_W"/"FNAME_W, 0222, NULL);
323 SAFE_TOUCH(DNAME_W"/"FNAME_X, 0111, NULL);
324
325 SAFE_TOUCH(DNAME_X"/"FNAME_R, 0444, NULL);
326 SAFE_TOUCH(DNAME_X"/"FNAME_W, 0222, NULL);
327 SAFE_TOUCH(DNAME_X"/"FNAME_X, 0111, NULL);
328
329 SAFE_TOUCH(DNAME_RW"/"FNAME_R, 0444, NULL);
330 SAFE_TOUCH(DNAME_RW"/"FNAME_W, 0222, NULL);
331 SAFE_TOUCH(DNAME_RW"/"FNAME_X, 0111, NULL);
332
333 SAFE_TOUCH(DNAME_RX"/"FNAME_R, 0444, NULL);
334 SAFE_TOUCH(DNAME_RX"/"FNAME_W, 0222, NULL);
335 SAFE_TOUCH(DNAME_RX"/"FNAME_X, 0111, NULL);
336
337 SAFE_TOUCH(DNAME_WX"/"FNAME_R, 0444, NULL);
338 SAFE_TOUCH(DNAME_WX"/"FNAME_W, 0222, NULL);
339 SAFE_TOUCH(DNAME_WX"/"FNAME_X, 0111, NULL);
340 }
341
342 static struct tst_test test = {
343 .needs_tmpdir = 1,
344 .needs_root = 1,
345 .forks_child = 1,
346 .setup = setup,
347 .test = verify_access,
348 .tcnt = ARRAY_SIZE(tcases),
349 };
350