1 /*
2 * Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
3 * Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without modification,
6 * are permitted provided that the following conditions are met:
7 *
8 * 1. Redistributions of source code must retain the above copyright notice, this list of
9 * conditions and the following disclaimer.
10 *
11 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 * of conditions and the following disclaimer in the documentation and/or other materials
13 * provided with the distribution.
14 *
15 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
16 * to endorse or promote products derived from this software without specific prior written
17 * permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
24 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
25 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
26 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
27 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
28 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
29 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 */
31 #include "pthread.h"
32 #include "linux/capability.h"
33 #include "it_test_reugid.h"
34 #include <signal.h>
35 #include <sys/types.h>
36 #include <time.h>
37
Child1(int * list,int listSize)38 static int Child1(int *list, int listSize)
39 {
40 int getList[500];
41 int ruid = 0;
42 int euid = 0;
43 int suid = 100;
44 int rgid = 0;
45 int egid = 0;
46 int sgid = 100;
47 int ret;
48
49 rgid = getgid();
50 ICUNIT_ASSERT_EQUAL(rgid, 300, rgid);
51 egid = getegid();
52 ICUNIT_ASSERT_EQUAL(egid, 300, egid);
53
54 ret = getresgid((gid_t *)&ruid, (gid_t *)&euid, (gid_t *)&suid);
55 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
56 ICUNIT_ASSERT_EQUAL(ruid, 300, ruid);
57 ICUNIT_ASSERT_EQUAL(euid, 300, euid);
58 ICUNIT_ASSERT_EQUAL(suid, 300, suid);
59
60 ruid = getuid();
61 ICUNIT_ASSERT_EQUAL(ruid, 300, ruid);
62 euid = geteuid();
63 ICUNIT_ASSERT_EQUAL(euid, 300, euid);
64
65 ret = getresuid((gid_t *)&ruid, (gid_t *)&euid, (gid_t *)&suid);
66 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
67 ICUNIT_ASSERT_EQUAL(ruid, 300, ruid);
68 ICUNIT_ASSERT_EQUAL(euid, 300, euid);
69 ICUNIT_ASSERT_EQUAL(suid, 300, suid);
70
71 int size = getgroups(0, (gid_t *)getList);
72 ICUNIT_ASSERT_EQUAL(size, listSize, size);
73
74 size = getgroups(size, (gid_t *)getList);
75 ICUNIT_ASSERT_EQUAL(size, listSize, size);
76 for (int i = 0; i < size - 1; i++) {
77 ICUNIT_ASSERT_EQUAL(getList[i], list[i], getList[i]);
78 }
79
80 getList[size - 1] = 500;
81 ret = setgroups(0, (gid_t *)getList);
82 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
83
84 ret = getgroups(0, NULL);
85 ICUNIT_ASSERT_EQUAL(ret, 1, ret);
86
87 ret = getgroups(ret, (gid_t *)getList);
88 ICUNIT_ASSERT_EQUAL(ret, 1, ret);
89 ICUNIT_ASSERT_EQUAL(getList[0], getgid(), getList[0]);
90
91 exit(255);
92 }
93
Child(void)94 static int Child(void)
95 {
96 int size;
97 int ret;
98 int list[500];
99 int getList[500];
100 int ruid = 0;
101 int euid = 0;
102 int suid = 100;
103 int rgid = 0;
104 int egid = 0;
105 int sgid = 100;
106
107 ret = setgid(3000);
108 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
109 ret = getgid();
110 ICUNIT_ASSERT_EQUAL(ret, 3000, ret);
111 ret = getegid();
112 ICUNIT_ASSERT_EQUAL(ret, 3000, ret);
113
114 ret = setegid(3000);
115 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
116 ret = getgid();
117 ICUNIT_ASSERT_EQUAL(ret, 3000, ret);
118 ret = getegid();
119 ICUNIT_ASSERT_EQUAL(ret, 3000, ret);
120
121 ret = setgid(-1);
122 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
123 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
124 ret = setegid(-2);
125 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
126 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
127
128 list[0] = 1000;
129 list[1] = 2000;
130 list[2] = 3000;
131 list[3] = 4000;
132 list[4] = 5000;
133 ret = setgroups(5, (gid_t *)list);
134 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
135
136 size = getgroups(0, (gid_t *)getList);
137 ICUNIT_ASSERT_EQUAL(size, 5, size);
138
139 size = getgroups(size, (gid_t *)getList);
140 ICUNIT_ASSERT_EQUAL(size, 5, size);
141
142 for (int i = 0; i < size; i++) {
143 ICUNIT_ASSERT_EQUAL(getList[i], list[i], getList[i]);
144 }
145
146 list[0] = 1000;
147 list[1] = 2000;
148 list[2] = 6000;
149 list[3] = 4000;
150 list[4] = 5000;
151 list[5] = -1;
152 ret = setgroups(6, (gid_t *)list);
153 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
154 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
155
156 list[0] = 1000;
157 list[1] = 2000;
158 list[2] = 6000;
159 list[3] = 4000;
160 list[4] = 5000;
161 list[5] = 7000;
162 ret = setgroups(6, (gid_t *)list);
163 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
164
165 size = getgroups(0, (gid_t *)getList);
166 ICUNIT_ASSERT_EQUAL(size, 7, size);
167
168 size = getgroups(0, NULL);
169 ICUNIT_ASSERT_EQUAL(size, 7, size);
170
171 size = getgroups(size, (gid_t *)getList);
172 ICUNIT_ASSERT_EQUAL(size, 7, size);
173 for (int i = 0; i < size - 1; i++) {
174 ICUNIT_ASSERT_EQUAL(getList[i], list[i], getList[i]);
175 }
176
177 ICUNIT_ASSERT_EQUAL(getList[size - 1], getgid(), getList[size - 1]);
178
179 ret = seteuid(8000);
180 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
181
182 ret = geteuid();
183 ICUNIT_ASSERT_EQUAL(ret, 8000, ret);
184
185 ret = setuid(2000);
186 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
187 ret = geteuid();
188 ICUNIT_ASSERT_EQUAL(ret, 2000, ret);
189 ret = getuid();
190 ICUNIT_ASSERT_EQUAL(ret, 2000, ret);
191
192 ret = setuid(-1);
193 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
194 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
195 ret = seteuid(-2);
196 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
197 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
198
199 ret = setregid(5000, 300);
200 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
201 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
202
203 ret = setregid(5000, 5000);
204 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
205 ret = getgid();
206 ICUNIT_ASSERT_EQUAL(ret, 5000, ret);
207 egid = getegid();
208 ICUNIT_ASSERT_EQUAL(egid, 5000, egid);
209
210 ret = setregid(5000, -1);
211 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
212 ret = getgid();
213 ICUNIT_ASSERT_EQUAL(ret, 5000, ret);
214 egid = getegid();
215 ICUNIT_ASSERT_EQUAL(egid, 5000, egid);
216
217 ret = setregid(3000, -2);
218 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
219 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
220
221 ret = setregid(-5, -2);
222 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
223 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
224
225 ret = setregid(3000, -1);
226 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
227 ret = getgid();
228 ICUNIT_ASSERT_EQUAL(ret, 3000, ret);
229 egid = getegid();
230 ICUNIT_ASSERT_EQUAL(egid, 3000, egid);
231
232 ret = setreuid(1000, 3000);
233 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
234 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
235
236 ret = setreuid(1000, -2);
237 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
238 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
239
240 ret = setreuid(-2, -2);
241 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
242 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
243
244 ret = setreuid(-1, 3000);
245 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
246 ruid = getuid();
247 ICUNIT_ASSERT_EQUAL(ruid, 3000, ruid);
248 euid = geteuid();
249 ICUNIT_ASSERT_EQUAL(euid, 3000, euid);
250
251 ret = setreuid(1000, -1);
252 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
253 ruid = getuid();
254 ICUNIT_ASSERT_EQUAL(ruid, 1000, ruid);
255 euid = geteuid();
256 ICUNIT_ASSERT_EQUAL(euid, 1000, euid);
257
258 ret = setresuid(100, 100, 100);
259 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
260 ret = getresuid((uid_t *)&ruid, (uid_t *)&euid, (uid_t *)&suid);
261 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
262 ICUNIT_ASSERT_EQUAL(ruid, 100, ruid);
263 ICUNIT_ASSERT_EQUAL(euid, 100, euid);
264 ICUNIT_ASSERT_EQUAL(suid, 100, suid);
265
266 ret = setresuid(200, 100, 100);
267 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
268 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
269
270 ret = setresuid(100, 100, 200);
271 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
272 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
273
274 ret = setresuid(100, 200, 200);
275 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
276 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
277
278 ret = setresuid(-1, 200, 200);
279 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
280 ret = getresuid((uid_t *)&ruid, (uid_t *)&euid, (uid_t *)&suid);
281 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
282 ICUNIT_ASSERT_EQUAL(ruid, 200, ruid);
283 ICUNIT_ASSERT_EQUAL(euid, 200, euid);
284 ICUNIT_ASSERT_EQUAL(suid, 200, suid);
285
286 ret = setresuid(-1, -1, 300);
287 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
288 ret = getresuid((uid_t *)&ruid, (uid_t *)&euid, (uid_t *)&suid);
289 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
290 ICUNIT_ASSERT_EQUAL(ruid, 300, ruid);
291 ICUNIT_ASSERT_EQUAL(euid, 300, euid);
292 ICUNIT_ASSERT_EQUAL(suid, 300, suid);
293
294 ret = setresuid(-1, 200, 300);
295 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
296 ret = setresuid(-1, -2, 200);
297 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
298 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
299
300 ret = setresuid(-2, 200, 200);
301 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
302 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
303
304 ret = setresuid(200, -2, 200);
305 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
306 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
307
308 ret = setresuid(200, 200, -3);
309 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
310 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
311
312 ret = setresgid(100, 100, 100);
313 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
314 ret = getresgid((gid_t *)&rgid, (gid_t *)&egid, (gid_t *)&sgid);
315 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
316 ICUNIT_ASSERT_EQUAL(rgid, 100, rgid);
317 ICUNIT_ASSERT_EQUAL(egid, 100, egid);
318 ICUNIT_ASSERT_EQUAL(sgid, 100, sgid);
319
320 ret = setresgid(200, 100, 100);
321 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
322 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
323
324 ret = setresgid(100, 100, 200);
325 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
326 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
327
328 ret = setresgid(100, 200, 200);
329 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
330 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
331
332 ret = setresgid(-2, 100, 200);
333 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
334 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
335 ret = setresgid(100, -2, 200);
336 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
337 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
338 ret = setresgid(100, 100, -2);
339 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
340 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
341 ret = setresgid(100, -1, -2);
342 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
343 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
344 ret = setresgid(-1, 200, 200);
345 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
346 ret = getresgid((gid_t *)&rgid, (gid_t *)&egid, (gid_t *)&sgid);
347 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
348 ICUNIT_ASSERT_EQUAL(rgid, 200, rgid);
349 ICUNIT_ASSERT_EQUAL(egid, 200, egid);
350 ICUNIT_ASSERT_EQUAL(sgid, 200, sgid);
351
352 ret = setresgid(-1, -1, 300);
353 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
354 ret = getresgid((gid_t *)&rgid, (gid_t *)&egid, (gid_t *)&sgid);
355 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
356 ICUNIT_ASSERT_EQUAL(rgid, 300, rgid);
357 ICUNIT_ASSERT_EQUAL(egid, 300, egid);
358 ICUNIT_ASSERT_EQUAL(sgid, 300, sgid);
359
360 ret = setresgid(-1, 200, 300);
361 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
362 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
363
364 size = getgroups(0, (gid_t *)getList);
365 size = getgroups(size, (gid_t *)getList);
366 pid_t pid = fork();
367 if (pid == 0) {
368 Child1(getList, size);
369 exit(__LINE__);
370 }
371
372 int status = 0;
373 ret = waitpid(pid, &status, 0);
374 ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT);
375 status = WEXITSTATUS(status);
376 ICUNIT_GOTO_EQUAL(status, 255, status, EXIT);
377
378 ret = setgroups(0, NULL);
379 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
380
381 ret = getgroups(0, (gid_t *)getList);
382 ICUNIT_ASSERT_EQUAL(ret, 1, ret);
383
384 ret = getgroups(1, (gid_t *)getList);
385 ICUNIT_ASSERT_EQUAL(ret, 1, ret);
386 ICUNIT_ASSERT_EQUAL(getList[0], getgid(), getList[0]);
387
388 ret = setreuid(-1, -1);
389 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
390 ret = setregid(-1, -1);
391 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
392 ret = setresuid(-1, -1, -1);
393 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
394 ret = setresuid(-1, -1, -1);
395 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
396 ret = setegid(-1);
397 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
398 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
399 ret = seteuid(-1);
400 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
401 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
402
403 exit(255);
404
405 EXIT:
406 return 1;
407 }
408
TestCase(VOID)409 static int TestCase(VOID)
410 {
411 int ret;
412 int status = 0;
413 pid_t pid = fork();
414 ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT);
415 if (pid == 0) {
416 ret = Child();
417 exit(__LINE__);
418 }
419
420 ret = waitpid(pid, &status, 0);
421 ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT);
422 status = WEXITSTATUS(status);
423 ICUNIT_GOTO_EQUAL(status, 255, status, EXIT);
424
425 return 0;
426
427 EXIT:
428 return 1;
429 }
430
ItTestReugid001(void)431 void ItTestReugid001(void)
432 {
433 TEST_ADD_CASE("IT_SEC_UGID_001", TestCase, TEST_POSIX, TEST_SEC, TEST_LEVEL0, TEST_FUNCTION);
434 }
435