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