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