• 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(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