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(reinterpret_cast<gid_t *>(&ruid), reinterpret_cast<gid_t *>(&euid),
55 reinterpret_cast<gid_t *>(&suid));
56 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
57 ICUNIT_ASSERT_EQUAL(ruid, 300, ruid); // 300: expected ruid
58 ICUNIT_ASSERT_EQUAL(euid, 300, euid); // 300: expected euid
59 ICUNIT_ASSERT_EQUAL(suid, 300, suid);
60
61 ruid = getuid();
62 ICUNIT_ASSERT_EQUAL(ruid, 300, ruid);
63 euid = geteuid();
64 ICUNIT_ASSERT_EQUAL(euid, 300, euid);
65
66 ret = getresuid(reinterpret_cast<gid_t *>(&ruid), reinterpret_cast<gid_t *>(&euid),
67 reinterpret_cast<gid_t *>(&suid));
68 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
69 ICUNIT_ASSERT_EQUAL(ruid, 300, ruid); // 300: expected ruid
70 ICUNIT_ASSERT_EQUAL(euid, 300, euid);
71 ICUNIT_ASSERT_EQUAL(suid, 300, suid);
72
73 int size = getgroups(0, reinterpret_cast<gid_t *>(getList));
74 ICUNIT_ASSERT_EQUAL(size, listSize, size);
75
76 size = getgroups(size, reinterpret_cast<gid_t *>(getList));
77 ICUNIT_ASSERT_EQUAL(size, listSize, size);
78 for (int i = 0; i < size - 1; i++) {
79 ICUNIT_ASSERT_EQUAL(getList[i], list[i], getList[i]);
80 }
81
82 getList[size - 1] = 500;
83 ret = setgroups(0, reinterpret_cast<gid_t *>(getList));
84 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
85
86 ret = getgroups(0, NULL);
87 ICUNIT_ASSERT_EQUAL(ret, 1, ret);
88
89 ret = getgroups(ret, reinterpret_cast<gid_t *>(getList));
90 ICUNIT_ASSERT_EQUAL(ret, 1, ret);
91 ICUNIT_ASSERT_EQUAL(getList[0], getgid(), getList[0]);
92
93 exit(255);
94 }
95
Child(void)96 static int Child(void)
97 {
98 int size;
99 int ret;
100 int list[500];
101 int getList[500];
102 int ruid = 0;
103 int euid = 0;
104 int suid = 100;
105 int rgid = 0;
106 int egid = 0;
107 int sgid = 100;
108
109 ret = setgid(3000);
110 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
111 ret = getgid();
112 ICUNIT_ASSERT_EQUAL(ret, 3000, ret);
113 ret = getegid();
114 ICUNIT_ASSERT_EQUAL(ret, 3000, ret); // 3000: expected egid
115
116 ret = setegid(3000);
117 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
118 ret = getgid();
119 ICUNIT_ASSERT_EQUAL(ret, 3000, ret);
120 ret = getegid();
121 ICUNIT_ASSERT_EQUAL(ret, 3000, ret);
122
123 ret = setgid(-1);
124 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
125 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
126 ret = setegid(-2);
127 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
128 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
129
130 list[0] = 1000; // 1000: preset value of list[0]
131 list[1] = 2000; // 2000: preset value of list[1]
132 list[2] = 3000; // 3000: preset value of list[2]
133 list[3] = 4000; // 4000: preset value of list[3]
134 list[4] = 5000; // 5000: preset value of list[4]
135 ret = setgroups(5, reinterpret_cast<gid_t *>(list)); // 5: set groupid for testing
136 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
137
138 size = getgroups(0, reinterpret_cast<gid_t *>(getList));
139 ICUNIT_ASSERT_EQUAL(size, 5, size);
140
141 size = getgroups(size, reinterpret_cast<gid_t *>(getList));
142 ICUNIT_ASSERT_EQUAL(size, 5, size);
143
144 for (int i = 0; i < size; i++) {
145 ICUNIT_ASSERT_EQUAL(getList[i], list[i], getList[i]);
146 }
147
148 list[0] = 1000; // 1000: preset value of list[0]
149 list[1] = 2000; // 2000: preset value of list[1]
150 list[2] = 6000; // 6000: preset value of list[2]
151 list[3] = 4000; // 4000: preset value of list[3]
152 list[4] = 5000; // 5000: preset value of list[4]
153 list[5] = -1;
154 ret = setgroups(6, reinterpret_cast<gid_t *>(list)); // 6: set groupid for testing
155 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
156 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
157
158 list[0] = 1000; // 1000: preset value of list[0]
159 list[1] = 2000; // 2000: preset value of list[1]
160 list[2] = 6000; // 6000: preset value of list[2]
161 list[3] = 4000; // 4000: preset value of list[3]
162 list[4] = 5000; // 5000: preset value of list[4]
163 list[5] = 7000;
164 ret = setgroups(6, reinterpret_cast<gid_t *>(list)); // 6: set groupid for testing
165 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
166
167 size = getgroups(0, reinterpret_cast<gid_t *>(getList));
168 ICUNIT_ASSERT_EQUAL(size, 7, size);
169
170 size = getgroups(0, NULL);
171 ICUNIT_ASSERT_EQUAL(size, 7, size);
172
173 size = getgroups(size, reinterpret_cast<gid_t *>(getList));
174 ICUNIT_ASSERT_EQUAL(size, 7, size);
175 for (int i = 0; i < size - 1; i++) {
176 ICUNIT_ASSERT_EQUAL(getList[i], list[i], getList[i]);
177 }
178
179 ICUNIT_ASSERT_EQUAL(getList[size - 1], getgid(), getList[size - 1]);
180
181 ret = seteuid(8000);
182 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
183
184 ret = geteuid();
185 ICUNIT_ASSERT_EQUAL(ret, 8000, ret); // 8000: expected value of euid
186
187 ret = setuid(2000);
188 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
189 ret = geteuid();
190 ICUNIT_ASSERT_EQUAL(ret, 2000, ret);
191 ret = getuid();
192 ICUNIT_ASSERT_EQUAL(ret, 2000, ret);
193
194 ret = setuid(-1);
195 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
196 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
197 ret = seteuid(-2);
198 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
199 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
200
201 ret = setregid(5000, 300);
202 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
203 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
204
205 ret = setregid(5000, 5000);
206 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
207 ret = getgid();
208 ICUNIT_ASSERT_EQUAL(ret, 5000, ret); // 5000: expected value of gid
209 egid = getegid();
210 ICUNIT_ASSERT_EQUAL(egid, 5000, egid); // 5000: expected value of egid
211
212 ret = setregid(5000, -1);
213 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
214 ret = getgid();
215 ICUNIT_ASSERT_EQUAL(ret, 5000, ret); // 5000: expected value of gid
216 egid = getegid();
217 ICUNIT_ASSERT_EQUAL(egid, 5000, egid); // 5000: expected value of egid
218
219 ret = setregid(3000, -2);
220 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
221 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
222
223 ret = setregid(-5, -2);
224 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
225 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
226
227 ret = setregid(3000, -1);
228 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
229 ret = getgid();
230 ICUNIT_ASSERT_EQUAL(ret, 3000, ret); // 3000: expected value of gid
231 egid = getegid();
232 ICUNIT_ASSERT_EQUAL(egid, 3000, egid); // 3000: expected value of egid
233
234 ret = setreuid(1000, 3000);
235 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
236 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
237
238 ret = setreuid(1000, -2);
239 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
240 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
241
242 ret = setreuid(-2, -2);
243 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
244 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
245
246 ret = setreuid(-1, 3000);
247 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
248 ruid = getuid();
249 ICUNIT_ASSERT_EQUAL(ruid, 3000, ruid); // 3000: expected value of ruid
250 euid = geteuid();
251 ICUNIT_ASSERT_EQUAL(euid, 3000, euid); // 3000: expected value of euid
252
253 ret = setreuid(1000, -1);
254 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
255 ruid = getuid();
256 ICUNIT_ASSERT_EQUAL(ruid, 1000, ruid); // 1000: expected value of ruid
257 euid = geteuid();
258 ICUNIT_ASSERT_EQUAL(euid, 1000, euid); // 1000: expected value of euid
259
260 ret = setresuid(100, 100, 100);
261 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
262 ret = getresuid(reinterpret_cast<uid_t *>(&ruid), reinterpret_cast<uid_t *>(&euid),
263 reinterpret_cast<uid_t *>(&suid));
264 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
265 ICUNIT_ASSERT_EQUAL(ruid, 100, ruid);
266 ICUNIT_ASSERT_EQUAL(euid, 100, euid); // 100: expected value of euid
267 ICUNIT_ASSERT_EQUAL(suid, 100, suid);
268
269 ret = setresuid(200, 100, 100);
270 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
271 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
272
273 ret = setresuid(100, 100, 200);
274 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
275 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
276
277 ret = setresuid(100, 200, 200);
278 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
279 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
280
281 ret = setresuid(-1, 200, 200);
282 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
283 ret = getresuid(reinterpret_cast<uid_t *>(&ruid), reinterpret_cast<uid_t *>(&euid),
284 reinterpret_cast<uid_t *>(&suid));
285 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
286 ICUNIT_ASSERT_EQUAL(ruid, 200, ruid); // 200: expected value of ruid
287 ICUNIT_ASSERT_EQUAL(euid, 200, euid);
288 ICUNIT_ASSERT_EQUAL(suid, 200, suid);
289
290 ret = setresuid(-1, -1, 300); // set saved-set user id to 300
291 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
292 ret = getresuid(reinterpret_cast<uid_t *>(&ruid), reinterpret_cast<uid_t *>(&euid),
293 reinterpret_cast<uid_t *>(&suid));
294 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
295 ICUNIT_ASSERT_EQUAL(ruid, 300, ruid);
296 ICUNIT_ASSERT_EQUAL(euid, 300, euid); // 300: expected value of euid
297 ICUNIT_ASSERT_EQUAL(suid, 300, suid);
298
299 ret = setresuid(-1, 200, 300);
300 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
301 ret = setresuid(-1, -2, 200);
302 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
303 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
304
305 ret = setresuid(-2, 200, 200);
306 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
307 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
308
309 ret = setresuid(200, -2, 200);
310 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
311 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
312
313 ret = setresuid(200, 200, -3);
314 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
315 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
316
317 ret = setresgid(100, 100, 100); // 100: value of rgid, egid and sgid
318 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
319 ret = getresgid(reinterpret_cast<gid_t *>(&rgid), reinterpret_cast<gid_t *>(&egid),
320 reinterpret_cast<gid_t *>(&sgid));
321 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
322 ICUNIT_ASSERT_EQUAL(rgid, 100, rgid);
323 ICUNIT_ASSERT_EQUAL(egid, 100, egid);
324 ICUNIT_ASSERT_EQUAL(sgid, 100, sgid); // 100: expected value of sgid
325
326 ret = setresgid(200, 100, 100);
327 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
328 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
329
330 ret = setresgid(100, 100, 200);
331 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
332 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
333
334 ret = setresgid(100, 200, 200);
335 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
336 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
337
338 ret = setresgid(-2, 100, 200); // set rgid to -2, egid to 100, sgid to 200
339 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
340 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
341 ret = setresgid(100, -2, 200); // set rgid to 100, egid to -2, sgid to 200
342 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
343 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
344 ret = setresgid(100, 100, -2); // set rgid and egid to 100, rgid to -2
345 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
346 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
347 ret = setresgid(100, -1, -2);
348 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
349 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
350 ret = setresgid(-1, 200, 200); // 200: value of egid and sgid
351 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
352 ret = getresgid(reinterpret_cast<gid_t *>(&rgid), reinterpret_cast<gid_t *>(&egid),
353 reinterpret_cast<gid_t *>(&sgid));
354 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
355 ICUNIT_ASSERT_EQUAL(rgid, 200, rgid); // 200: expected value of rgid
356 ICUNIT_ASSERT_EQUAL(egid, 200, egid); // 200: expected value of egid
357 ICUNIT_ASSERT_EQUAL(sgid, 200, sgid); // 200: expected value of sgid
358
359 ret = setresgid(-1, -1, 300); // set sgid to 300
360 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
361 ret = getresgid(reinterpret_cast<gid_t *>(&rgid), reinterpret_cast<gid_t *>(&egid),
362 reinterpret_cast<gid_t *>(&sgid));
363 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
364 ICUNIT_ASSERT_EQUAL(rgid, 300, rgid);
365 ICUNIT_ASSERT_EQUAL(egid, 300, egid);
366 ICUNIT_ASSERT_EQUAL(sgid, 300, sgid);
367
368 ret = setresgid(-1, 200, 300);
369 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
370 ICUNIT_ASSERT_EQUAL(EPERM, errno, errno);
371
372 size = getgroups(0, reinterpret_cast<gid_t *>(getList));
373 size = getgroups(size, reinterpret_cast<gid_t *>(getList));
374 pid_t pid = fork();
375 if (pid == 0) {
376 Child1(getList, size);
377 exit(__LINE__);
378 }
379
380 int status = 0;
381 ret = waitpid(pid, &status, 0);
382 ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT);
383 status = WEXITSTATUS(status);
384 ICUNIT_GOTO_EQUAL(status, 255, status, EXIT);
385
386 ret = setgroups(0, NULL);
387 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
388
389 ret = getgroups(0, reinterpret_cast<gid_t *>(getList));
390 ICUNIT_ASSERT_EQUAL(ret, 1, ret);
391
392 ret = getgroups(1, reinterpret_cast<gid_t *>(getList));
393 ICUNIT_ASSERT_EQUAL(ret, 1, ret);
394 ICUNIT_ASSERT_EQUAL(getList[0], getgid(), getList[0]);
395
396 ret = setreuid(-1, -1);
397 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
398 ret = setregid(-1, -1);
399 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
400 ret = setresuid(-1, -1, -1);
401 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
402 ret = setresuid(-1, -1, -1);
403 ICUNIT_ASSERT_EQUAL(ret, 0, ret);
404 ret = setegid(-1);
405 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
406 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
407 ret = seteuid(-1);
408 ICUNIT_ASSERT_EQUAL(ret, -1, ret);
409 ICUNIT_ASSERT_EQUAL(EINVAL, errno, errno);
410
411 exit(255);
412
413 EXIT:
414 return 1;
415 }
416
TestCase(VOID)417 static int TestCase(VOID)
418 {
419 int ret;
420 int status = 0;
421 pid_t pid = fork();
422 ICUNIT_GOTO_WITHIN_EQUAL(pid, 0, 100000, pid, EXIT); // assume pid is between 0 and 100000
423 if (pid == 0) {
424 ret = Child();
425 exit(__LINE__);
426 }
427
428 ret = waitpid(pid, &status, 0);
429 ICUNIT_GOTO_EQUAL(ret, pid, ret, EXIT);
430 status = WEXITSTATUS(status);
431 ICUNIT_GOTO_EQUAL(status, 255, status, EXIT);
432
433 return 0;
434
435 EXIT:
436 return 1;
437 }
438
ItTestReugid001(void)439 void ItTestReugid001(void)
440 {
441 TEST_ADD_CASE("IT_SEC_UGID_001", TestCase, TEST_POSIX, TEST_SEC, TEST_LEVEL0, TEST_FUNCTION);
442 }
443