1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * SPDX-License-Identifier: GPL-2.0
4  *
5  * Unless required by applicable law or agreed to in writing, software
6  * distributed under the License is distributed on an "AS IS" BASIS,
7  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
8  * See the License for the specific language governing permissions and
9  * limitations under the License.
10  */
11 
12 #include "accesstokenid_test.h"
13 #include <cstdio>
14 #include <cstdlib>
15 #include <fcntl.h>
16 #include <cerrno>
17 #include <unistd.h>
18 #include <sys/types.h>
19 #include <sys/stat.h>
20 #include <sys/mman.h>
21 #include <sys/wait.h>
22 #include <sys/ioctl.h>
23 #include <ctime>
24 #include <climits>
25 #include <pthread.h>
26 #include <sys/syscall.h>
27 #include <grp.h>
28 
29 constexpr unsigned char ACCESS_TOKEN_ID_IOCTL_BASE = 'A';
30 constexpr unsigned int GET_TOKEN_ID = 1;
31 constexpr unsigned int SET_TOKEN_ID = 2;
32 constexpr unsigned int GET_FTOKEN_ID = 3;
33 constexpr unsigned int SET_FTOKEN_ID = 4;
34 constexpr unsigned int ACCESS_TOKENID_MAX_NR = 5;
35 #define	ACCESS_TOKENID_GET_TOKENID \
36     _IOR(ACCESS_TOKEN_ID_IOCTL_BASE, GET_TOKEN_ID, unsigned long long)
37 #define	ACCESS_TOKENID_SET_TOKENID \
38     _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_TOKEN_ID, unsigned long long)
39 #define	ACCESS_TOKENID_GET_FTOKENID \
40     _IOR(ACCESS_TOKEN_ID_IOCTL_BASE, GET_FTOKEN_ID, unsigned long long)
41 #define	ACCESS_TOKENID_SET_FTOKENID \
42     _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, SET_FTOKEN_ID, unsigned long long)
43 #define	ACCESS_TOKENID_ILLEGAL1 \
44     _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, 0, unsigned long long)
45 #define	ACCESS_TOKENID_ILLEGAL2 \
46     _IOW(ACCESS_TOKEN_ID_IOCTL_BASE, ACCESS_TOKENID_MAX_NR, unsigned long long)
47 
48 constexpr unsigned long long INVAL_TOKEN = 0xffffffffffffffff;
49 
50 #define CHILDREN_NUM			    3
51 #define WAIT_FOR_SHELL_OP_TIME		1
52 #define FATHER_WAIT_TIME		    (WAIT_FOR_SHELL_OP_TIME * (CHILDREN_NUM + 1))
53 
54 constexpr unsigned int ACCESS_TOKEN_GRPID = 3020;
55 constexpr unsigned int ACCESS_TOKEN_OTHER_UID = 1234;
56 constexpr unsigned int ACCESS_TOKEN_OTHER_GRPID = 1234;
57 
58 const char DEV_ACCESSTOKENID[] = "/dev/access_token_id";
59 
60 struct Tokeninfo {
61     pid_t               pid;
62     pid_t               tid;
63     unsigned long long  tokenid;
64     unsigned long long  ftokenid;
65 };
66 
67 namespace {
GenRand64(void)68 static unsigned long long GenRand64(void)
69 {
70     struct timespec time = {0, 0};
71     unsigned long long randvalue = 0;
72     int fd;
73 
74     fd = open("/dev/random", O_RDONLY);
75     if (fd > 0) {
76         read(fd, &randvalue, sizeof(unsigned long long));
77     }
78     close(fd);
79 
80     sleep(1);
81     clock_gettime(CLOCK_REALTIME, &time);
82 
83     return randvalue + time.tv_nsec;
84 }
85 
GetTokenid(unsigned long long *token)86 static int GetTokenid(unsigned long long *token)
87 {
88     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
89     if (fd < 0) {
90         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
91         return -1;
92     }
93 
94     int ret = ioctl(fd, ACCESS_TOKENID_GET_TOKENID, token);
95     if (ret) {
96         printf("ioctl ACCESS_TOKENID_GET_TOKENID failed\r\n");
97         close(fd);
98         return -1;
99     }
100 
101     close(fd);
102     return 0;
103 }
104 
SetTokenid(unsigned long long *token)105 static int SetTokenid(unsigned long long *token)
106 {
107     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
108     if (fd < 0) {
109         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
110         return -1;
111     }
112 
113     int ret = ioctl(fd, ACCESS_TOKENID_SET_TOKENID, token);
114     if (ret) {
115         printf("ioctl ACCESS_TOKENID_SET_TOKENID failed\r\n");
116         close(fd);
117         return -1;
118     }
119 
120     close(fd);
121     return 0;
122 }
123 
GetfTokenid(unsigned long long *ftoken)124 static int GetfTokenid(unsigned long long *ftoken)
125 {
126     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
127     if (fd < 0) {
128         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
129         return -1;
130     }
131 
132     int ret = ioctl(fd, ACCESS_TOKENID_GET_FTOKENID, ftoken);
133     if (ret) {
134         printf("ioctl ACCESS_TOKENID_GET_FTOKENID failed\r\n");
135         close(fd);
136         return -1;
137     }
138 
139     close(fd);
140     return 0;
141 }
142 
SetfTokenid(unsigned long long *ftoken)143 static int SetfTokenid(unsigned long long *ftoken)
144 {
145     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
146     if (fd < 0) {
147         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
148         return -1;
149     }
150 
151     int ret = ioctl(fd, ACCESS_TOKENID_SET_FTOKENID, ftoken);
152     if (ret) {
153         printf("ioctl ACCESS_TOKENID_SET_FTOKENID failed\r\n");
154         close(fd);
155         return -1;
156     }
157 
158     close(fd);
159     return 0;
160 }
161 
GetCurToken(unsigned long long *token, unsigned long long *ftoken)162 static void GetCurToken(unsigned long long *token, unsigned long long *ftoken)
163 {
164     GetTokenid(token);
165     GetfTokenid(ftoken);
166 
167     return;
168 }
169 
CheckChildThreadInheritance(void *args)170 static void *CheckChildThreadInheritance(void *args)
171 {
172     struct Tokeninfo *tinfo = static_cast<struct Tokeninfo *>(args);
173 
174     tinfo->pid = getpid();
175     tinfo->tid = gettid();
176     GetTokenid(&(tinfo->tokenid));
177     GetfTokenid(&(tinfo->ftokenid));
178 
179     pthread_exit(nullptr);
180     return nullptr;
181 }
182 
CheckChildThreadSetIndepent(void *args)183 static void *CheckChildThreadSetIndepent(void *args)
184 {
185     struct Tokeninfo *tinfo = static_cast<struct Tokeninfo *>(args);
186     unsigned long long tokenSet = GenRand64();
187     unsigned long long ftokenSet = GenRand64();
188     unsigned long long tokenidGet = INVAL_TOKEN;
189     unsigned long long ftokenidGet = INVAL_TOKEN;
190 
191     tinfo->pid = getpid();
192     tinfo->tid = gettid();
193 
194     GetTokenid(&tokenidGet);
195     GetfTokenid(&ftokenidGet);
196     SetTokenid(&tokenSet);
197     SetfTokenid(&ftokenSet);
198     GetTokenid(&(tinfo->tokenid));
199     GetfTokenid(&(tinfo->ftokenid));
200 
201     /* Indicate that the tokenid setting of each child thread does not met requirements. */
202     if (ftokenidGet == 0 && tinfo->tokenid == tokenSet && tinfo->ftokenid == ftokenSet && tinfo->ftokenid != 0) {
203         tinfo->ftokenid = INVAL_TOKEN;
204     }
205 
206     pthread_exit(nullptr);
207     return nullptr;
208 }
209 }
210 
211 using namespace testing::ext;
212 using namespace std;
213 
SetUp()214 void AccesstokenidTest::SetUp() {}
215 
TearDown()216 void AccesstokenidTest::TearDown() {}
217 
SetUpTestCase()218 void AccesstokenidTest::SetUpTestCase() {}
219 
TearDownTestCase()220 void AccesstokenidTest::TearDownTestCase() {}
221 
222 /**
223  * @tc.name: CheckInitToken
224  * @tc.desc: Test init value of tokenid and ftokenid
225  * @tc.desc: tokenid equals to the father(hdcd) and ftokenid equals to 0
226  * @tc.type: FUNC
227  */
HWTEST_F(AccesstokenidTest, CheckInitToken, Function | MediumTest | Level1)228 HWTEST_F(AccesstokenidTest, CheckInitToken, Function | MediumTest | Level1)
229 {
230     unsigned long long token = INVAL_TOKEN;
231     unsigned long long ftoken = INVAL_TOKEN;
232 
233     GetCurToken(&token, &ftoken);
234 
235     /* /data/service/el0/access_token/nativetoken.json
236        {"processName":"hdcd","APL":3,"version":1,"tokenId":680034571,"tokenAttr":0,"dcaps":[]}
237     */
238     ASSERT_NE(0, token);
239     ASSERT_EQ(0, ftoken);
240 }
241 
242 /**
243  * @tc.name: CheckSetTokenid
244  * @tc.desc: Test setting of tokenid
245  * @tc.desc: tokenid equals to the setting value
246  * @tc.type: FUNC
247  */
HWTEST_F(AccesstokenidTest, CheckSetTokenid, Function | MediumTest | Level1)248 HWTEST_F(AccesstokenidTest, CheckSetTokenid, Function | MediumTest | Level1)
249 {
250     unsigned long long token = INVAL_TOKEN;
251     unsigned long long tokenSet = GenRand64();
252 
253     SetTokenid(&tokenSet);
254     GetTokenid(&token);
255 
256     ASSERT_EQ(tokenSet, token);
257 }
258 
259 /**
260  * @tc.name: CheckSetfTokenid
261  * @tc.desc: Test setting of ftokenid
262  * @tc.desc: ftokenid equals to the setting value
263  * @tc.type: FUNC
264  */
HWTEST_F(AccesstokenidTest, CheckSetfTokenid, Function | MediumTest | Level1)265 HWTEST_F(AccesstokenidTest, CheckSetfTokenid, Function | MediumTest | Level1)
266 {
267     unsigned long long ftoken = INVAL_TOKEN;
268     unsigned long long ftokenSet = GenRand64();
269 
270     SetfTokenid(&ftokenSet);
271     GetfTokenid(&ftoken);
272 
273     ASSERT_EQ(ftokenSet, ftoken);
274 }
275 
276 /**
277  * @tc.name: CheckChildThreadInheritance
278  * @tc.desc: Test each child thread tokenid equals to father process while ftokenid not equals
279  * @tc.desc: The ftokenid of each child thread equals to 0
280  * @tc.type: FUNC
281  */
HWTEST_F(AccesstokenidTest, CheckChildThreadInheritance, Function | MediumTest | Level1)282 HWTEST_F(AccesstokenidTest, CheckChildThreadInheritance, Function | MediumTest | Level1)
283 {
284     pthread_t cid[10];
285 
286     unsigned long long token = INVAL_TOKEN;
287     unsigned long long ftoken = INVAL_TOKEN;
288     unsigned long long tokenSet = GenRand64();
289     unsigned long long ftokenSet = GenRand64();
290 
291     struct Tokeninfo tinfo;
292     tinfo.pid = getpid();
293     tinfo.tid = gettid();
294     tinfo.tokenid = INVAL_TOKEN;
295     tinfo.ftokenid = INVAL_TOKEN;
296 
297     GetTokenid(&token);
298     GetfTokenid(&ftoken);
299 
300     SetTokenid(&tokenSet);
301     SetfTokenid(&ftokenSet);
302 
303     for (int i = 0; i < 10; i++) {
304         if (pthread_create(&cid[i], nullptr, CheckChildThreadInheritance, &tinfo) != 0) {
305             printf("thread %d (ID %ld) pthread_create error\n", i, cid[i]);
306         }
307 
308         if (pthread_join(cid[i], nullptr) != 0) {
309             printf("thread %d (ID %ld) pthread_join error\n", i, cid[i]);
310         }
311 
312         ASSERT_EQ(tinfo.tokenid, tokenSet);
313         ASSERT_NE(tinfo.ftokenid, ftokenSet);
314         ASSERT_EQ(0, tinfo.ftokenid);
315     }
316 }
317 
318 /**
319  * @tc.name: CheckChildThreadSetIndepent
320  * @tc.desc: Test each child thread tokenid and ftokenid is independent
321  * @tc.desc: The tokenid and ftokenid of each child thread not equal to father process
322  * @tc.type: FUNC
323  */
HWTEST_F(AccesstokenidTest, CheckChildThreadSetIndepent, Function | MediumTest | Level1)324 HWTEST_F(AccesstokenidTest, CheckChildThreadSetIndepent, Function | MediumTest | Level1)
325 {
326     pthread_t cid[10];
327 
328     unsigned long long token = INVAL_TOKEN;
329     unsigned long long ftoken = INVAL_TOKEN;
330     unsigned long long tokenSet = GenRand64();
331     unsigned long long ftokenSet = GenRand64();
332 
333     struct Tokeninfo tinfo;
334     tinfo.pid = getpid();
335     tinfo.tid = gettid();
336     tinfo.tokenid = INVAL_TOKEN;
337     tinfo.ftokenid = INVAL_TOKEN;
338 
339     GetTokenid(&token);
340     GetfTokenid(&ftoken);
341 
342     SetTokenid(&tokenSet);
343     SetfTokenid(&ftokenSet);
344 
345     for (int i = 0; i < 10; i++) {
346         if (pthread_create(&cid[i], nullptr, CheckChildThreadSetIndepent, &tinfo) != 0) {
347             printf("thread %d (ID %ld) pthread_create error\n", i, cid[i]);
348         }
349 
350         if (pthread_join(cid[i], nullptr) != 0) {
351             printf("thread %d (ID %ld) pthread_join error\n", i, cid[i]);
352         }
353 
354         ASSERT_NE(tinfo.tokenid, tokenSet);
355         ASSERT_NE(tinfo.ftokenid, ftokenSet);
356         ASSERT_NE(0, tinfo.ftokenid);
357     }
358 }
359 
360 /**
361  * @tc.name: AbnormalGetTokenid
362  * @tc.desc: Test abnormal ioctl cmd of ACCESS_TOKENID_GET_TOKENID
363  * @tc.desc: using nullptr instead of the address of tokenid to ioctl
364  * @tc.type: FUNC
365  */
HWTEST_F(AccesstokenidTest, AbnormalGetTokenid, Function | MediumTest | Level1)366 HWTEST_F(AccesstokenidTest, AbnormalGetTokenid, Function | MediumTest | Level1)
367 {
368     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
369     if (fd < 0) {
370         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
371         return;
372     }
373 
374     int ret = ioctl(fd, ACCESS_TOKENID_GET_TOKENID, nullptr);
375     close(fd);
376 
377     ASSERT_NE(0, ret);
378 }
379 
380 /**
381  * @tc.name: AbnormalSetTokenid
382  * @tc.desc: Test abnormal ioctl cmd of ACCESS_TOKENID_SET_TOKENID
383  * @tc.desc: using nullptr instead of the address of tokenid to ioctl
384  * @tc.type: FUNC
385  */
HWTEST_F(AccesstokenidTest, AbnormalSetTokenid, Function | MediumTest | Level1)386 HWTEST_F(AccesstokenidTest, AbnormalSetTokenid, Function | MediumTest | Level1)
387 {
388     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
389     if (fd < 0) {
390         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
391         return;
392     }
393 
394     int ret = ioctl(fd, ACCESS_TOKENID_SET_TOKENID, nullptr);
395     close(fd);
396 
397     ASSERT_NE(0, ret);
398 }
399 
400 /**
401  * @tc.name: AbnormalGetfTokenid
402  * @tc.desc: Test abnormal ioctl cmd of ACCESS_TOKENID_GET_FTOKENID
403  * @tc.desc: using nullptr instead of the address of ftokenid to ioctl
404  * @tc.type: FUNC
405  */
HWTEST_F(AccesstokenidTest, AbnormalGetfTokenid, Function | MediumTest | Level1)406 HWTEST_F(AccesstokenidTest, AbnormalGetfTokenid, Function | MediumTest | Level1)
407 {
408     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
409     if (fd < 0) {
410         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
411         return;
412     }
413 
414     int ret = ioctl(fd, ACCESS_TOKENID_GET_FTOKENID, nullptr);
415     close(fd);
416 
417     ASSERT_NE(0, ret);
418 }
419 
420 /**
421  * @tc.name: AbnormalSetfTokenid
422  * @tc.desc: Test abnormal ioctl cmd of ACCESS_TOKENID_SET_FTOKENID
423  * @tc.desc: using nullptr instead of the address of ftokenid to ioctl
424  * @tc.type: FUNC
425  */
HWTEST_F(AccesstokenidTest, AbnormalSetfTokenid, Function | MediumTest | Level1)426 HWTEST_F(AccesstokenidTest, AbnormalSetfTokenid, Function | MediumTest | Level1)
427 {
428     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
429     if (fd < 0) {
430         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
431         return;
432     }
433 
434     int ret = ioctl(fd, ACCESS_TOKENID_SET_FTOKENID, nullptr);
435     close(fd);
436 
437     ASSERT_NE(0, ret);
438 }
439 
440 /**
441  * @tc.name: AbnormalIoctlCmd
442  * @tc.desc: Test abnormal ioctl cmd of ACCESS_TOKENID_ILLEGAL1 and ACCESS_TOKENID_ILLEGAL1
443  * @tc.desc: using illegal cmd instead of accesstokenid to ioctl
444  * @tc.type: FUNC
445  */
HWTEST_F(AccesstokenidTest, AbnormalIoctlCmd, Function | MediumTest | Level1)446 HWTEST_F(AccesstokenidTest, AbnormalIoctlCmd, Function | MediumTest | Level1)
447 {
448     unsigned long long token;
449 
450     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
451     if (fd < 0) {
452         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
453         return;
454     }
455 
456     int ret1 = ioctl(fd, ACCESS_TOKENID_ILLEGAL1, &token);
457     int ret2 = ioctl(fd, ACCESS_TOKENID_ILLEGAL2, &token);
458     close(fd);
459 
460     ASSERT_NE(0, ret1);
461     ASSERT_NE(0, ret2);
462 }
463 
464 /**
465  * @tc.name: OtherUidSetTokenid
466  * @tc.desc: Test ACCESS_TOKEN_OTHER_UID can not set tokenid
467  * @tc.desc: tokenid can be only set by uid 3020
468  * @tc.type: FUNC
469  */
HWTEST_F(AccesstokenidTest, OtherUidSetTokenid, Function | MediumTest | Level1)470 HWTEST_F(AccesstokenidTest, OtherUidSetTokenid, Function | MediumTest | Level1)
471 {
472     unsigned long long tokenSet = GenRand64();
473     int ret;
474 
475     ret = setuid(ACCESS_TOKEN_OTHER_UID);
476     if (ret != 0) {
477         printf("setuid error %d \r\n", ret);
478     }
479 
480     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
481     if (fd < 0) {
482         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
483         return;
484     }
485 
486     ret = ioctl(fd, ACCESS_TOKENID_SET_TOKENID, &tokenSet);
487     close(fd);
488 
489     ASSERT_NE(0, ret);
490 }
491 
492 /**
493  * @tc.name: OtherUidGetTokenid
494  * @tc.desc: Test ACCESS_TOKEN_OTHER_UID can get tokenid
495  * @tc.desc: tokenid can get not only by uid 3020
496  * @tc.type: FUNC
497  */
HWTEST_F(AccesstokenidTest, OtherUidGetTokenid, Function | MediumTest | Level1)498 HWTEST_F(AccesstokenidTest, OtherUidGetTokenid, Function | MediumTest | Level1)
499 {
500     unsigned long long token = INVAL_TOKEN;
501     int ret;
502 
503     ret = setuid(ACCESS_TOKEN_OTHER_UID);
504     if (ret != 0) {
505         printf("setuid error %d \r\n", ret);
506     }
507 
508     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
509     if (fd < 0) {
510         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
511         return;
512     }
513 
514     ret = ioctl(fd, ACCESS_TOKENID_GET_TOKENID, &token);
515     close(fd);
516 
517     ASSERT_EQ(0, ret);
518 }
519 
520 /**
521  * @tc.name: WithoutGrpSetfTokenid
522  * @tc.desc: Test ACCESS_TOKEN_OTHER_GRPID can not set ftokenid
523  * @tc.desc: ftokenid can not set by groups without grpid 3020
524  * @tc.type: FUNC
525  */
HWTEST_F(AccesstokenidTest, WithoutGrpSetfTokenid, Function | MediumTest | Level1)526 HWTEST_F(AccesstokenidTest, WithoutGrpSetfTokenid, Function | MediumTest | Level1)
527 {
528     int ret;
529     size_t size = 1;
530     gid_t list[1] = {ACCESS_TOKEN_OTHER_GRPID};
531     unsigned long long ftokenSet = GenRand64();
532 
533     ret = setgroups(size, list);
534     if (ret != 0) {
535         printf("setgroups error %d \r\n", ret);
536     }
537 
538     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
539     if (fd < 0) {
540         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
541         return;
542     }
543 
544     ret = ioctl(fd, ACCESS_TOKENID_SET_FTOKENID, &ftokenSet);
545     close(fd);
546 
547     ASSERT_NE(0, ret);
548 }
549 
550 /**
551  * @tc.name: WithoutGrpGetfTokenid
552  * @tc.desc: Test ACCESS_TOKEN_OTHER_GRPID can not get ftokenid
553  * @tc.desc: ftokenid can not get by groups without grpid 3020
554  * @tc.type: FUNC
555  */
HWTEST_F(AccesstokenidTest, WithoutGrpGetfTokenid, Function | MediumTest | Level1)556 HWTEST_F(AccesstokenidTest, WithoutGrpGetfTokenid, Function | MediumTest | Level1)
557 {
558     int ret;
559     size_t size = 1;
560     gid_t list[1] = {ACCESS_TOKEN_OTHER_GRPID};
561     unsigned long long ftoken = INVAL_TOKEN;
562 
563     ret = setgroups(size, list);
564     if (ret != 0) {
565         printf("setgroups error %d \r\n", ret);
566     }
567 
568     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
569     if (fd < 0) {
570         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
571         return;
572     }
573 
574     ret = ioctl(fd, ACCESS_TOKENID_GET_FTOKENID, &ftoken);
575     close(fd);
576 
577     ASSERT_NE(0, ret);
578 }
579 
580 /**
581  * @tc.name: WithGrpSetfTokenid
582  * @tc.desc: Test ACCESS_TOKEN_OTHER_GRPID and ACCESS_TOKEN_GRPID can set ftokenid
583  * @tc.desc: ftokenid can set by groups with grpid 3020
584  * @tc.type: FUNC
585  */
HWTEST_F(AccesstokenidTest, WithGrpSetfTokenid, Function | MediumTest | Level1)586 HWTEST_F(AccesstokenidTest, WithGrpSetfTokenid, Function | MediumTest | Level1)
587 {
588     int ret;
589     size_t size = 2;
590     gid_t list[2] = {ACCESS_TOKEN_OTHER_GRPID, ACCESS_TOKEN_GRPID};
591     unsigned long long ftokenSet = GenRand64();
592 
593     ret = setgroups(size, list);
594     if (ret != 0) {
595         printf("setgroups error %d \r\n", ret);
596     }
597 
598     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
599     if (fd < 0) {
600         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
601         return;
602     }
603 
604     ret = ioctl(fd, ACCESS_TOKENID_SET_FTOKENID, &ftokenSet);
605     close(fd);
606 
607     ASSERT_EQ(0, ret);
608 }
609 
610 /**
611  * @tc.name: WithGrpGetfTokenid
612  * @tc.desc: Test ACCESS_TOKEN_OTHER_GRPID and ACCESS_TOKEN_GRPID can set ftokenid
613  * @tc.desc: ftokenid can set by groups with grpid 3020
614  * @tc.type: FUNC
615  */
HWTEST_F(AccesstokenidTest, WithGrpGetfTokenid, Function | MediumTest | Level1)616 HWTEST_F(AccesstokenidTest, WithGrpGetfTokenid, Function | MediumTest | Level1)
617 {
618     int ret;
619     size_t size = 2;
620     gid_t list[2] = {ACCESS_TOKEN_OTHER_GRPID, ACCESS_TOKEN_GRPID};
621     unsigned long long ftoken = INVAL_TOKEN;
622 
623     ret = setgroups(size, list);
624     if (ret != 0) {
625         printf("setgroups error %d \r\n", ret);
626     }
627 
628     int fd = open(DEV_ACCESSTOKENID, O_RDWR);
629     if (fd < 0) {
630         printf("open %s failed\r\n", DEV_ACCESSTOKENID);
631         return;
632     }
633 
634     ret = ioctl(fd, ACCESS_TOKENID_GET_FTOKENID, &ftoken);
635     close(fd);
636 
637     ASSERT_EQ(0, ret);
638 }
639 
640