1/*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16#include "UidGidTest.h"
17#include <unistd.h>
18#include <sys/types.h>
19#include "log.h"
20#include "utils.h"
21
22using namespace testing::ext;
23
24/**
25 * @tc.number SUB_KERNEL_DAC_SetGetUID_0100
26 * @tc.name   setuid and getuid basic test
27 * @tc.desc   [C- SOFTWARE -0200]
28 */
29HWTEST_F(UidGidTest, testSetGetuid, Function | MediumTest | Level1)
30{
31    AssertAllUid(SHELL_UID);
32    uid_t uid = getuid();
33    ASSERT_EQ(uid, SHELL_UID);
34
35    uid_t newUid = GetRandom(100);
36    LOG("new uid = %d", newUid);
37    int rt = setuid(newUid);
38    ASSERT_EQ(rt, 0);
39    uid = getuid();
40    ASSERT_EQ(uid, newUid);
41
42    pid_t pid = fork();
43    ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
44    if (pid > 0) { // parent
45        Msleep(20);
46        WaitProcExitedOK(pid);
47    } else { // child
48        uid = getuid();
49        if (uid != newUid) {
50            LOG("child uid check fail, child uid=%d", uid);
51            exit(1);
52        }
53        LOG("child uid check OK");
54        exit(0);
55    }
56    rt = setuid(0);
57    ASSERT_EQ(rt, 0);
58    uid = getuid();
59    ASSERT_EQ(uid, 0);
60}
61/**
62 * @tc.number SUB_KERNEL_DAC_SetGetUID_0200
63 * @tc.name   test setuid fail if input uid is negative
64 * @tc.desc   [C- SOFTWARE -0200]
65 */
66HWTEST_F(UidGidTest, testSetuidFail, Function | MediumTest | Level3)
67{
68    uid_t uid = getuid();
69    ASSERT_EQ(uid, SHELL_UID);
70
71    int newUid = -GetRandID();
72    LOG("new uid = %d", newUid);
73    int rt = setuid(newUid);
74    ASSERT_EQ(rt, -1);
75    ASSERT_EQ(errno, EINVAL);
76
77    uid = getuid();
78    ASSERT_EQ(uid, SHELL_UID);
79}
80
81/**
82 * @tc.number SUB_KERNEL_DAC_SetGetGID_0100
83 * @tc.name   setgid and getgid basic test
84 * @tc.desc   [C- SOFTWARE -0200]
85 */
86HWTEST_F(UidGidTest, testSetGetgid, Function | MediumTest | Level1)
87{
88    AssertAllGid(SHELL_GID);
89    gid_t gid = getgid();
90    ASSERT_EQ(gid, SHELL_GID);
91
92    uid_t newgid = GetRandom(100);
93    LOG("new gid = %d", newgid);
94    int rt = setgid(newgid);
95    ASSERT_EQ(rt, 0);
96    gid = getgid();
97    ASSERT_EQ(gid, newgid);
98
99    pid_t pid = fork();
100    ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
101    if (pid > 0) { // parent
102        Msleep(20);
103        WaitProcExitedOK(pid);
104    } else { // child
105        gid = getgid();
106        if (gid != newgid) {
107            LOG("child gid check fail, child gid=%d", gid);
108            exit(1);
109        }
110        LOG("child guid check OK");
111        exit(0);
112    }
113    rt = setgid(0);
114    ASSERT_EQ(rt, 0);
115    gid = getgid();
116    ASSERT_EQ(gid, 0);
117}
118/**
119 * @tc.number SUB_KERNEL_DAC_SetGetGID_0200
120 * @tc.name   test setgid fail if input gid is negative
121 * @tc.desc   [C- SOFTWARE -0200]
122 */
123HWTEST_F(UidGidTest, testSetgidFail, Function | MediumTest | Level3)
124{
125    gid_t gid = getgid();
126    ASSERT_EQ(gid, SHELL_GID);
127
128    int newgid = -GetRandID();
129    LOG("new gid = %d", newgid);
130    int rt = setgid(newgid);
131    ASSERT_EQ(rt, -1);
132    ASSERT_EQ(errno, EINVAL);
133
134    gid = getgid();
135    ASSERT_EQ(gid, SHELL_GID);
136}
137
138
139/**
140 * @tc.number SUB_KERNEL_DAC_SetGetEUID_0100
141 * @tc.name   seteuid and geteuid basic test
142 * @tc.desc   [C- SOFTWARE -0200]
143 */
144HWTEST_F(UidGidTest, testSetGeteuid, Function | MediumTest | Level1)
145{
146    AssertAllUid(SHELL_UID);
147
148    uid_t newEuid = GetRandID();
149    LOG("new euid = %d", newEuid);
150    int rt = seteuid(newEuid);
151    ASSERT_EQ(rt, 0);
152    uid_t euid = geteuid();
153    ASSERT_EQ(euid, newEuid);
154    AssertAllUid(newEuid);
155
156    pid_t pid = fork();
157    ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
158    if (pid > 0) { // parent
159        Msleep(20);
160        WaitProcExitedOK(pid);
161    } else { // child
162        uid_t uid, euid, suid;
163        getresuid(&uid, &euid, &suid);
164        if (uid != newEuid || euid != newEuid || suid != newEuid) {
165            LOG("child resuid check fail, actual uid=%d,euid=%d,suid=%d,", uid, euid, suid);
166            exit(1);
167        }
168        LOG("child uid check OK");
169        exit(0);
170    }
171    rt = seteuid(SHELL_UID);
172    ASSERT_EQ(rt, 0);
173    euid = geteuid();
174    ASSERT_EQ(euid, SHELL_UID);
175    AssertAllUid(SHELL_UID);
176}
177/**
178 * @tc.number SUB_KERNEL_DAC_SetGetEUID_0200
179 * @tc.name   test seteuid fail if input uid is negative
180 * @tc.desc   [C- SOFTWARE -0200]
181 */
182HWTEST_F(UidGidTest, testSeteuidFail, Function | MediumTest | Level3)
183{
184    uid_t uid = getuid();
185    ASSERT_EQ(uid, SHELL_UID);
186
187    int newEuid = -GetRandID();
188    LOG("new euid = %d", newEuid);
189    int rt = seteuid(newEuid);
190    ASSERT_EQ(rt, -1);
191    ASSERT_EQ(errno, EINVAL);
192
193    uid = getuid();
194    ASSERT_EQ(uid, SHELL_UID);
195    uid_t euid = geteuid();
196    ASSERT_EQ(euid, SHELL_UID);
197}
198
199/**
200 * @tc.number SUB_KERNEL_DAC_SetGetEGID_0100
201 * @tc.name   setegid and getegid basic test
202 * @tc.desc   [C- SOFTWARE -0200]
203 */
204HWTEST_F(UidGidTest, testSetGetegid, Function | MediumTest | Level1)
205{
206    AssertAllGid(SHELL_GID);
207
208    uid_t newEgid = GetRandID();
209    LOG("new egid = %d", newEgid);
210    int rt = setegid(newEgid);
211    ASSERT_EQ(rt, 0);
212    gid_t egid = getegid();
213    ASSERT_EQ(egid, newEgid);
214    AssertAllGid(newEgid);
215
216    pid_t pid = fork();
217    ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
218    if (pid > 0) { // parent
219        Msleep(20);
220        WaitProcExitedOK(pid);
221    } else { // child
222        gid_t gid, egid, sgid;
223        getresgid(&gid, &egid, &sgid);
224        if (gid != newEgid || egid != newEgid || sgid != newEgid) {
225            LOG("child resgid check fail, actual gid=%d,egid=%d,sgid=%d,", gid, egid, sgid);
226            exit(1);
227        }
228        LOG("child gid check OK");
229        exit(0);
230    }
231    rt = setegid(SHELL_GID);
232    ASSERT_EQ(rt, 0);
233    egid = getegid();
234    ASSERT_EQ(egid, SHELL_GID);
235    AssertAllGid(SHELL_GID);
236}
237/**
238 * @tc.number SUB_KERNEL_DAC_SetGetEGID_0200
239 * @tc.name   test setegid fail if input gid is negative
240 * @tc.desc   [C- SOFTWARE -0200]
241 */
242HWTEST_F(UidGidTest, testSetegidFail, Function | MediumTest | Level3)
243{
244    gid_t gid = getgid();
245    ASSERT_EQ(gid, SHELL_GID);
246
247    int newEgid = -GetRandID();
248    LOG("new egid = %d", newEgid);
249    int rt = setegid(newEgid);
250    ASSERT_EQ(rt, -1);
251    ASSERT_EQ(errno, EINVAL);
252
253    gid = getgid();
254    ASSERT_EQ(gid, SHELL_GID);
255    gid_t egid = getegid();
256    ASSERT_EQ(egid, SHELL_GID);
257}
258
259
260/**
261 * @tc.number SUB_KERNEL_DAC_SetREUID_0100
262 * @tc.name   setreuid basic test
263 * @tc.desc   [C- SOFTWARE -0200]
264 */
265HWTEST_F(UidGidTest, testSetreuid, Function | MediumTest | Level1)
266{
267    AssertAllUid(SHELL_UID);
268
269    int newUid = GetRandID();
270    LOG("new uid1 = %d", newUid);
271    int rt = setreuid(newUid, newUid);
272    ASSERT_EQ(rt, 0);
273    AssertAllUid(newUid);
274
275    newUid = GetRandID();
276    LOG("new uid2 = %d", newUid);
277    rt = setreuid(newUid, -1);
278    ASSERT_EQ(rt, 0);
279    AssertAllUid(newUid);
280
281    newUid = GetRandID();
282    LOG("new uid3 = %d", newUid);
283    rt = setreuid(-1, newUid);
284    ASSERT_EQ(rt, 0);
285    AssertAllUid(newUid);
286
287    LOG("use all -1");
288    rt = setreuid(-1, -1);
289    ASSERT_EQ(rt, 0);
290    AssertAllUid(newUid);
291
292    LOG("restore to 0");
293    rt = setreuid(SHELL_UID, SHELL_UID);
294    ASSERT_EQ(rt, 0);
295    AssertAllUid(SHELL_UID);
296}
297/**
298 * @tc.number SUB_KERNEL_DAC_SetREUID_0200
299 * @tc.name   test setreuid fail if input uid is negative, or ruid and euid is not equal
300 * @tc.desc   [C- SOFTWARE -0200]
301 */
302HWTEST_F(UidGidTest, testSetreuidFail, Function | MediumTest | Level2)
303{
304    AssertAllUid(SHELL_UID);
305
306    int newUid = GetRandID();
307    LOG("new uid = %d", -newUid);
308    int rt = setreuid(-newUid, -newUid);
309    ASSERT_EQ(rt, -1);
310    ASSERT_EQ(errno, EINVAL);
311
312    rt = setreuid(-newUid, newUid);
313    ASSERT_EQ(rt, -1);
314    ASSERT_EQ(errno, EINVAL);
315
316    rt = setreuid(-newUid, -1);
317    ASSERT_EQ(rt, -1);
318    ASSERT_EQ(errno, EINVAL);
319
320    int newUid2 = GetRandID();
321    LOG("new uid2 = %d", -newUid2);
322    rt = setreuid(newUid, -newUid2);
323    ASSERT_EQ(rt, -1);
324    ASSERT_EQ(errno, EINVAL);
325    rt = setreuid(newUid2, -newUid);
326    ASSERT_EQ(rt, -1);
327    ASSERT_EQ(errno, EINVAL);
328
329    AssertAllUid(SHELL_UID);
330
331    LOG("check uids of setreuid should equal");
332    rt = setreuid(newUid, newUid2);
333    ASSERT_EQ(rt, -1);
334    ASSERT_EQ(errno, EPERM);
335
336    AssertAllUid(SHELL_UID);
337}
338
339/**
340 * @tc.number SUB_KERNEL_DAC_SetREGID_0100
341 * @tc.name   setregid basic test
342 * @tc.desc   [C- SOFTWARE -0200]
343 */
344HWTEST_F(UidGidTest, testSetregid, Function | MediumTest | Level1)
345{
346    AssertAllGid(SHELL_GID);
347
348    int newGid = GetRandID();
349    LOG("new gid1 = %d", newGid);
350    int rt = setregid(newGid, newGid);
351    ASSERT_EQ(rt, 0);
352    AssertAllGid(newGid);
353
354    newGid = GetRandID();
355    LOG("new gid2 = %d", newGid);
356    rt = setregid(newGid, -1);
357    ASSERT_EQ(rt, 0);
358    AssertAllGid(newGid);
359
360    newGid = GetRandID();
361    LOG("new gid3 = %d", newGid);
362    rt = setregid(-1, newGid);
363    ASSERT_EQ(rt, 0);
364    AssertAllGid(newGid);
365
366    LOG("use all -1");
367    rt = setregid(-1, -1);
368    EXPECT_EQ(rt, 0);
369    AssertAllGid(newGid);
370
371    LOG("restore to 0");
372    rt = setregid(SHELL_GID, SHELL_GID);
373    ASSERT_EQ(rt, 0);
374    AssertAllGid(SHELL_GID);
375}
376/**
377 * @tc.number SUB_KERNEL_DAC_SetREGID_0200
378 * @tc.name   test setregid fail if input gid is negative, or rgid and egid is not equal
379 * @tc.desc   [C- SOFTWARE -0200]
380 */
381HWTEST_F(UidGidTest, testSetregidFail, Function | MediumTest | Level2)
382{
383    AssertAllGid(SHELL_GID);
384
385    int newGid = GetRandID();
386    LOG("new gid = %d", -newGid);
387    int rt = setregid(-newGid, -newGid);
388    ASSERT_EQ(rt, -1);
389    ASSERT_EQ(errno, EINVAL);
390
391    rt = setregid(-newGid, newGid);
392    ASSERT_EQ(rt, -1);
393    ASSERT_EQ(errno, EINVAL);
394
395    rt = setregid(-newGid, -1);
396    ASSERT_EQ(rt, -1);
397    ASSERT_EQ(errno, EINVAL);
398
399    int newGid2 = GetRandID();
400    LOG("new gid2 = %d", -newGid2);
401    rt = setregid(newGid, -newGid2);
402    ASSERT_EQ(rt, -1);
403    ASSERT_EQ(errno, EINVAL);
404    rt = setregid(newGid2, -newGid);
405    ASSERT_EQ(rt, -1);
406    ASSERT_EQ(errno, EINVAL);
407
408    AssertAllGid(SHELL_GID);
409
410    LOG("check gids of setregid should equal");
411    rt = setregid(newGid, newGid2);
412    ASSERT_EQ(rt, -1);
413    ASSERT_EQ(errno, EPERM);
414
415    AssertAllGid(SHELL_GID);
416}
417
418// ================================== res ===========================================
419/**
420 * @tc.number SUB_KERNEL_DAC_SetGetRESUID_0100
421 * @tc.name   setresuid and getresuid basic test
422 * @tc.desc   [C- SOFTWARE -0200]
423 */
424HWTEST_F(UidGidTest, testSetGetresuid, Function | MediumTest | Level1)
425{
426    AssertAllUid(SHELL_UID);
427
428    int newUid = GetRandID();
429    LOG("new uid1 = %d", newUid);
430    int rt = setresuid(newUid, newUid, newUid);
431    ASSERT_EQ(rt, 0);
432    uid_t uid = getuid();
433    ASSERT_EQ(uid, newUid);
434    AssertAllUid(newUid);
435
436    newUid = GetRandID();
437    LOG("new uid2 = %d", newUid);
438    rt = setresuid(newUid, -1, -1);
439    ASSERT_EQ(rt, 0);
440    AssertAllUid(newUid);
441
442    newUid = GetRandID();
443    LOG("new uid3 = %d", newUid);
444    rt = setresuid(-1, newUid, -1);
445    ASSERT_EQ(rt, 0);
446    AssertAllUid(newUid);
447
448    newUid = GetRandID();
449    LOG("new uid4 = %d", newUid);
450    rt = setresuid(-1, -1, newUid);
451    ASSERT_EQ(rt, 0);
452    AssertAllUid(newUid);
453
454    newUid = GetRandID();
455    LOG("new uid5 = %d", newUid);
456    rt = setresuid(-1, newUid, newUid);
457    ASSERT_EQ(rt, 0);
458    AssertAllUid(newUid);
459
460    newUid = GetRandID();
461    LOG("new uid6 = %d", newUid);
462    rt = setresuid(newUid, -1, newUid);
463    ASSERT_EQ(rt, 0);
464    AssertAllUid(newUid);
465
466    newUid = GetRandID();
467    LOG("new uid7 = %d", newUid);
468    rt = setresuid(newUid, newUid, -1);
469    ASSERT_EQ(rt, 0);
470    AssertAllUid(newUid);
471
472    LOG("use all -1");
473    rt = setresuid(-1, -1, -1);
474    ASSERT_EQ(rt, 0);
475    AssertAllUid(newUid);
476
477    LOG("restore to %d", SHELL_UID);
478    rt = setresuid(SHELL_UID, SHELL_UID, SHELL_UID);
479    ASSERT_EQ(rt, 0);
480    AssertAllUid(SHELL_UID);
481}
482/**
483 * @tc.number SUB_KERNEL_DAC_SetGetRESUID_0200
484 * @tc.name   test setresuid fail if input uid is negative, or ruid,euid,suid is not equal to each other.
485 * @tc.desc   [C- SOFTWARE -0200]
486 */
487HWTEST_F(UidGidTest, testSetresuidFail, Function | MediumTest | Level2)
488{
489    AssertAllUid(SHELL_UID);
490
491    int newUid = GetRandID();
492    int newUid2 = GetRandID();
493    LOG("new uid = %d, new uid2 = %d", newUid, newUid2);
494    int rt = setresuid(-newUid, newUid2, newUid2);
495    ASSERT_EQ(rt, -1);
496    ASSERT_EQ(errno, EINVAL);
497    rt = setresuid(newUid2, -newUid, newUid2);
498    ASSERT_EQ(rt, -1);
499    ASSERT_EQ(errno, EINVAL);
500    rt = setresuid(newUid2, -1, -newUid);
501    ASSERT_EQ(rt, -1);
502    ASSERT_EQ(errno, EINVAL);
503    rt = setresuid(-1, -1, -newUid);
504    ASSERT_EQ(rt, -1);
505    ASSERT_EQ(errno, EINVAL);
506
507    AssertAllUid(SHELL_UID);
508
509    LOG("check uids of setresuid should all equal to each other");
510    rt = setresuid(newUid, newUid2, newUid2);
511    ASSERT_EQ(rt, -1);
512    ASSERT_EQ(errno, EPERM);
513    rt = setresuid(newUid2, newUid, newUid2);
514    ASSERT_EQ(rt, -1);
515    ASSERT_EQ(errno, EPERM);
516    rt = setresuid(newUid2, -1, newUid);
517    ASSERT_EQ(rt, -1);
518    ASSERT_EQ(errno, EPERM);
519    rt = setresuid(-1, newUid, newUid2);
520    ASSERT_EQ(rt, -1);
521    ASSERT_EQ(errno, EPERM);
522
523    AssertAllUid(SHELL_UID);
524}
525
526/**
527 * @tc.number SUB_KERNEL_DAC_SetGetRESGID_0100
528 * @tc.name   setresgid and getresgid basic test
529 * @tc.desc   [C- SOFTWARE -0200]
530 */
531HWTEST_F(UidGidTest, testSetGetresgid, Function | MediumTest | Level1)
532{
533    AssertAllGid(SHELL_GID);
534
535    int newGid = GetRandID();
536    LOG("new gid1 = %d", newGid);
537    int rt = setresgid(newGid, newGid, newGid);
538    ASSERT_EQ(rt, 0);
539    gid_t gid = getgid();
540    ASSERT_EQ(gid, newGid);
541    AssertAllGid(newGid);
542
543    newGid = GetRandID();
544    LOG("new gid2 = %d", newGid);
545    rt = setresgid(newGid, -1, -1);
546    ASSERT_EQ(rt, 0);
547    AssertAllGid(newGid);
548
549    newGid = GetRandID();
550    LOG("new gid3 = %d", newGid);
551    rt = setresgid(-1, newGid, -1);
552    ASSERT_EQ(rt, 0);
553    AssertAllGid(newGid);
554
555    newGid = GetRandID();
556    LOG("new gid4 = %d", newGid);
557    rt = setresgid(-1, -1, newGid);
558    ASSERT_EQ(rt, 0);
559    AssertAllGid(newGid);
560
561    newGid = GetRandID();
562    LOG("new gid5 = %d", newGid);
563    rt = setresgid(-1, newGid, newGid);
564    ASSERT_EQ(rt, 0);
565    AssertAllGid(newGid);
566
567    newGid = GetRandID();
568    LOG("new gid6 = %d", newGid);
569    rt = setresgid(newGid, -1, newGid);
570    ASSERT_EQ(rt, 0);
571    AssertAllGid(newGid);
572
573    newGid = GetRandID();
574    LOG("new gid7 = %d", newGid);
575    rt = setresgid(newGid, newGid, -1);
576    ASSERT_EQ(rt, 0);
577    AssertAllGid(newGid);
578
579    LOG("use all -1");
580    rt = setresgid(-1, -1, -1);
581    ASSERT_EQ(rt, 0);
582    AssertAllGid(newGid);
583
584    LOG("restore to %d", SHELL_GID);
585    rt = setresgid(SHELL_GID, SHELL_GID, SHELL_GID);
586    ASSERT_EQ(rt, 0);
587    AssertAllGid(SHELL_GID);
588}
589/**
590 * @tc.number SUB_KERNEL_DAC_SetGetRESGID_0200
591 * @tc.name   test setresgid fail if input ids is negative, or rgid,egid,sgid is not equal to each other.
592 * @tc.desc   [C- SOFTWARE -0200]
593 */
594HWTEST_F(UidGidTest, testSetresgidFail, Function | MediumTest | Level2)
595{
596    AssertAllGid(SHELL_GID);
597
598    int newGid = GetRandID();
599    int newGid2 = GetRandID();
600    LOG("new gid = %d, new gid2 = %d", newGid, newGid2);
601    int rt = setresgid(-newGid, newGid2, newGid2);
602    ASSERT_EQ(rt, -1);
603    ASSERT_EQ(errno, EINVAL);
604    rt = setresgid(newGid2, -newGid, newGid2);
605    ASSERT_EQ(rt, -1);
606    ASSERT_EQ(errno, EINVAL);
607    rt = setresgid(newGid2, -1, -newGid);
608    ASSERT_EQ(rt, -1);
609    ASSERT_EQ(errno, EINVAL);
610    rt = setresgid(-1, -1, -newGid);
611    ASSERT_EQ(rt, -1);
612    ASSERT_EQ(errno, EINVAL);
613
614    AssertAllGid(SHELL_GID);
615
616    LOG("check gids of setresgid should all equal to each other");
617    rt = setresgid(newGid, newGid2, newGid2);
618    ASSERT_EQ(rt, -1);
619    ASSERT_EQ(errno, EPERM);
620    rt = setresgid(newGid2, newGid, newGid2);
621    ASSERT_EQ(rt, -1);
622    ASSERT_EQ(errno, EPERM);
623    rt = setresgid(newGid2, -1, newGid);
624    ASSERT_EQ(rt, -1);
625    ASSERT_EQ(errno, EPERM);
626    rt = setresgid(-1, newGid, newGid2);
627    ASSERT_EQ(rt, -1);
628    ASSERT_EQ(errno, EPERM);
629
630    AssertAllGid(SHELL_GID);
631}
632
633/**
634 * @tc.number SUB_KERNEL_DAC_GetGroups_0100
635 * @tc.name   getgroups basic test
636 * @tc.desc   [C- SOFTWARE -0200]
637 */
638HWTEST_F(UidGidTest, testGetgroups, Function | MediumTest | Level1)
639{
640    const int testSize = 10;
641    gid_t gidList[testSize] = {0};
642    int n = getgroups(0, gidList);
643    ASSERT_EQ(n, 1);
644    int rt = getgroups(n, gidList);
645    ASSERT_EQ(gidList[0], SHELL_GID);
646    ASSERT_EQ(rt, n);
647    n = getgroups(testSize, gidList);
648    ASSERT_EQ(n, 1);
649    ASSERT_EQ(gidList[0], SHELL_GID);
650
651}
652
653/**
654 * @tc.number SUB_KERNEL_DAC_SetGroups_0100
655 * @tc.name   setgroups function test. also test invalid size of getroups, and clear groups function.
656 * @tc.desc   [C- SOFTWARE -0200]
657 */
658HWTEST_F(UidGidTest, testSetgroups1, Function | MediumTest | Level1)
659{
660    int groupSize = GetRandom(MAX_PROCESS_GROUPS - 3) + 3;
661    gid_t *gidListIn  = (gid_t*)malloc(groupSize * sizeof(gid_t));
662    if (!gidListIn) {
663        LOG("gidListIn malloc fail!");
664        FAIL();
665    }
666    gid_t *gidListOut = (gid_t*)malloc(groupSize * sizeof(gid_t));
667    if (!gidListOut) {
668        LOG("gidListOut malloc fail!");
669        free(gidListIn);
670        FAIL();
671    }
672    gidListIn[0]  = SHELL_GID;
673    for (int i=1; i<groupSize; i++) {
674        gidListIn[i]  = GetRandID();
675        gidListOut[i] = 0;
676    }
677
678    int rt = setgroups(groupSize, gidListIn);
679    EXPECT_EQ(rt, 0);
680
681    int n = getgroups(1, gidListOut);
682    EXPECT_EQ(n, -1) << "input size less than the number of group IDs should fail";
683    EXPECT_EQ(errno, EINVAL);
684
685    n = getgroups(groupSize, gidListOut);
686    EXPECT_EQ(n, groupSize);
687    for (int i=0; i<groupSize; i++) {
688        EXPECT_EQ(gidListIn[i], gidListOut[i]) << " groups not equal, i=" << i << std::endl;
689    }
690
691    LOG("clear groups");
692    rt = setgroups(0, NULL);
693    EXPECT_EQ(rt, 0);
694    n = getgroups(2, gidListOut);
695    EXPECT_EQ(n, 1);
696    EXPECT_EQ(gidListOut[0], SHELL_GID);
697    free(gidListIn);
698    free(gidListOut);
699}
700
701/**
702 * @tc.number SUB_KERNEL_DAC_SetGroups_0200
703 * @tc.name   setgroups function test: gid not in groups will automaticlly add by kernel
704 * @tc.desc   [C- SOFTWARE -0200]
705 */
706HWTEST_F(UidGidTest, testSetgroups2, Function | MediumTest | Level1)
707{
708    gid_t gidListIn[2] = {GetRandID(), GetRandID()};
709    gid_t gidListOut[4] = {0};
710
711    LOG("Init: make sure groups not changed by other test.");
712    int n = getgroups(0, gidListOut);
713    EXPECT_EQ(n, 1);
714    int rt = getgroups(n, gidListOut);
715    EXPECT_EQ(gidListOut[0], SHELL_GID);
716    EXPECT_EQ(rt, n);
717
718    LOG("add 2 groups");
719    rt = setgroups(2, gidListIn);
720    EXPECT_EQ(rt, 0);
721    n = getgroups(4, gidListOut);
722    EXPECT_EQ(n, 3);
723    EXPECT_EQ(gidListOut[0], gidListIn[0]);
724    EXPECT_EQ(gidListOut[1], gidListIn[1]);
725    EXPECT_EQ(gidListOut[2], SHELL_GID);
726
727    LOG("clear groups");
728    rt = setgroups(0, NULL);
729    EXPECT_EQ(rt, 0);
730    n = getgroups(0, gidListOut);
731    EXPECT_EQ(n, 1);
732    rt = getgroups(n, gidListOut);
733    EXPECT_EQ(rt, n);
734    EXPECT_EQ(gidListOut[0], SHELL_GID);
735}
736
737/**
738 * @tc.number SUB_KERNEL_DAC_SetGroups_0300
739 * @tc.name   setgroups function test: input size is grater than 'MAX_PROCESS_GROUPS'
740 * @tc.desc   [C- SOFTWARE -0200]
741 */
742HWTEST_F(UidGidTest, testSetgroupsFail, Function | MediumTest | Level3)
743{
744    LOG("add 2 groups");
745    gid_t gidListIn[2] = {GetRandID(), GetRandID()};
746    gid_t gidListOut[4] = {0};
747
748    int rt = setgroups(2, gidListIn);
749    EXPECT_EQ(rt, 0);
750
751    LOG("setgroups fail");
752    rt = setgroups(MAX_PROCESS_GROUPS+1, gidListIn);
753    EXPECT_EQ(rt, -1);
754    EXPECT_EQ(errno, EINVAL);
755
756    LOG("check groups not changed");
757    int n = getgroups(4, gidListOut);
758    EXPECT_EQ(n, 3);
759    EXPECT_EQ(gidListOut[0], gidListIn[0]);
760    EXPECT_EQ(gidListOut[1], gidListIn[1]);
761    EXPECT_EQ(gidListOut[2], SHELL_GID);
762
763    LOG("clear groups");
764    rt = setgroups(0, NULL);
765    EXPECT_EQ(rt, 0);
766    n = getgroups(2, gidListOut);
767    EXPECT_EQ(n, 1);
768    EXPECT_EQ(gidListOut[0], SHELL_GID);
769}
770