1 /*
2 * Copyright (c) 2022-2023 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 "tokensetproc_kit_test.h"
17 #include <ctime>
18 #include "token_setproc.h"
19
20 using namespace testing::ext;
21 using namespace OHOS::Security;
22 using namespace OHOS::Security::AccessToken;
23
24 static const uint32_t ACCESS_TOKEN_UID = 3020;
25 static const uint32_t MAX_PROCESS_SIZE = 500; // same as kernel size
26 static const uint32_t MAX_PERM_NUM = 2048; // 64 * 32
27 static const uint32_t INVALID_OP_CODE = 65532;
28 static uint32_t g_tokeId = 5000;
29 static const std::vector<uint32_t> g_opCodeList = {0, 1, 2, 3, 4, 5, 63, 128};
30 static const std::vector<bool> g_statusList = {true, true, false, false, false, false, true, false};
31 static uint32_t g_selfUid;
32 static const int32_t CYCLE_TIMES = 1000;
33
SetUpTestCase()34 void TokensetprocKitTest::SetUpTestCase()
35 {
36 g_selfUid = getuid();
37 }
38
TearDownTestCase()39 void TokensetprocKitTest::TearDownTestCase()
40 {}
41
SetUp()42 void TokensetprocKitTest::SetUp()
43 {}
44
TearDown()45 void TokensetprocKitTest::TearDown()
46 {
47 RemovePermissionFromKernel(g_tokeId);
48 setuid(g_selfUid);
49 }
50
51 /**
52 * @tc.name: AddPermissionToKernel001
53 * @tc.desc: cannot AddPermissionToKernel with no permission.
54 * @tc.type: FUNC
55 * @tc.require:
56 */
57 HWTEST_F(TokensetprocKitTest, AddPermissionToKernel001, TestSize.Level0)
58 {
59 ASSERT_EQ(EPERM, AddPermissionToKernel(g_tokeId, g_opCodeList, g_statusList));
60 }
61
62 /**
63 * @tc.name: AddPermissionToKernel002
64 * @tc.desc: AddPermissionToKernel with differet size parameter.
65 * @tc.type: FUNC
66 * @tc.require:
67 */
68 HWTEST_F(TokensetprocKitTest, AddPermissionToKernel002, TestSize.Level0)
69 {
70 setuid(ACCESS_TOKEN_UID);
71 std::vector<uint32_t> opcodeList = {0, 1, 2};
72 std::vector<bool> statusList = {0, 0};
73 ASSERT_EQ(ACCESS_TOKEN_PARAM_INVALID, AddPermissionToKernel(g_tokeId, opcodeList, statusList));
74 ASSERT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
75 setuid(g_selfUid);
76 }
77
78 /**
79 * @tc.name: AddPermissionToKernel003
80 * @tc.desc: AddPermissionToKernel with size is 0.
81 * @tc.type: FUNC
82 * @tc.require:
83 */
84 HWTEST_F(TokensetprocKitTest, AddPermissionToKernel003, TestSize.Level0)
85 {
86 setuid(ACCESS_TOKEN_UID);
87 std::vector<uint32_t> opcodeList;
88 std::vector<bool> statusList;
89 ASSERT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, opcodeList, statusList));
90 ASSERT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
91 setuid(g_selfUid);
92 }
93
94 /**
95 * @tc.name: AddPermissionToKernel004
96 * @tc.desc: AddPermissionToKernel with having permission.
97 * @tc.type: FUNC
98 * @tc.require:
99 */
100 HWTEST_F(TokensetprocKitTest, AddPermissionToKernel004, TestSize.Level0)
101 {
102 setuid(ACCESS_TOKEN_UID);
103 ASSERT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, g_opCodeList, g_statusList));
104 ASSERT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
105 setuid(g_selfUid);
106 }
107
108 /**
109 * @tc.name: AddPermissionToKernel005
110 * @tc.desc: update less permission with same token.
111 * @tc.type: FUNC
112 * @tc.require:
113 */
114 HWTEST_F(TokensetprocKitTest, AddPermissionToKernel005, TestSize.Level0)
115 {
116 setuid(ACCESS_TOKEN_UID);
117 std::vector<uint32_t> opCodeList1 = {123, 124};
118 std::vector<bool> statusList1 = {false, false}; // not granted
119 std::vector<uint32_t> opCodeList2 = {123};
120 std::vector<bool> statusList2 = {true}; // granted
121
122 EXPECT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, opCodeList1, statusList1));
123 bool isGranted = false;
124 EXPECT_EQ(ACCESS_TOKEN_OK, GetPermissionFromKernel(g_tokeId, opCodeList1[0], isGranted));
125 EXPECT_EQ(false, isGranted);
126
127 EXPECT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, opCodeList2, statusList2));
128
129 EXPECT_EQ(ACCESS_TOKEN_OK, GetPermissionFromKernel(g_tokeId, opCodeList2[0], isGranted));
130 EXPECT_EQ(true, isGranted);
131 EXPECT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
132
133 setuid(g_selfUid);
134 }
135
136 /**
137 * @tc.name: AddPermissionToKernel006
138 * @tc.desc: update more permissiion with same token.
139 * @tc.type: FUNC
140 * @tc.require:
141 */
142 HWTEST_F(TokensetprocKitTest, AddPermissionToKernel006, TestSize.Level0)
143 {
144 setuid(ACCESS_TOKEN_UID);
145 std::vector<uint32_t> opCodeList1 = {123};
146 std::vector<bool> statusList1 = {true}; // granted
147 std::vector<uint32_t> opCodeList2 = {123, 124};
148 std::vector<bool> statusList2 = {false, false}; // not granted
149
150 EXPECT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, opCodeList1, statusList1));
151 bool isGranted = false;
152 EXPECT_EQ(ACCESS_TOKEN_OK, GetPermissionFromKernel(g_tokeId, opCodeList1[0], isGranted));
153 EXPECT_EQ(true, isGranted);
154
155 EXPECT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, opCodeList2, statusList2));
156 EXPECT_EQ(ACCESS_TOKEN_OK, GetPermissionFromKernel(g_tokeId, opCodeList2[0], isGranted));
157 EXPECT_EQ(false, isGranted);
158
159 EXPECT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
160
161 setuid(g_selfUid);
162 }
163
164 /**
165 * @tc.name: AddPermissionToKernel007
166 * @tc.desc: AddPermissionToKernel with different token.
167 * @tc.type: FUNC
168 * @tc.require:
169 */
170 HWTEST_F(TokensetprocKitTest, AddPermissionToKernel007, TestSize.Level0)
171 {
172 setuid(ACCESS_TOKEN_UID);
173 uint32_t token1 = 111;
174 uint32_t token2 = 222;
175 ASSERT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(token1, g_opCodeList, g_statusList));
176 EXPECT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(token2, g_opCodeList, g_statusList));
177 EXPECT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(token1));
178 EXPECT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(token2));
179 setuid(g_selfUid);
180 }
181
182 /**
183 * @tc.name: AddPermissionToKernel008
184 * @tc.desc: AddPermissionToKernel with oversize.
185 * @tc.type: FUNC
186 * @tc.require:
187 */
188 HWTEST_F(TokensetprocKitTest, AddPermissionToKernel008, TestSize.Level0)
189 {
190 setuid(ACCESS_TOKEN_UID);
191 std::vector<uint32_t> tokenList;
192 for (uint32_t i = 0; i < MAX_PROCESS_SIZE + 1; i++) {
193 int32_t ret = AddPermissionToKernel(i, g_opCodeList, g_statusList);
194 if (ret != ACCESS_TOKEN_OK) {
195 EXPECT_EQ(ret, EDQUOT);
196 break;
197 } else {
198 tokenList.emplace_back(i);
199 }
200 }
201
202 for (uint32_t i = 0; i < tokenList.size(); i++) {
203 RemovePermissionFromKernel(tokenList[i]);
204 }
205 setuid(g_selfUid);
206 }
207
208
209 /**
210 * @tc.name: AddPermissionToKernel009
211 * @tc.desc: AddPermissionToKernel with update permission.
212 * @tc.type: FUNC
213 * @tc.require:
214 */
215 HWTEST_F(TokensetprocKitTest, AddPermissionToKernel009, TestSize.Level0)
216 {
217 setuid(ACCESS_TOKEN_UID);
218 ASSERT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, g_opCodeList, g_statusList));
219
220 EXPECT_EQ(ACCESS_TOKEN_OK, SetPermissionToKernel(g_tokeId, g_opCodeList[0], true));
221 bool isGranted = false;
222 EXPECT_EQ(ACCESS_TOKEN_OK, GetPermissionFromKernel(g_tokeId, g_opCodeList[0], isGranted));
223 EXPECT_EQ(true, isGranted);
224
225 std::vector<uint32_t> opCodeList;
226 std::vector<bool> statusList;
227 // update with less permission(size is 0)
228 EXPECT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, opCodeList, statusList));
229 EXPECT_EQ(ENODATA, GetPermissionFromKernel(g_tokeId, g_opCodeList[0], isGranted));
230 EXPECT_EQ(false, isGranted);
231
232 // update with more permission
233 EXPECT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, g_opCodeList, g_statusList));
234 EXPECT_EQ(ACCESS_TOKEN_OK, GetPermissionFromKernel(g_tokeId, g_opCodeList[0], isGranted));
235 EXPECT_EQ(g_statusList[0], isGranted);
236
237 EXPECT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
238 setuid(g_selfUid);
239 }
240
241 /**
242 * @tc.name: RemovePermissionFromKernel001
243 * @tc.desc: cannot RemovePermissionFromKernel with no permission.
244 * @tc.type: FUNC
245 * @tc.require:
246 */
247 HWTEST_F(TokensetprocKitTest, RemovePermissionFromKernel001, TestSize.Level0)
248 {
249 ASSERT_EQ(EPERM, RemovePermissionFromKernel(g_tokeId));
250 }
251
252 /**
253 * @tc.name: RemovePermissionFromKernel002
254 * @tc.desc: RemovePermissionFromKernel with same token.
255 * @tc.type: FUNC
256 * @tc.require:
257 */
258 HWTEST_F(TokensetprocKitTest, RemovePermissionFromKernel002, TestSize.Level0)
259 {
260 setuid(ACCESS_TOKEN_UID);
261 ASSERT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, g_opCodeList, g_statusList));
262 EXPECT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
263 ASSERT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
264 setuid(g_selfUid);
265 }
266
267 /**
268 * @tc.name: SetPermissionToKernel001
269 * @tc.desc: cannot SetPermissionToKernel with no permission.
270 * @tc.type: FUNC
271 * @tc.require: issueI8HMUH
272 */
273 HWTEST_F(TokensetprocKitTest, SetPermissionToKernel001, TestSize.Level0)
274 {
275 ASSERT_EQ(EPERM, SetPermissionToKernel(g_tokeId, 1, true));
276 }
277
278 /**
279 * @tc.name: SetPermissionToKernel002
280 * @tc.desc: cannot SetPermissionToKernel with noexst token.
281 * @tc.type: FUNC
282 * @tc.require: issueI8HMUH
283 */
284 HWTEST_F(TokensetprocKitTest, SetPermissionToKernel002, TestSize.Level0)
285 {
286 setuid(ACCESS_TOKEN_UID);
287 ASSERT_EQ(ENODATA, SetPermissionToKernel(g_tokeId, g_opCodeList[0], true));
288 bool isGranted = false;
289 ASSERT_EQ(ENODATA, GetPermissionFromKernel(g_tokeId, g_opCodeList[0], isGranted));
290 ASSERT_EQ(false, isGranted);
291 }
292
293 /**
294 * @tc.name: SetPermissionToKernel003
295 * @tc.desc: SetPermissionToKernel after remove token from kernel.
296 * @tc.type: FUNC
297 * @tc.require: issueI8HMUH
298 */
299 HWTEST_F(TokensetprocKitTest, SetPermissionToKernel003, TestSize.Level0)
300 {
301 setuid(ACCESS_TOKEN_UID);
302 ASSERT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, g_opCodeList, g_statusList));
303 ASSERT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
304 ASSERT_EQ(ENODATA, SetPermissionToKernel(g_tokeId, g_opCodeList[0], true));
305 bool isGranted = false;
306 ASSERT_EQ(ENODATA, GetPermissionFromKernel(g_tokeId, g_opCodeList[0], isGranted));
307 }
308
309
310 /**
311 * @tc.name: GetPermissionFromKernel001
312 * @tc.desc: Get permissin status after removing token perission.
313 * @tc.type: FUNC
314 * @tc.require: issueI8HMUH
315 */
316 HWTEST_F(TokensetprocKitTest, GetPermissionFromKernel001, TestSize.Level0)
317 {
318 setuid(ACCESS_TOKEN_UID);
319 uint32_t size = g_opCodeList.size();
320 ASSERT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, g_opCodeList, g_statusList));
321 for (uint32_t i = 0; i < size; i++) {
322 bool isGranted = false;
323 EXPECT_EQ(ACCESS_TOKEN_OK, GetPermissionFromKernel(g_tokeId, g_opCodeList[i], isGranted));
324 EXPECT_EQ(g_statusList[i], isGranted);
325 }
326
327 std::set<uint32_t> knownOpCodeSet(g_opCodeList.data(), g_opCodeList.data() + size);
328 for (uint32_t i = 0; i < MAX_PERM_NUM; i++) {
329 if (knownOpCodeSet.find(i) == knownOpCodeSet.end()) {
330 bool isGranted = false;
331 EXPECT_EQ(ACCESS_TOKEN_OK, GetPermissionFromKernel(g_tokeId, i, isGranted));
332 EXPECT_FALSE(isGranted);
333 }
334 }
335
336 EXPECT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
337 for (uint32_t i = 0; i < size; i++) {
338 bool isGranted = false;
339 EXPECT_EQ(ENODATA, GetPermissionFromKernel(g_tokeId, g_opCodeList[i], isGranted));
340 EXPECT_EQ(false, isGranted);
341 }
342 setuid(g_selfUid);
343 }
344
345 /**
346 * @tc.name: GetPermissionFromKernel002
347 * @tc.desc: Get permissin status after set perission.
348 * @tc.type: FUNC
349 * @tc.require: issueI8HMUH
350 */
351 HWTEST_F(TokensetprocKitTest, GetPermissionFromKernel002, TestSize.Level0)
352 {
353 GTEST_LOG_(INFO) << "GetPermissionFromKernel002 start";
354 setuid(ACCESS_TOKEN_UID);
355 ASSERT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, g_opCodeList, g_statusList));
356
357 // set permission status: false
358 bool isGranted = false;
359 EXPECT_EQ(ACCESS_TOKEN_OK, SetPermissionToKernel(g_tokeId, g_opCodeList[0], false));
360 EXPECT_EQ(ACCESS_TOKEN_OK, GetPermissionFromKernel(g_tokeId, g_opCodeList[0], isGranted));
361 EXPECT_EQ(false, isGranted);
362
363 // set permission status: true
364 EXPECT_EQ(ACCESS_TOKEN_OK, SetPermissionToKernel(g_tokeId, g_opCodeList[0], true));
365 EXPECT_EQ(ACCESS_TOKEN_OK, GetPermissionFromKernel(g_tokeId, g_opCodeList[0], isGranted));
366 EXPECT_EQ(true, isGranted);
367
368 ASSERT_EQ(ACCESS_TOKEN_OK, RemovePermissionFromKernel(g_tokeId));
369 setuid(g_selfUid);
370 }
371
372 /**
373 * @tc.name: Invalid parameter
374 * @tc.desc: InvalidParam test.
375 * @tc.type: FUNC
376 * @tc.require: issueI8HMUH
377 */
378 HWTEST_F(TokensetprocKitTest, InvalidParam1, TestSize.Level0)
379 {
380 setuid(ACCESS_TOKEN_UID);
381 ASSERT_EQ(ACCESS_TOKEN_OK, AddPermissionToKernel(g_tokeId, g_opCodeList, g_statusList));
382
383 // set permission fail
384 EXPECT_EQ(EINVAL, SetPermissionToKernel(g_tokeId, INVALID_OP_CODE, false));
385
386 // get permission fail
387 bool isGranted = false;
388 ASSERT_EQ(EINVAL, GetPermissionFromKernel(g_tokeId, INVALID_OP_CODE, isGranted));
389 EXPECT_EQ(false, isGranted);
390 }
391
ThreadTestFunc01(void * args)392 static void *ThreadTestFunc01(void *args)
393 {
394 int32_t token1 = g_tokeId;
395 for (int32_t i = 0; i < CYCLE_TIMES; i++) {
396 bool isGranted = false;
397 AddPermissionToKernel(token1, g_opCodeList, g_statusList);
398 SetPermissionToKernel(token1, g_opCodeList[0], false);
399 GetPermissionFromKernel(token1, g_opCodeList[0], isGranted);
400 RemovePermissionFromKernel(token1);
401 token1++;
402 }
403 return nullptr;
404 }
405
ThreadTestFunc02(void * args)406 static void *ThreadTestFunc02(void *args)
407 {
408 int32_t token2 = g_tokeId + CYCLE_TIMES;
409 uint32_t size = g_opCodeList.size();
410 for (int32_t i = 0; i < CYCLE_TIMES; i++) {
411 bool isGranted = false;
412 AddPermissionToKernel(token2, g_opCodeList, g_statusList);
413 SetPermissionToKernel(token2, g_opCodeList[size - 1], true);
414 GetPermissionFromKernel(token2, g_opCodeList[size - 1], isGranted);
415 RemovePermissionFromKernel(token2);
416 token2++;
417 }
418 return nullptr;
419 }
420
421 /**
422 * @tc.name: Mulitpulthread001
423 * @tc.desc: Mulitpulthread test.
424 * @tc.type: FUNC
425 * @tc.require: issueI8HMUH
426 */
427 HWTEST_F(TokensetprocKitTest, Mulitpulthread001, TestSize.Level0)
428 {
429 setuid(ACCESS_TOKEN_UID);
430 int64_t beginTime = std::chrono::duration_cast<std::chrono::milliseconds>(
431 std::chrono::system_clock::now().time_since_epoch()).count();
432 pthread_t tid[2];
433 (void)pthread_create(&tid[0], nullptr, &ThreadTestFunc01, nullptr);
434 (void)pthread_create(&tid[1], nullptr, &ThreadTestFunc01, nullptr);
435 (void)pthread_join(tid[0], nullptr);
436 (void)pthread_join(tid[1], nullptr);
437
438 (void)pthread_create(&tid[0], nullptr, &ThreadTestFunc02, nullptr);
439 (void)pthread_create(&tid[1], nullptr, &ThreadTestFunc02, nullptr);
440 (void)pthread_join(tid[0], nullptr);
441 (void)pthread_join(tid[1], nullptr);
442 int64_t endTime = std::chrono::duration_cast<std::chrono::milliseconds>(
443 std::chrono::system_clock::now().time_since_epoch()).count();
444
445 setuid(g_selfUid);
446 ASSERT_TRUE(endTime - beginTime < 1000 * 100);
447 }
448
449 /**
450 * @tc.name: APICostTimeTest001
451 * @tc.desc: Test time of get permission api.
452 * @tc.type: FUNC
453 * @tc.require: issueI8HMUH
454 */
455 HWTEST_F(TokensetprocKitTest, APICostTimeTest001, TestSize.Level0)
456 {
457 GTEST_LOG_(INFO) << "APICostTimeTest001 start";
458 setuid(ACCESS_TOKEN_UID);
459 int32_t token = 0;
460 double costSum = 0.0;
461 std::vector<uint32_t> tokenList;
462 bool isGranted = false;
463 while (1) {
464 if (AddPermissionToKernel(token, g_opCodeList, g_statusList) != 0) {
465 break;
466 }
467 tokenList.emplace_back(token);
468
469 struct timespec ts1, ts2;
470 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts1);
471 GetPermissionFromKernel(token, g_opCodeList[0], isGranted);
472 clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts2);
473
474 double cost = (1000.0 * 1000.0 * ts2.tv_sec + 1e-3 * ts2.tv_nsec) -
475 (1000.0 * 1000.0 * ts1.tv_sec + 1e-3 * ts1.tv_nsec);
476
477 costSum += cost;
478 token++;
479 }
480 if (!tokenList.empty()) {
481 double avgCost = costSum / tokenList.size();
482 GTEST_LOG_(INFO) << "get average time: " << avgCost << " us";
483 EXPECT_TRUE(avgCost < 100.0); // 100.0: time limit
484 }
485
486 for (uint32_t i = 0; i < tokenList.size(); i++) {
487 RemovePermissionFromKernel(tokenList[i]);
488 }
489 setuid(g_selfUid);
490 }
491