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 #include "ActsCapabilityTest.h"
16 #include <dirent.h>
17 #include <fcntl.h>
18 #include <securec.h>
19 #include <sys/capability.h>
20 #include <sys/stat.h>
21 #include <sys/types.h>
22 #include <sys/wait.h>
23 #include "gtest/gtest.h"
24 #include "CapabilityFileSystemTest.h"
25
26 using namespace std;
27 using namespace testing::ext;
28
29 #if defined(LITE_FS_VFAT)
CreateTxt()30 static void CreateTxt()
31 {
32 int ret;
33 int fd = 0;
34 char cap[] = "CapabilityTestSuite!\n";
35 // Initialize the process and set the uid and gid of the process to zero
36 SetUidGid(UID0, GID0);
37 // Create a directory 'CAPDIR0' in the directory 'TOP_DIR'
38 ret = mkdir(TOP_DIR "/" CAPDIR0, NORWX);
39 ASSERT_EQ(ret, 0) << "ErrInfo: Failed to create the directory 'TOP_DIR/CAPDIR0'";
40 // Create a directory 'CAPDIR0_CAPDIR0' in the directory 'TOP_DIR/CAPDIR0'
41 ret = mkdir(TOP_DIR "/" CAPDIR0 "/" CAPDIR0_CAPDIR0, RWX);
42 ASSERT_EQ(ret, 0) << "ErrInfo: Failed to create the directory 'TOP_DIR/CAPDIR0/CAPDIR0_CAPDIR0'";
43 // Create a file 'CAPDIR0_CAPFILE0' in the directory 'CAPDIR0'
44 fd = open(TOP_DIR "/" CAPDIR0 "/" CAPDIR0_CAPFILE0, O_WRONLY | O_CREAT | O_TRUNC, RWX);
45 if (fd >= 0) {
46 // File created successfully
47 write(fd, cap, sizeof(cap));
48 close(fd);
49 } else {
50 // Failed to create the file
51 ASSERT_GE(fd, 0) << "ErrInfo: Failed to create the file 'TOP_DIR/CAPDIR0/CAPDIR0_CAPFILE0'";
52 }
53 }
54
CapsetOnlySETPCAP(int num)55 static int CapsetOnlySETPCAP(int num)
56 {
57 struct __user_cap_header_struct capheader;
58 errno_t result = memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0,
59 sizeof(struct __user_cap_header_struct));
60 if (result != EOK) {
61 LOG("CapgetWithAllCap memset_s failed");
62 return FALSE;
63 };
64 capheader.version = _LINUX_CAPABILITY_VERSION_3;
65 capheader.pid = 0;
66 struct __user_cap_data_struct capdata[CAP_NUM];
67 result = memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
68 0, CAP_NUM * sizeof(struct __user_cap_data_struct));
69 if (result != EOK) {
70 LOG("CapgetWithAllCap memset_s failed");
71 return FALSE;
72 };
73 capdata[CAP_TO_INDEX(CAP_SETPCAP)].permitted |= CAP_TO_MASK(CAP_SETPCAP);
74 capdata[CAP_TO_INDEX(CAP_SETPCAP)].effective |= CAP_TO_MASK(CAP_SETPCAP);
75 capdata[CAP_TO_INDEX(CAP_SETPCAP)].inheritable |= CAP_TO_MASK(CAP_SETPCAP);
76 // Set capabilities
77 int ret = capset(&capheader, &capdata[0]);
78 if (ret != 0) {
79 LOG("ErrInfo: Failed to drop all caps except CAP_SETPCAP during the %d time", num);
80 return FALSE;
81 }
82 return 0;
83 }
84
AddCapUnauthorized(int num)85 static int AddCapUnauthorized(int num)
86 {
87 struct __user_cap_header_struct capheader;
88 errno_t result = memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0,
89 sizeof(struct __user_cap_header_struct));
90 if (result != EOK) {
91 LOG("CapgetWithAllCap memset_s failed");
92 return FALSE;
93 };
94 capheader.version = _LINUX_CAPABILITY_VERSION_3;
95 capheader.pid = 0;
96 struct __user_cap_data_struct capdata[CAP_NUM];
97 result = memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
98 0, CAP_NUM * sizeof(struct __user_cap_data_struct));
99 if (result != EOK) {
100 LOG("CapgetWithAllCap memset_s failed");
101 return FALSE;
102 };
103 capdata[0].permitted = LINUX_FULL_CAP;
104 capdata[0].effective = LINUX_FULL_CAP;
105 capdata[0].inheritable = LINUX_FULL_CAP;
106 // Set capabilities
107 int ret = capset(&capheader, &capdata[0]);
108 if (ret != FALSE) {
109 LOG("ErrInfo: Add unauthorized capability during the %d time", num);
110 return FALSE;
111 }
112 return 0;
113 }
114
CapgetWithAllCap(int num)115 static int CapgetWithAllCap(int num)
116 {
117 struct __user_cap_header_struct capheader = { 0 };
118 errno_t result = memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0,
119 sizeof(struct __user_cap_header_struct));
120 if (result != EOK) {
121 LOG("CapgetWithAllCap memset_s failed");
122 return FALSE;
123 };
124 capheader.version = _LINUX_CAPABILITY_VERSION_3;
125 capheader.pid = 0;
126 struct __user_cap_data_struct capdataget[CAP_NUM] = { { 0 }, { 0 } };
127 result = memset_s(capdataget, CAP_NUM * sizeof(struct __user_cap_data_struct),
128 0, CAP_NUM * sizeof(struct __user_cap_data_struct));
129 if (result != EOK) {
130 LOG("CapgetWithAllCap memset_s failed");
131 return FALSE;
132 };
133 int ret = capget(&capheader, &capdataget[0]);
134 if (ret != 0) {
135 EXPECT_EQ(ret, 0) << "ErrInfo: Failed to get CAPs";
136 LOG("ErrInfo: Failed to get CAPs during the %d time", num);
137 return FALSE;
138 }
139 // The process has all capabilities
140 if (capdataget[0].effective != OHOS_FULL_CAP) {
141 EXPECT_EQ(capdataget[0].effective, OHOS_FULL_CAP) << "ErrInfo: Get wrong capabilities";
142 LOG("ErrInfo: Get wrong capabilities during the %d time", num);
143 return FALSE;
144 }
145 return 0;
146 }
147
CapgetWithNoCap(int num)148 static int CapgetWithNoCap(int num)
149 {
150 struct __user_cap_header_struct capheader = { 0 };
151 errno_t result = memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0,
152 sizeof(struct __user_cap_header_struct));
153 if (result != EOK) {
154 LOG("CapgetWithAllCap memset_s failed");
155 return FALSE;
156 };
157 capheader.version = _LINUX_CAPABILITY_VERSION_3;
158 capheader.pid = 0;
159 struct __user_cap_data_struct capdataget[CAP_NUM] = { { 0 }, { 0 } };
160 result = memset_s(capdataget, CAP_NUM * sizeof(struct __user_cap_data_struct),
161 0, CAP_NUM * sizeof(struct __user_cap_data_struct));
162 if (result != EOK) {
163 LOG("CapgetWithAllCap memset_s failed");
164 return FALSE;
165 };
166 int ret = capget(&capheader, &capdataget[0]);
167 if (ret != 0) {
168 EXPECT_EQ(ret, 0) << "ErrInfo: Failed to get CAPs";
169 LOG("ErrInfo: Failed to get CAPs during the %d time", num);
170 return FALSE;
171 }
172 // The process does not have any capabilities
173 if (capdataget[0].effective != NO_CAP) {
174 EXPECT_EQ(capdataget[0].effective, NO_CAP) << "ErrInfo: Get wrong capabilities";
175 LOG("ErrInfo: Get wrong capabilities during the %d time", num);
176 return FALSE;
177 }
178 return 0;
179 }
180
CapgetOnlySETPCAP(int num)181 static int CapgetOnlySETPCAP(int num)
182 {
183 struct __user_cap_header_struct capheader = { 0 };
184 errno_t result = memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0,
185 sizeof(struct __user_cap_header_struct));
186 if (result != EOK) {
187 LOG("CapgetWithAllCap memset_s failed");
188 return FALSE;
189 };
190 capheader.version = _LINUX_CAPABILITY_VERSION_3;
191 capheader.pid = 0;
192 struct __user_cap_data_struct capdataget[CAP_NUM] = { { 0 }, { 0 } };
193 result = memset_s(capdataget, CAP_NUM * sizeof(struct __user_cap_data_struct),
194 0, CAP_NUM * sizeof(struct __user_cap_data_struct));
195 if (result != EOK) {
196 LOG("CapgetWithAllCap memset_s failed");
197 return FALSE;
198 };
199 int ret = capget(&capheader, &capdataget[0]);
200 if (ret != 0) {
201 EXPECT_EQ(ret, 0) << "ErrInfo: Failed to get CAPs";
202 LOG("ErrInfo: Failed to get CAPs during the %d time", num);
203 return FALSE;
204 }
205 // The process only has CAP_SETPCAP
206 if (capdataget[0].effective != ONLY_SETPCAP_CAP) {
207 EXPECT_EQ(capdataget[0].effective, ONLY_SETPCAP_CAP) << "ErrInfo: Get wrong capabilities";
208 LOG("ErrInfo: Get wrong capabilities during the %d time", num);
209 return FALSE;
210 }
211 return 0;
212 }
213
CapsetWithoutSETPCAP()214 static int CapsetWithoutSETPCAP()
215 {
216 // Drop the capabilities of CAP_SETPCAP 8
217 int retsetpcap = DropCAPSETPCAP();
218 EXPECT_EQ(retsetpcap, 0) << "ErrInfo: Failed to drop CAP_SETPCAP";
219 // Drop the capabilities of CAP_CHOWN 0
220 int retchown = DropCAPCHOWN();
221 EXPECT_EQ(retchown, FALSE) << "ErrInfo: Drop CAP_CHOWN without CAP_SETPCAP";
222 // Drop the capabilities of CAP_DAC_OVERRIDE 1
223 int retdacoverride = DropCAPDACOVERRIDE();
224 EXPECT_EQ(retdacoverride, FALSE) << "ErrInfo: Drop CAP_DAC_OVERRIDE without CAP_SETPCAP";
225 // Drop the capabilities of CAP_DAC_READ_SEARCH 2
226 int retdacreadsearch = DropCAPDACREADSEARCH();
227 EXPECT_EQ(retdacreadsearch, FALSE) << "ErrInfo: Drop CAP_DAC_READ_SEARCH without CAP_SETPCAP";
228 // Drop the capabilities of CAP_FOWNER 3
229 int retfowner = DropCAPFOWNER();
230 EXPECT_EQ(retfowner, FALSE) << "ErrInfo: Drop CAP_FOWNER without CAP_SETPCAP";
231 // Drop the capabilities of CAP_KILL 5
232 int retkill = DropCAPKILL();
233 EXPECT_EQ(retkill, FALSE) << "ErrInfo: Drop CAP_KILL without CAP_SETPCAP";
234 // Drop the capabilities of CAP_SETGID 6
235 int retsetgid = DropCAPSETGID();
236 EXPECT_EQ(retsetgid, FALSE) << "ErrInfo: Drop CAP_SETGID without CAP_SETPCAP";
237 // Drop the capabilities of CAP_SETUID 7
238 int retsetuid = DropCAPSETUID();
239 EXPECT_EQ(retsetuid, FALSE) << "ErrInfo: Drop CAP_SETUID without CAP_SETPCAP";
240 // Drop the capabilities of CAP_SETPCAP 8
241 int retsetpcapfailed = DropCAPSETPCAP();
242 EXPECT_EQ(retsetpcapfailed, FALSE) << "ErrInfo: Drop CAP_SETPCAP without CAP_SETPCAP";
243 // Drop the capabilities of CAP_SYS_NICE 23
244 int retsysnice = DropCAPSYSNICE();
245 EXPECT_EQ(retsysnice, FALSE) << "ErrInfo: Drop CAP_SYS_NICE without CAP_SETPCAP";
246 // Drop the capabilities of CAP_SYS_TIME 25
247 int retsystime = DropCAPSYSTIME();
248 EXPECT_EQ(retsystime, FALSE) << "ErrInfo: Drop CAP_SYS_TIME without CAP_SETPCAP";
249 if ((retchown != FALSE) || (retdacoverride != FALSE) || (retdacreadsearch != FALSE) || (retfowner != FALSE) ||
250 (retkill != FALSE) || (retsetgid != FALSE) || (retsetuid != FALSE) || (retsetpcapfailed != FALSE) ||
251 (retsysnice != FALSE) || (retsystime != FALSE) || (retsetpcap == FALSE)) {
252 LOG("ErrInfo: Drop the capabilities without CAP_SETPCAP");
253 return FALSE;
254 }
255 return 0;
256 }
257
CapsetWithVersion(pid_t pid,unsigned int version)258 static int CapsetWithVersion(pid_t pid, unsigned int version)
259 {
260 struct __user_cap_header_struct capheader = { 0 };
261 errno_t result = memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0,
262 sizeof(struct __user_cap_header_struct));
263 if (result != EOK) {
264 LOG("CapgetWithAllCap memset_s failed");
265 return FALSE;
266 };
267 capheader.pid = pid;
268 capheader.version = version;
269 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
270 result = memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
271 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
272 if (result != EOK) {
273 LOG("CapgetWithAllCap memset_s failed");
274 return FALSE;
275 };
276 // Capget based on input parameters
277 int ret = capset(&capheader, &capdata[0]);
278 if (ret != 0) {
279 // Capset with abnormal parameter
280 return FALSE;
281 }
282 return 0;
283 }
284
CapgetWithVersion(pid_t pid,unsigned int version)285 static int CapgetWithVersion(pid_t pid, unsigned int version)
286 {
287 struct __user_cap_header_struct capheader = { 0 };
288 errno_t result = memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0,
289 sizeof(struct __user_cap_header_struct));
290 if (result != EOK) {
291 LOG("CapgetWithAllCap memset_s failed");
292 return FALSE;
293 };
294 capheader.pid = pid;
295 capheader.version = version;
296 struct __user_cap_data_struct capdataget[CAP_NUM] = { { 0 }, { 0 } };
297 result = memset_s(capdataget, CAP_NUM * sizeof(struct __user_cap_data_struct),
298 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
299 if (result != EOK) {
300 LOG("CapgetWithAllCap memset_s failed");
301 return FALSE;
302 };
303 // Capget based on input parameters
304 int ret = capget(&capheader, &capdataget[0]);
305 if (ret != 0) {
306 // Capget with abnormal parameter
307 return FALSE;
308 }
309 return 0;
310 }
311
CapgetWithCaps(pid_t pid,unsigned int caps)312 static int CapgetWithCaps(pid_t pid, unsigned int caps)
313 {
314 struct __user_cap_header_struct capheader = { 0 };
315 errno_t result = memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0,
316 sizeof(struct __user_cap_header_struct));
317 if (result != EOK) {
318 LOG("CapgetWithAllCap memset_s failed");
319 return FALSE;
320 };
321 capheader.pid = pid;
322 capheader.version = _LINUX_CAPABILITY_VERSION_3;
323 struct __user_cap_data_struct capdataget[CAP_NUM] = { { 0 }, { 0 } };
324 result = memset_s(capdataget, CAP_NUM * sizeof(struct __user_cap_data_struct),
325 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
326 if (result != EOK) {
327 LOG("CapgetWithAllCap memset_s failed");
328 return FALSE;
329 };
330 // Capget based on input parameters and check whether the capability is the same as the input parameter
331 int ret = capget(&capheader, &capdataget[0]);
332 if (ret != 0 || capdataget[0].effective != caps) {
333 EXPECT_EQ(capdataget[0].effective, caps) << "ErrInfo: Pid = " << pid << ", process has wrong capability";
334 return FALSE;
335 }
336 return 0;
337 }
338
339 /*
340 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_0600
341 * @tc.name : Processes with the CAP_KILL capability can invoke their management
342 and control interfaces to kill other processes
343 * @tc.desc : [C-SECURITY-0100]
344 */
345 HWTEST_F(CapabilityTestSuite, CapabilityTest0600, Function | MediumTest | Level2)
346 {
347 int ret;
348 int status1 = 0;
349 int status2 = 0;
350 // Preset action: Fork a sub process pid1
351 pid_t pid1 = fork();
352 ASSERT_TRUE(pid1 >= 0) << "======== Fork Error! =========";
353 usleep(SLEEP_NUM);
354 // Preset action: Change the UID&GID of the sub process pid1 and keep it hibernated
355 if (pid1 == 0) {
356 SetUidGid(UID555, GID555);
357 ChildSleep();
358 } else {
359 // Preset action: Fork a sub process pid2
360 pid_t pid2 = fork();
361 ASSERT_TRUE(pid2 >= 0) << "======== Fork Error! =========";
362 usleep(SLEEP_NUM);
363 if (pid2 == 0) {
364 int exitCode = 0;
365 // Step 1: Drop the capabilities of CAP_KILL
366 ret = DropCAPKILL();
367 if (ret != 0) {
368 LOG("ErrInfo: Failed to drop CAP_KILL");
369 exitCode = 1;
370 }
371 // Step 2: Failed to kill the sub process
372 ret = kill(pid1, SIGXFSZ);
373 if (ret != FALSE) {
374 LOG("ErrInfo: Kill process without CAP_KILL");
375 exitCode = 1;
376 }
377 // Step 3: Change the UID&GID of the sub process pid1 and keep it hibernated
378 ret = SetUidGid(UID555, GID555);
379 if (ret != 0) {
380 LOG("ErrInfo: Failed to set uid and gid");
381 exitCode = 1;
382 }
383 // Step 4: The sub process exit with the exitCode
384 exit(exitCode);
385 } else {
386 // Step 4: Kill the sub process pid1 successfully
387 ret = kill(pid1, SIGXFSZ);
388 EXPECT_EQ(ret, 0) << "ErrInfo: Failed to Kill pid1 with CAP_KILL";
389 // Cleanup action: Wait for the sub process pid1 and pid2 to be killed
390 waitpid(pid1, &status1, 0);
391 waitpid(pid2, &status2, 0);
392 EXPECT_NE(WIFEXITED(status2), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid2;
393 EXPECT_EQ(WEXITSTATUS(status2), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = "
394 << pid2;
395 }
396 }
397 }
398
399 /*
400 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_0700
401 * @tc.name : Processes with the CAP_SETGID capability can invoke their management
402 and control interfaces to change the group IDs of other processes
403 * @tc.desc : [C-SECURITY-0100]
404 */
405 HWTEST_F(CapabilityTestSuite, CapabilityTest0700, Function | MediumTest | Level2)
406 {
407 int ret;
408 int status = 0;
409 pid_t pid = fork(); // Preset action: Fork a sub process
410 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
411 usleep(SLEEP_NUM);
412 if (pid == 0) {
413 int exitCode = 0;
414 ret = setgid(NUM500); // Step 1.1: Set GID with interface 'setgid'
415 if (ret != 0) {LOG("ErrInfo: Failed to set GID with interface 'setgid', now process gid=%d", getpid());
416 exitCode = 1; }
417 ret = setregid(NUM600, NUM600); // Step 1.2: Set reGID with interface 'setregid'
418 if (ret != 0) {LOG("ErrInfo: Failed to set reGID with interface 'setregid', now process gid=%d", getpid());
419 exitCode = 1; }
420 ret = setresgid(NUM700, NUM700, NUM700); // Step 1.3: Set resGID with interface 'setresgid'
421 if (ret != 0) {LOG("ErrInfo: Failed to set resGID with interface 'setresgid', now process gid=%d", getpid());
422 exitCode = 1; }
423 ret = setgroups(NUM3, GROUPLIST); // Step 1.4: Set groups with interface 'setgroups'
424 if (ret != 0) {LOG("ErrInfo: Failed to set groups with interface 'setgroups'");
425 exitCode = 1; }
426 ret = DropCAPSETGID(); // Step 2: Drop the capabilities of CAP_SETGID
427 if (ret != 0) {LOG("ErrInfo: Failed to drop CAP_SETGID");
428 exitCode = 1; }
429 ret = setgid(NUM500); // Step 3.1: Failed to set GID with interface 'setgid'
430 if (ret != FALSE) {LOG("ErrInfo: Set GID without CAP_SETGID, now process gid=%d", getpid());
431 exitCode = 1; }
432 ret = setregid(NUM500, NUM500); // Step 3.2: Failed to set reGID with interface 'setregid'
433 if (ret != FALSE) {LOG("ErrInfo: Set reGID without CAP_SETGID, now process gid=%d", getpid());
434 exitCode = 1; }
435 ret = setresgid(NUM500, NUM500, NUM500); // Step 3.3: Failed to set resGID with interface 'setregid'
436 if (ret != FALSE) {LOG("ErrInfo: Set resGID without CAP_SETGID, now process gid=%d", getpid());
437 exitCode = 1; }
438 ret = setgroups(NUM3, GROUPLIST); // Step 3.4: Failed to set groups with interface 'setgroups'
439 if (ret != FALSE) {LOG("ErrInfo: Set groups without CAP_SETGID");
440 exitCode = 1; } // Step 4: The sub process exit with the exitCode
441 exit(exitCode);
442 } else {
443 waitpid(pid, &status, 0); // Step 5: The parent process wait for the sub process to exit and obtain the exitCode
444 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
445 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
446 }
447 }
448
449 /*
450 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_0800
451 * @tc.name : Processes with the CAP_SETUID capability can invoke their management
452 and control interfaces to change user IDs of other processes
453 * @tc.desc : [C-SECURITY-0100]
454 */
455 HWTEST_F(CapabilityTestSuite, CapabilityTest0800, Function | MediumTest | Level2)
456 {
457 int ret;
458 int status = 0;
459 // Preset action: Fork a sub process
460 pid_t pid = fork();
461 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
462 usleep(SLEEP_NUM);
463 if (pid == 0) {
464 int exitCode = 0;
465 // Step 1.1: Set UID with interface 'setuid'
466 ret = setuid(NUM500);
467 if (ret != 0) {
468 LOG("ErrInfo: Failed to set UID with interface 'setuid', now process uid=%d", getpid());
469 exitCode = 1;
470 }
471 // Step 1.2: Set reUID with interface 'setreuid'
472 ret = setreuid(NUM600, NUM600);
473 if (ret != 0) {
474 LOG("ErrInfo: Failed to set reUID with interface 'setreuid', now process uid=%d", getpid());
475 exitCode = 1;
476 }
477 // Step 1.3: Set resUID with interface 'setresuid'
478 ret = setresuid(NUM700, NUM700, NUM700);
479 if (ret != 0) {
480 LOG("ErrInfo: Failed to set resUID with interface 'setresuid', now process uid=%d", getpid());
481 exitCode = 1;
482 }
483 // Step 2: Drop the capabilities of CAP_SETUID
484 ret = DropCAPSETUID();
485 if (ret != 0) {
486 LOG("ErrInfo: Failed to drop CAP_SETUID");
487 exitCode = 1;
488 }
489 // Step 3.1: Failed to set UID with interface 'setuid'
490 ret = setuid(NUM500);
491 if (ret != FALSE) {
492 LOG("ErrInfo: Set UID without CAP_SETUID, now process uid=%d", getpid());
493 exitCode = 1;
494 }
495 // Step 3.2: Failed to set reUID with interface 'setreuid'
496 ret = setreuid(NUM500, NUM500);
497 if (ret != FALSE) {
498 LOG("ErrInfo: Set reUID without CAP_SETUID, now process uid=%d", getpid());
499 exitCode = 1;
500 }
501 // Step 3.3: Failed to set resUID with interface 'setreuid'
502 ret = setresuid(NUM500, NUM500, NUM500);
503 if (ret != FALSE) {
504 LOG("ErrInfo: Set resUID without CAP_SETUID, now process uid=%d", getpid());
505 exitCode = 1;
506 }
507 // Step 4: The sub process exit with the exitCode
508 exit(exitCode);
509 } else {
510 // Step 5: The parent process wait for the sub process to exit and obtain the exitCode
511 waitpid(pid, &status, 0);
512 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
513 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
514 }
515 }
516
517 /*
518 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_0900
519 * @tc.name : Processes with the CAP_SETPCCAP capability can invoke their management
520 and control interfaces to add and delete capabilities for other processes
521 * @tc.desc : [C-SECURITY-0100]
522 */
523 HWTEST_F(CapabilityTestSuite, CapabilityTest0900, Security | MediumTest | Level2)
524 {
525 int ret;
526 int status = 0;
527 // Preset action: Fork a sub process
528 pid_t pid = fork();
529 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
530 usleep(SLEEP_NUM);
531 if (pid == 0) {
532 int exitCode = 0;
533 // Step 1: Drop the capabilities of CAP_SETPCAP
534 ret = DropCAPSETPCAP();
535 if (ret != 0) {
536 LOG("ErrInfo: Failed to drop CAP_SETPCAP");
537 exitCode = 1;
538 }
539 // Step 2: Failed to add the capabilities of CAP_SETPCAP
540 exitCode = AddCapUnauthorized(1);
541 if (exitCode != 0) {
542 LOG("ErrInfo: Add capabilities without CAP_SETPCAP");
543 }
544 // Step 3: The sub process exit with the exitCode
545 exit(exitCode);
546 } else {
547 // Step 4: The parent process wait for the sub process to exit and obtain the exitCode
548 waitpid(pid, &status, 0);
549 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
550 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
551 }
552 }
553
554 /*
555 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_1000
556 * @tc.name : Processes with the CAP_SYS_NICE capability can invoke their management
557 and control interfaces to set the process priority
558 * @tc.desc : [C-SECURITY-0100]
559 */
560 HWTEST_F(CapabilityTestSuite, CapabilityTest1000, Function | MediumTest | Level2)
561 {
562 int ret;
563 int status1 = 0;
564 int status2 = 0;
565 // Preset action: Fork a sub process pid1
566 pid_t pid1 = fork();
567 ASSERT_TRUE(pid1 >= 0) << "======== Fork Error! =========";
568 usleep(SLEEP_NUM);
569 // Preset action: keep the sub process pid1 hibernated
570 if (pid1 == 0) {
571 ChildSleep();
572 } else {
573 // Preset action: Fork a sub process pid2
574 pid_t pid2 = fork();
575 ASSERT_TRUE(pid2 >= 0) << "======== Fork Error! =========";
576 usleep(SLEEP_NUM);
577 if (pid2 == 0) {
578 int exitCode = 0;
579 // Preset action: Obtains the test priority
580 struct sched_param param = { 0 };
581 ret = sched_getparam(pid1, ¶m);
582 param.sched_priority--;
583 // Step 1: Set the priority of the sub process successfully
584 ret = sched_setparam(pid1, ¶m);
585 if (ret != 0) {
586 LOG("ErrInfo: Failed to set priority with CAP_SYS_NICE");
587 exitCode = 1;
588 }
589 // Step 2: Drop the capabilities of CAP_SYS_NICE
590 ret = DropCAPSYSNICE();
591 if (ret != 0) {
592 LOG("ErrInfo: Failed to drop CAP_SYS_NICE");
593 exitCode = 1;
594 }
595 // Step 3: Failed to set the priority of the sub process
596 param.sched_priority++;
597 ret = sched_setparam(pid1, ¶m);
598 if (ret != FALSE) {
599 LOG("ErrInfo: Set priority without CAP_SYS_NICE");
600 exitCode = 1;
601 }
602 // Step 4: The sub process exit with the exitCode
603 exit(exitCode);
604 } else {
605 // Step 5: The parent process wait for the sub process to exit and obtain the exitCode
606 waitpid(pid2, &status2, 0);
607 EXPECT_NE(WIFEXITED(status2), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid2;
608 EXPECT_EQ(WEXITSTATUS(status2), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = "
609 << pid2;
610 // Cleanup action: Kill the sub process and wait for the sub process to be killed
611 ret = kill(pid1, SIGXFSZ);
612 EXPECT_EQ(ret, 0) << "ErrInfo: Failed to kill the sub process pid1";
613 waitpid(pid1, &status1, 0);
614 }
615 }
616 }
617
618 /*
619 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_1100
620 * @tc.name : Processes with the CAP_SYS_TIME capability can call their management
621 and control interfaces and change the system clock
622 * @tc.desc : [C-SECURITY-0100]
623 */
624 HWTEST_F(CapabilityTestSuite, CapabilityTest1100, Function | MediumTest | Level2)
625 {
626 int ret;
627 int status = 0;
628 struct timespec tp = { 0 };
629 // Preset action: Fork a sub process
630 pid_t pid = fork();
631 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
632 usleep(SLEEP_NUM);
633 if (pid == 0) {
634 int exitCode = 0;
635 // Preset action: Obtains the system time and the test time
636 clock_gettime(CLOCK_REALTIME, &tp);
637 tp.tv_sec += 1;
638 // Step 1: Set the System Time with the test time successfully
639 ret = clock_settime(CLOCK_REALTIME, &tp);
640 if (ret != 0) {
641 LOG("ErrInfo: Failed to set clocktime with CAP_SYS_TIME");
642 exitCode = 1;
643 }
644 // Step 2: Drop the capabilities of CAP_SYS_TIME
645 ret = DropCAPSYSTIME();
646 if (ret != 0) {
647 LOG("ErrInfo: Failed to drop CAP_SYS_TIME");
648 exitCode = 1;
649 }
650 // Step 3: Failed to set the system time with the test time
651 tp.tv_sec += 1;
652 ret = clock_settime(CLOCK_REALTIME, &tp);
653 if (ret != FALSE) {
654 LOG("ErrInfo: Set clocktime without CAP_SYS_TIME");
655 exitCode = 1;
656 }
657 // Step 4: The sub process exit with the exitCode
658 exit(exitCode);
659 } else {
660 // Step 5: The parent process wait for the sub process to exit and obtain the exitCode
661 waitpid(pid, &status, 0);
662 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
663 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
664 }
665 }
666
667 /*
668 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_1200
669 * @tc.name : Processes without the CAP_SETPCAP capability cannot drop any capability
670 * @tc.desc : [C-SECURITY-0100]
671 */
672 HWTEST_F(CapabilityTestSuite, CapabilityTest1200, Function | MediumTest | Level3)
673 {
674 int status = 0;
675 // Preset action: Fork a sub process
676 pid_t pid = fork();
677 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
678 usleep(SLEEP_NUM);
679 if (pid == 0) {
680 int exitCode = 0;
681 // Step 1: Failed to add capabilities without CAP_SETPCAP
682 exitCode = CapsetWithoutSETPCAP();
683 // Step 2: The sub process exit with the exitCode
684 exit(exitCode);
685 } else {
686 // Step 3: The parent process wait for the sub process to exit and obtain the exitCode
687 waitpid(pid, &status, 0);
688 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
689 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
690 }
691 }
692
693 /*
694 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_1300
695 * @tc.name : Inheritance of process capabilities
696 * @tc.desc : [C-SECURITY-0100]
697 */
698 HWTEST_F(CapabilityTestSuite, CapabilityTest1300, Function | MediumTest | Level1)
699 {
700 int status = 0;
701 // Preset action: Fork a sub process
702 pid_t pid = fork();
703 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
704 usleep(SLEEP_NUM);
705 if (pid == 0) {
706 int exitCode = 0;
707 // Step 1: Query the sub process capabilities for 10000 times
708 for (int number = 0; number < NUM10000; number++) {
709 exitCode = CapgetWithAllCap(number);
710 if (exitCode != 0) {
711 LOG("ErrInfo: CapgetWithAllCap error during the %d time", number);
712 break;
713 }
714 }
715 // Step 2: The sub process exit with the exitCode
716 exit(exitCode);
717 } else {
718 // Step 3: The parent process wait for the sub process to exit and obtain the exitCode
719 waitpid(pid, &status, 0);
720 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
721 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
722 // Step 4: Query the parent process capabilities
723 int ret = CapgetWithAllCap(1);
724 EXPECT_EQ(ret, 0) << "ErrInfo: CapgetWithAllCap error";
725 }
726 }
727
728 /*
729 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_1400
730 * @tc.name : Invoke the capset interface to add and drop the process capabilities for 10000 times
731 * @tc.desc : [C-SECURITY-0100]
732 */
733 HWTEST_F(CapabilityTestSuite, CapabilityTest1400, Reliability | MediumTest | Level2)
734 {
735 int status = 0;
736 // Preset action: Fork a sub process
737 pid_t pid = fork();
738 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
739 usleep(SLEEP_NUM);
740 if (pid == 0) {
741 int exitCode = 0;
742 // Step 1: Drop and add the sub process capabilities for 10000 times
743 for (int number = 0; number < NUM10000; number++) {
744 exitCode = CapsetOnlySETPCAP(number);
745 if (exitCode != 0) {
746 LOG("ErrInfo: CapsetOnlySETPCAP error during the %d time", number);
747 break;
748 }
749 exitCode = AddCapUnauthorized(number);
750 if (exitCode != 0) {
751 LOG("ErrInfo: AddCapUnauthorized error during the %d time", number);
752 break;
753 }
754 }
755 // Step 2: The sub process exit with the exitCode
756 exit(exitCode);
757 } else {
758 // Step 3: The parent process wait for the sub process to exit and obtain the exitCode
759 waitpid(pid, &status, 0);
760 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
761 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
762 }
763 }
764
765 /*
766 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_1500
767 * @tc.name : Invoke the capset interface to revoke the process capabilities which not exist for 10000 times
768 * @tc.desc : [C-SECURITY-0100]
769 */
770 HWTEST_F(CapabilityTestSuite, CapabilityTest1500, Reliability | MediumTest | Level2)
771 {
772 int status = 0;
773 // Preset action: Fork a sub process
774 pid_t pid = fork();
775 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
776 usleep(SLEEP_NUM);
777 if (pid == 0) {
778 int exitCode = 0;
779 struct __user_cap_header_struct capheader = { 0 };
780 errno_t result = memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0,
781 sizeof(struct __user_cap_header_struct));
782 if (result != EOK) {
783 LOG("CapgetWithAllCap memset_s failed");
784 ASSERT_TRUE(false);
785 };
786 capheader.version = _LINUX_CAPABILITY_VERSION_3;
787 capheader.pid = 0;
788 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
789 result = memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
790 LINUX_FULL_CAP, CAP_NUM * sizeof(struct __user_cap_data_struct));
791 if (result != EOK) {
792 LOG("CapgetWithAllCap memset_s failed");
793 ASSERT_TRUE(false);
794 };
795 capdata[CAP_TO_INDEX(INVALID_CAP_TO_INDEX)].permitted &= ~CAP_TO_MASK(INVALID_CAP_TO_INDEX);
796 capdata[CAP_TO_INDEX(INVALID_CAP_TO_INDEX)].effective &= ~CAP_TO_MASK(INVALID_CAP_TO_INDEX);
797 capdata[CAP_TO_INDEX(INVALID_CAP_TO_INDEX)].inheritable &= ~CAP_TO_MASK(INVALID_CAP_TO_INDEX);
798 for (int number = 0; number < NUM10000; number++) {
799 // Step 1: Drop an abnormal capability for 10000 times
800 int ret = capset(&capheader, &capdata[0]);
801 if (ret != 0) {
802 LOG("ErrInfo: Drop an abnormal capability during the %d time", number);
803 exitCode = 1;
804 break;
805 }
806 }
807 // Step 2: The sub process exit with the exitCode
808 exit(exitCode);
809 } else {
810 // Step 3: The parent process wait for the sub process to exit and obtain the exitCode
811 waitpid(pid, &status, 0);
812 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
813 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
814 }
815 }
816
817 /*
818 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_1600
819 * @tc.name : Enter the exception parameter for 10000 times when invoke the capset interface
820 * @tc.desc : [C-SECURITY-0100]
821 */
822 HWTEST_F(CapabilityTestSuite, CapabilityTest1600, Reliability | MediumTest | Level3)
823 {
824 int ret;
825 int status = 0;
826 // Preset action: Fork a sub process
827 pid_t pid = fork();
828 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
829 usleep(SLEEP_NUM);
830 if (pid == 0) {
831 int exitCode = 0;
832 for (int number = 0; number < NUM10000; number++) {
833 // Step 1.1: Capset the abnormal capheader.pid '-1' for 10000 times
834 ret = CapsetWithVersion(FALSE, _LINUX_CAPABILITY_VERSION_3);
835 if (ret != FALSE) {
836 LOG("ErrInfo: Capset with the abnormal capheader.pid '-1' during the %d time", number);
837 exitCode = 1;
838 break;
839 }
840 // Step 1.2: Capset the abnormal capheader.pid '65536' for 10000 times
841 ret = CapsetWithVersion(INVAILD_PID, _LINUX_CAPABILITY_VERSION_3);
842 if (ret != FALSE) {
843 LOG("ErrInfo: Capset with the abnormal capheader.pid '65536' during the %d time", number);
844 exitCode = 1;
845 break;
846 }
847 // Step 1.3: Capset the abnormal capheader.version '1' for 10000 times
848 ret = CapsetWithVersion(0, 1);
849 if (ret != FALSE) {
850 LOG("ErrInfo: Capset with the abnormal normal capheader.version '1' during the %d time", number);
851 exitCode = 1;
852 break;
853 }
854 // Step 1.4: Capset the abnormal capheader.version '_LINUX_CAPABILITY_VERSION_1' for 10000 times
855 ret = CapsetWithVersion(0, _LINUX_CAPABILITY_VERSION_1);
856 if (ret != 0) {
857 LOG("ErrInfo: Capset with the abnormal capheader.version '_LINUX_CAPABILITY_VERSION_1'"
858 "during the %d time", number);
859 exitCode = 1;
860 break;
861 }
862 // Step 1.5: Add normal capheader.version '_LINUX_CAPABILITY_VERSION_3' for 10000 times
863 ret = CapsetWithVersion(0, _LINUX_CAPABILITY_VERSION_3);
864 if (ret != 0) {
865 LOG("ErrInfo: Failed to capset with normal capheader.version during the %d time", number);
866 exitCode = 1;
867 break;
868 }
869 }
870 // Step 2: The sub process exit with the exitCode
871 exit(exitCode);
872 } else {
873 // Step 3: The parent process wait for the sub process to exit and obtain the exitCode
874 waitpid(pid, &status, 0);
875 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
876 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
877 }
878 }
879
880 /*
881 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_1700
882 * @tc.name : Invoke the capget interface to query the process capabilities for 10000 times
883 * @tc.desc : [C-SECURITY-0100]
884 */
885 HWTEST_F(CapabilityTestSuite, CapabilityTest1700, Reliability | MediumTest | Level2)
886 {
887 // Step 1: Query the process capabilities for 10000 times
888 for (int number = 0; number < NUM10000; number++) {
889 int ret = CapgetWithAllCap(number);
890 if (ret != 0) {
891 EXPECT_EQ(ret, 0) << "ErrInfo: CapgetWithAllCap error during the " << number << " time";
892 break;
893 }
894 }
895 }
896
897 /*
898 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_1800
899 * @tc.name : Invoke the capget interface to query the process capabilities which not exist for 10000 times
900 * @tc.desc : [C-SECURITY-0100]
901 */
902 HWTEST_F(CapabilityTestSuite, CapabilityTest1800, Reliability | MediumTest | Level3)
903 {
904 int ret;
905 int status = 0;
906 // Preset action: Fork a sub process
907 pid_t pid = fork();
908 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
909 usleep(SLEEP_NUM);
910 if (pid == 0) {
911 int exitCode = 0;
912 // Step 1: Drop all the sub process capabilities
913 DropAllCAP();
914 // Step 2: Obtain the sub process capabilities
915 for (int number = 0; number < NUM10000; number++) {
916 exitCode = CapgetWithNoCap(number);
917 if (exitCode != 0) {
918 LOG("ErrInfo: CapgetWithNoCap error during the %d time", number);
919 break;
920 }
921 }
922 // Step 3: The sub process exit with the exitCode
923 exit(exitCode);
924 } else {
925 // Step 4: The parent process wait for the sub process to exit and obtain the exitCode
926 waitpid(pid, &status, 0);
927 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
928 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
929 // Step 5: Query the parent process capabilities
930 ret = CapgetWithAllCap(1);
931 EXPECT_EQ(ret, 0) << "ErrInfo: CapgetWithAllCap error";
932 }
933 }
934
935 /*
936 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_1900
937 * @tc.name : Enter the exception parameter for 10000 times when invoke the capget interface
938 * @tc.desc : [C-SECURITY-0100]
939 */
940 HWTEST_F(CapabilityTestSuite, CapabilityTest1900, Reliability | MediumTest | Level2)
941 {
942 int ret;
943 int status = 0;
944 // Preset action: Fork a sub process
945 pid_t pid = fork();
946 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
947 usleep(SLEEP_NUM);
948 if (pid == 0) {
949 int exitCode = 0;
950 for (int number = 0; number < NUM10000; number++) {
951 // Step 1.1: Capget the abnormal capheader.pid '-1' for 10000 times
952 ret = CapgetWithVersion(FALSE, _LINUX_CAPABILITY_VERSION_3);
953 if (ret != FALSE) {
954 LOG("ErrInfo: Capget with the abnormal capheader.pid '-1' during the %d time", number);
955 exitCode = 1;
956 break;
957 }
958 // Step 1.2: Capget the abnormal capheader.pid '65536' for 10000 times
959 ret = CapgetWithVersion(INVAILD_PID, _LINUX_CAPABILITY_VERSION_3);
960 if (ret != FALSE) {
961 LOG("ErrInfo: Capget with the abnormal capheader.pid '65536' during the %d time", number);
962 exitCode = 1;
963 break;
964 }
965 // Step 1.3: Capget the abnormal capheader.version '1' for 10000 times
966 ret = CapgetWithVersion(0, 1);
967 if (ret != FALSE) {
968 LOG("ErrInfo: Capget with the abnormal capheader.version '1' during the %d time", number);
969 exitCode = 1;
970 break;
971 }
972 // Step 1.4: Capget with the abnormal capheader.version '_LINUX_CAPABILITY_VERSION_1' for 10000 times
973 ret = CapgetWithVersion(0, _LINUX_CAPABILITY_VERSION_1);
974 if (ret != 0) {
975 LOG("ErrInfo: Capget with the abnormal capheader.version '_LINUX_CAPABILITY_VERSION_1'"
976 "during the %d time", number);
977 exitCode = 1;
978 break;
979 }
980 // Step 1.5: Capget the normal capheader.version '_LINUX_CAPABILITY_VERSION_3' for 10000 times
981 ret = CapgetWithVersion(0, _LINUX_CAPABILITY_VERSION_3);
982 if (ret != 0) {
983 LOG("ErrInfo: Failed to capget with the normal capheader.version '_LINUX_CAPABILITY_VERSION_3'"
984 "during the %d time", number);
985 exitCode = 1;
986 break;
987 }
988 }
989 // Step 2: The sub process exit with the exitCode
990 exit(exitCode);
991 } else {
992 // Step 3: The parent process wait for the sub process to exit and obtain the exitCode
993 waitpid(pid, &status, 0);
994 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
995 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
996 }
997 }
998
999 /*
1000 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_2100
1001 * @tc.name : Five processes concurrently invoke APIs managed by the capability for 5000 times
1002 * @tc.desc : [C-SECURITY-0100]
1003 */
1004 HWTEST_F(CapabilityTestSuite, CapabilityTest2100, Reliability | MediumTest | Level2)
1005 {
1006 int status = 0;
1007 // Preset action: Fork five sub processes
1008 pid_t pid;
1009 for (int num = 0; num < NUM5; num++) {
1010 pid = fork();
1011 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1012 usleep(SLEEP_NUM);
1013 if (pid == 0) {
1014 break;
1015 }
1016 }
1017 // get one parent & five children
1018 if (pid == 0) {
1019 int exitCode = 0;
1020 for (int number = 0; number < NUM5000; number++) {
1021 // Step 1: Five sub processes simultaneously drop capabilities for 5000 times
1022 exitCode = CapsetOnlySETPCAP(number);
1023 if (exitCode != 0) {
1024 LOG("ErrInfo: CapsetOnlySETPCAP Error during the %d time", number);
1025 break;
1026 }
1027 // Step 2: Five sub processes simultaneously add capabilities for 5000 times
1028 exitCode = AddCapUnauthorized(number);
1029 if (exitCode != 0) {
1030 LOG("ErrInfo: AddCapUnauthorized Error during the %d time", number);
1031 break;
1032 }
1033 // Step 3: Five sub processes simultaneously capget for 5000 times
1034 exitCode = CapgetOnlySETPCAP(number);
1035 if (exitCode != 0) {
1036 LOG("ErrInfo: CapgetOnlySETPCAP Error during the %d time", number);
1037 break;
1038 }
1039 }
1040 // Step 4: Five sub processes exit with the exitCode
1041 exit(exitCode);
1042 } else {
1043 // Step 5: The parent process wait for five sub processes to exit and obtain the exitCode
1044 for (int num2 = 0; num2 < NUM5; num2++) {
1045 wait(&status);
1046 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
1047 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: Pid = "<< pid
1048 << ", its exitCode is wrong and test case failed, please query logs";
1049 }
1050 }
1051 }
1052
1053 /*
1054 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_2200
1055 * @tc.name : Check whether the default configuration of the system process capabilities
1056 is the same as that described in the design document
1057 * @tc.desc : [C-SECURITY-0100]
1058 */
1059 HWTEST_F(CapabilityTestSuite, CapabilityTest2200, Security | MediumTest | Level1)
1060 {
1061 int ret;
1062 // Step 1: Check the capability of process 'init', pid = 1
1063 ret = CapgetWithCaps(INIT_PID, INIT_CAP);
1064 EXPECT_EQ(ret, 0) << "ErrInfo: Pid = 1, process init has wrong capability";
1065 // Step 2: Check the capability of process 'KProcess', pid = 2
1066 ret = CapgetWithCaps(KPROCESS_PID, KPROCESS_CAP);
1067 EXPECT_EQ(ret, 0) << "ErrInfo: Pid = 2, process KProcess has wrong capability";
1068 // Step 3: Check the capability of process 'shell', pid = 8
1069 ret = CapgetWithCaps(SHELL_PID, SHELL_CAP);
1070 EXPECT_EQ(ret, 0) << "ErrInfo: Pid = 8, process shell has wrong capability";
1071 // Step 4: Check the capability of process 'apphilogcat', pid = 10
1072 ret = CapgetWithCaps(HILOGCAT_PID, HILOGCAT_CAP);
1073 EXPECT_EQ(ret, 0) << "ErrInfo: Pid = 10, process apphilogcat has wrong capability";
1074 // Step 5: Check the capability of process 'foundation', pid = 3
1075 ret = CapgetWithCaps(FOUNDATION_PID, FOUNDATION_CAP);
1076 EXPECT_EQ(ret, 0) << "ErrInfo: Pid = 3, process foundation has wrong capability";
1077 // Step 6: Check the capability of process 'bundle_daemon', pid = 4
1078 ret = CapgetWithCaps(BUNDLE_DAEMON_PID, BUNDLE_DAEMON_CAP);
1079 EXPECT_EQ(ret, 0) << "ErrInfo: Pid = 4, process bundle_daemon has wrong capability";
1080 // Step 7: Check the capability of process 'appspawn', pid = 5
1081 ret = CapgetWithCaps(APPSPAWN_PID, APPSPAWN_CAP);
1082 EXPECT_EQ(ret, 0) << "ErrInfo: Pid = 5, process appspawn has wrong capability";
1083 // Step 8: Check the capability of process 'media_server', pid = 6
1084 ret = CapgetWithCaps(MEDIA_SERVER_PID, MEDIA_SERVER_CAP);
1085 EXPECT_EQ(ret, 0) << "ErrInfo: Pid = 6, process media_server has wrong capability";
1086 // Step 9: Check the capability of process 'wms_server' or 'ai_server', pid = 7
1087 ret = CapgetWithCaps(WMS_SERVER_OR_AI_SERVER_PID, WMS_SERVER_OR_AI_SERVER_CAP);
1088 EXPECT_EQ(ret, 0) << "ErrInfo: Pid = 7, process wms_server or ai_server has wrong capability";
1089 }
1090
1091 /*
1092 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_2300
1093 * @tc.name : Check whether the default configuration of the capability of the third-party application process
1094 is the same as that described in the design document
1095 * @tc.desc : [C-SECURITY-0100]
1096 */
1097 HWTEST_F(CapabilityTestSuite, CapabilityTest2300, Security | MediumTest | Level1)
1098 {
1099 int ret;
1100 struct __user_cap_header_struct capheader = { 0 };
1101 errno_t result = memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0,
1102 sizeof(struct __user_cap_header_struct));
1103 if (result != EOK) {
1104 LOG("CapgetWithAllCap memset_s failed");
1105 ASSERT_TRUE(false);
1106 };
1107 capheader.version = _LINUX_CAPABILITY_VERSION_3;
1108 struct __user_cap_data_struct capdataget[CAP_NUM] = { { 0 }, { 0 } };
1109 result = memset_s(capdataget, CAP_NUM * sizeof(struct __user_cap_data_struct),
1110 0, CAP_NUM * sizeof(struct __user_cap_data_struct));
1111 if (result != EOK) {
1112 LOG("CapgetWithAllCap memset_s failed");
1113 ASSERT_TRUE(false);
1114 };
1115 pid_t pid = getpid();
1116 for (int num = OTHER_PID; num <= pid; num++) {
1117 // Step 1: The current test process has all capabilities
1118 if (num == pid) {
1119 capheader.pid = pid;
1120 ret = capget(&capheader, &capdataget[0]);
1121 EXPECT_EQ(capdataget[0].effective, OHOS_FULL_CAP) <<"ErrInfo: Pid = " << num
1122 << ", test_process has wrong capability";
1123 } else {
1124 // Step 2: Check the capability of process from pid = 9
1125 capheader.pid = num;
1126 ret = capget(&capheader, &capdataget[0]);
1127 if (ret == 0) {
1128 // Step 2.1: Check the capability of process which exists now
1129 EXPECT_EQ(capdataget[0].effective, NO_CAP) << "ErrInfo: Pid = " << num
1130 << ", thirdPartyApp has wrong capability";
1131 } else {
1132 // Step 2.2: Check the capability of process which not exist now
1133 EXPECT_EQ(ret, FALSE) << "ErrInfo: Capget return error, now process uid=" << getuid();
1134 }
1135 }
1136 }
1137 }
1138
1139 /*
1140 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_2400
1141 * @tc.name : The process continuously invokes the capset and capget interfaces,
1142 which does not affect the use of other processes
1143 * @tc.desc : [C-SECURITY-0100]
1144 */
1145 HWTEST_F(CapabilityTestSuite, CapabilityTest2400, Function | MediumTest | Level1)
1146 {
1147 int status = 0;
1148 // Preset action: Create a txt
1149 CreateTxt();
1150 // Preset action: Fork two sub processes
1151 pid_t pid;
1152 for (int num = 0; num < NUM2; num++) {
1153 pid = fork();
1154 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1155 usleep(SLEEP_NUM);
1156 if (pid == 0) {
1157 break;
1158 }
1159 }
1160 // get one parent & two children
1161 if (pid == 0) {
1162 int exitCode = 0;
1163 for (int number = 0; number < NUM5000; number++) {
1164 // Step 1: Two sub processes simultaneously drop capabilities for 5000 times
1165 exitCode = CapsetOnlySETPCAP(number);
1166 if (exitCode != 0) {
1167 LOG("ErrInfo: CapsetOnlySETPCAP Error during the %d time", number);
1168 break;
1169 }
1170 // Step 2: Two sub processes simultaneously add capabilities for 5000 times
1171 exitCode = AddCapUnauthorized(number);
1172 if (exitCode != 0) {
1173 LOG("ErrInfo: AddCapUnauthorized Error during the %d time", number);
1174 break;
1175 }
1176 // Step 3: Two sub processes simultaneously capget for 5000 times
1177 exitCode = CapgetOnlySETPCAP(number);
1178 if (exitCode != 0) {
1179 LOG("ErrInfo: CapgetOnlySETPCAP Error during the %d time", number);
1180 break;
1181 }
1182 }
1183 // Step 4: Two sub processes exit with the exitCode
1184 exit(exitCode);
1185 } else {
1186 // Step 5: The parent process simultaneously invoke chown interfaces for 1000 times
1187 for (int number2 = 0; number2 < NUM1000; number2++) {
1188 int ret = chown(TOP_DIR "/" CAPDIR0 "/" CAPDIR0_CAPFILE0, number2, number2);
1189 if (ret != 0) {
1190 EXPECT_EQ(ret, 0) << "ErrInfo: Failed to chown during the " << number2 << " time";
1191 break;
1192 }
1193 }
1194 // Step 6: The parent process wait for two sub processes to exit and obtain the exitCode
1195 for (int num2 = 0; num2 < NUM2; num2++) {
1196 wait(&status);
1197 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
1198 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: Pid = "<< pid
1199 << ", its exitCode is wrong and test case failed, please query logs";
1200 }
1201 }
1202 }
1203
1204 /*
1205 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_2500
1206 * @tc.name : Performance test of capset and capget interface
1207 * @tc.desc : [C-SECURITY-0100]
1208 */
1209 HWTEST_F(CapabilityTestSuite, CapabilityTest2500, Performance | MediumTest | Level2)
1210 {
1211 int status = 0;
1212 // Preset action: Fork a sub process
1213 pid_t pid = fork();
1214 ASSERT_TRUE(pid >= 0) << "======== Fork Error! =========";
1215 usleep(SLEEP_NUM);
1216 if (pid == 0) {
1217 int exitCode = 0;
1218 struct timespec tp = { 0 };
1219 struct timespec starttime = { 0 };
1220 struct timespec endtime = { 0 };
1221 tp.tv_sec = 0;
1222 tp.tv_nsec = 0;
1223 // Preset action: Obtains the system time -> starttime
1224 clock_gettime(CLOCK_REALTIME, &starttime);
1225 // Step 1: Capset and capget for 200000 times
1226 for (int number = 0; number < NUM10000; number++) {
1227 CapsetOnlySETPCAP(number);
1228 AddCapUnauthorized(number);
1229 CapgetOnlySETPCAP(number);
1230 }
1231 // Step 2: Obtains the system time again -> endtime
1232 clock_gettime(CLOCK_REALTIME, &endtime);
1233 // Step 3: Compare the starttime and the endtime -> tp
1234 tp = CompareTime(starttime, endtime);
1235 if (tp.tv_sec > NUM20) {
1236 LOG("ErrInfo: Capset and capget for 200000 times used %d.%d s", tp.tv_sec, tp.tv_nsec);
1237 exitCode = 1;
1238 }
1239 // Step 4: Two sub processes exit with the exitCode
1240 exit(exitCode);
1241 } else {
1242 // Step 5: The parent process wait for the sub process to exit and obtain the exitCode
1243 waitpid(pid, &status, 0);
1244 EXPECT_NE(WIFEXITED(status), 0) << "ErrInfo: The sub process exit error, child_pid = " << pid;
1245 EXPECT_EQ(WEXITSTATUS(status), 0) << "ErrInfo: The exitCode is wrong, please query logs, child_pid = " << pid;
1246 }
1247 }
1248
1249 /*
1250 * @tc.number : SUB_SEC_AppSEC_PermissionMgmt_Capability_2600
1251 * @tc.name : Performance test of the interface managed by Capability
1252 * @tc.desc : [C-SECURITY-0100]
1253 */
1254 HWTEST_F(CapabilityTestSuite, CapabilityTest2600, Performance | MediumTest | Level2)
1255 {
1256 struct timespec tp = { 0 };
1257 struct timespec starttime = { 0 };
1258 struct timespec endtime = { 0 };
1259 tp.tv_sec = 0;
1260 tp.tv_nsec = 0;
1261 // Preset action: Create a txt
1262 CreateTxt();
1263 // Preset action: Obtains the system time -> starttime
1264 clock_gettime(CLOCK_REALTIME, &starttime);
1265 // Step 1: Chown for 10000 times
1266 for (int number = 0; number < NUM1000; number++) {
1267 chown(TOP_DIR "/" CAPDIR0 "/" CAPDIR0_CAPFILE0, number, number);
1268 }
1269 // Step 2: Obtains the system time again -> endtime
1270 clock_gettime(CLOCK_REALTIME, &endtime);
1271 // Step 3: Compare the starttime and the endtime -> tp
1272 tp = CompareTime(starttime, endtime);
1273 EXPECT_LE(tp.tv_sec, NUM80) << "ErrInfo: Chown for 1000 times used " << tp.tv_sec << "." << tp.tv_nsec << "s";
1274 // Cleanup action: Restore the initial status of the file
1275 chown(TOP_DIR "/" CAPDIR0 "/" CAPDIR0_CAPFILE0, UID0, GID0);
1276 }
1277 #endif
1278