• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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