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 <csignal>
17 #include <dirent.h>
18 #include <securec.h>
19 #include <sys/capability.h>
20 #include <unistd.h>
21
Sigac(int i)22 void Sigac(int i)
23 {
24 _exit(0);
25 }
26
ChildSleep()27 void ChildSleep()
28 {
29 signal(SIGXFSZ, Sigac);
30 usleep(LONG_SLEEP_NUM);
31 exit(0);
32 }
33
CapInit()34 int CapInit()
35 {
36 // Init capabilities
37 struct __user_cap_header_struct capheader;
38 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
39 capheader.version = _LINUX_CAPABILITY_VERSION_3;
40 capheader.pid = 0;
41 struct __user_cap_data_struct capdata[CAP_NUM];
42 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
43 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
44 capdata[0].permitted = LINUX_FULL_CAP;
45 capdata[0].effective = LINUX_FULL_CAP;
46 capdata[0].inheritable = LINUX_FULL_CAP;
47 // Set capabilities
48 int ret = capset(&capheader, &capdata[0]);
49 if (ret != 0) {
50 return FALSE;
51 }
52 return 0;
53 }
54
DropCAPCHOWN()55 int DropCAPCHOWN()
56 {
57 struct __user_cap_header_struct capheader = { 0 };
58 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
59 capheader.version = _LINUX_CAPABILITY_VERSION_3;
60 capheader.pid = 0;
61 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
62 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
63 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
64 // Drop the capabilities of CAP_CHOWN
65 capdata[CAP_TO_INDEX(CAP_CHOWN)].permitted &= ~CAP_TO_MASK(CAP_CHOWN);
66 capdata[CAP_TO_INDEX(CAP_CHOWN)].effective &= ~CAP_TO_MASK(CAP_CHOWN);
67 capdata[CAP_TO_INDEX(CAP_CHOWN)].inheritable &= ~CAP_TO_MASK(CAP_CHOWN);
68 int ret = capset(&capheader, &capdata[0]);
69 if (ret != 0) {
70 return FALSE;
71 }
72 return 0;
73 }
74
DropCAPDACOVERRIDE()75 int DropCAPDACOVERRIDE()
76 {
77 struct __user_cap_header_struct capheader = { 0, 0 };
78 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
79 capheader.version = _LINUX_CAPABILITY_VERSION_3;
80 capheader.pid = 0;
81 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
82 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
83 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
84 // Drop the capabilities of CAP_DAC_OVERRIDE
85 capdata[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].permitted &= ~CAP_TO_MASK(CAP_DAC_OVERRIDE);
86 capdata[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].effective &= ~CAP_TO_MASK(CAP_DAC_OVERRIDE);
87 capdata[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].inheritable &= ~CAP_TO_MASK(CAP_DAC_OVERRIDE);
88 int ret = capset(&capheader, &capdata[0]);
89 if (ret != 0) {
90 return FALSE;
91 }
92 return 0;
93 }
94
DropCAPDACREADSEARCH()95 int DropCAPDACREADSEARCH()
96 {
97 struct __user_cap_header_struct capheader = { 0, 0 };
98 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
99 capheader.version = _LINUX_CAPABILITY_VERSION_3;
100 capheader.pid = 0;
101 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
102 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
103 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
104 // Drop the capabilities of CAP_DAC_READ_SEARCH
105 capdata[CAP_TO_INDEX(CAP_DAC_READ_SEARCH)].permitted &= ~CAP_TO_MASK(CAP_DAC_READ_SEARCH);
106 capdata[CAP_TO_INDEX(CAP_DAC_READ_SEARCH)].effective &= ~CAP_TO_MASK(CAP_DAC_READ_SEARCH);
107 capdata[CAP_TO_INDEX(CAP_DAC_READ_SEARCH)].inheritable &= ~CAP_TO_MASK(CAP_DAC_READ_SEARCH);
108 int ret = capset(&capheader, &capdata[0]);
109 if (ret != 0) {
110 return FALSE;
111 }
112 return 0;
113 }
114
DropCAPDACOVERRIDEAndREADSEARCH()115 int DropCAPDACOVERRIDEAndREADSEARCH()
116 {
117 struct __user_cap_header_struct capheader = { 0, 0 };
118 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
119 capheader.version = _LINUX_CAPABILITY_VERSION_3;
120 capheader.pid = 0;
121 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
122 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
123 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
124 // Drop the capabilities of CAP_DAC_OVERRIDE and CAP_DAC_READ_SEARCH
125 capdata[CAP_TO_INDEX(CAP_DAC_READ_SEARCH)].permitted &= ~CAP_TO_MASK(CAP_DAC_READ_SEARCH);
126 capdata[CAP_TO_INDEX(CAP_DAC_READ_SEARCH)].effective &= ~CAP_TO_MASK(CAP_DAC_READ_SEARCH);
127 capdata[CAP_TO_INDEX(CAP_DAC_READ_SEARCH)].inheritable &= ~CAP_TO_MASK(CAP_DAC_READ_SEARCH);
128 capdata[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].permitted &= ~CAP_TO_MASK(CAP_DAC_OVERRIDE);
129 capdata[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].effective &= ~CAP_TO_MASK(CAP_DAC_OVERRIDE);
130 capdata[CAP_TO_INDEX(CAP_DAC_OVERRIDE)].inheritable &= ~CAP_TO_MASK(CAP_DAC_OVERRIDE);
131 int ret = capset(&capheader, &capdata[0]);
132 if (ret != 0) {
133 return FALSE;
134 }
135 return 0;
136 }
137
DropCAPFOWNER()138 int DropCAPFOWNER()
139 {
140 struct __user_cap_header_struct capheader = { 0, 0 };
141 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
142 capheader.version = _LINUX_CAPABILITY_VERSION_3;
143 capheader.pid = 0;
144 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
145 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
146 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
147 // Drop the capabilities of CAP_FOWNER
148 capdata[CAP_TO_INDEX(CAP_FOWNER)].permitted &= ~CAP_TO_MASK(CAP_FOWNER);
149 capdata[CAP_TO_INDEX(CAP_FOWNER)].effective &= ~CAP_TO_MASK(CAP_FOWNER);
150 capdata[CAP_TO_INDEX(CAP_FOWNER)].inheritable &= ~CAP_TO_MASK(CAP_FOWNER);
151 int ret = capset(&capheader, &capdata[0]);
152 if (ret != 0) {
153 return FALSE;
154 }
155 return 0;
156 }
157
DropCAPKILL()158 int DropCAPKILL()
159 {
160 struct __user_cap_header_struct capheader = { 0, 0 };
161 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
162 capheader.version = _LINUX_CAPABILITY_VERSION_3;
163 capheader.pid = 0;
164 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
165 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
166 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
167 // Drop the capabilities of CAP_KILL
168 capdata[CAP_TO_INDEX(CAP_KILL)].permitted &= ~CAP_TO_MASK(CAP_KILL);
169 capdata[CAP_TO_INDEX(CAP_KILL)].effective &= ~CAP_TO_MASK(CAP_KILL);
170 capdata[CAP_TO_INDEX(CAP_KILL)].inheritable &= ~CAP_TO_MASK(CAP_KILL);
171 int ret = capset(&capheader, &capdata[0]);
172 if (ret != 0) {
173 return FALSE;
174 }
175 return 0;
176 }
177
DropCAPSETGID()178 int DropCAPSETGID()
179 {
180 struct __user_cap_header_struct capheader = { 0, 0 };
181 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
182 capheader.version = _LINUX_CAPABILITY_VERSION_3;
183 capheader.pid = 0;
184 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
185 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
186 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
187 // Drop the capabilities of CAP_SETGID
188 capdata[CAP_TO_INDEX(CAP_SETGID)].permitted &= ~CAP_TO_MASK(CAP_SETGID);
189 capdata[CAP_TO_INDEX(CAP_SETGID)].effective &= ~CAP_TO_MASK(CAP_SETGID);
190 capdata[CAP_TO_INDEX(CAP_SETGID)].inheritable &= ~CAP_TO_MASK(CAP_SETGID);
191 int ret = capset(&capheader, &capdata[0]);
192 if (ret != 0) {
193 return FALSE;
194 }
195 return 0;
196 }
197
DropCAPSETUID()198 int DropCAPSETUID()
199 {
200 struct __user_cap_header_struct capheader = { 0, 0 };
201 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
202 capheader.version = _LINUX_CAPABILITY_VERSION_3;
203 capheader.pid = 0;
204 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
205 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
206 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
207 // Drop the capabilities of CAP_SETUID
208 capdata[CAP_TO_INDEX(CAP_SETUID)].permitted &= ~CAP_TO_MASK(CAP_SETUID);
209 capdata[CAP_TO_INDEX(CAP_SETUID)].effective &= ~CAP_TO_MASK(CAP_SETUID);
210 capdata[CAP_TO_INDEX(CAP_SETUID)].inheritable &= ~CAP_TO_MASK(CAP_SETUID);
211 int ret = capset(&capheader, &capdata[0]);
212 if (ret != 0) {
213 return FALSE;
214 }
215 return 0;
216 }
217
DropCAPSETPCAP()218 int DropCAPSETPCAP()
219 {
220 struct __user_cap_header_struct capheader = { 0, 0 };
221 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
222 capheader.version = _LINUX_CAPABILITY_VERSION_3;
223 capheader.pid = 0;
224 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
225 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
226 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
227 // Drop the capabilities of CAP_SETPCAP
228 capdata[CAP_TO_INDEX(CAP_SETPCAP)].permitted &= ~CAP_TO_MASK(CAP_SETPCAP);
229 capdata[CAP_TO_INDEX(CAP_SETPCAP)].effective &= ~CAP_TO_MASK(CAP_SETPCAP);
230 capdata[CAP_TO_INDEX(CAP_SETPCAP)].inheritable &= ~CAP_TO_MASK(CAP_SETPCAP);
231 int ret = capset(&capheader, &capdata[0]);
232 if (ret != 0) {
233 return FALSE;
234 }
235 return 0;
236 }
237
DropCAPSYSNICE()238 int DropCAPSYSNICE()
239 {
240 struct __user_cap_header_struct capheader = { 0, 0 };
241 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
242 capheader.version = _LINUX_CAPABILITY_VERSION_3;
243 capheader.pid = 0;
244 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
245 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
246 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
247 // Drop the capabilities of CAP_SYS_NICE
248 capdata[CAP_TO_INDEX(CAP_SYS_NICE)].permitted &= ~CAP_TO_MASK(CAP_SYS_NICE);
249 capdata[CAP_TO_INDEX(CAP_SYS_NICE)].effective &= ~CAP_TO_MASK(CAP_SYS_NICE);
250 capdata[CAP_TO_INDEX(CAP_SYS_NICE)].inheritable &= ~CAP_TO_MASK(CAP_SYS_NICE);
251 int ret = capset(&capheader, &capdata[0]);
252 if (ret != 0) {
253 return FALSE;
254 }
255 return 0;
256 }
257
DropCAPSYSTIME()258 int DropCAPSYSTIME()
259 {
260 struct __user_cap_header_struct capheader = { 0, 0 };
261 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
262 capheader.version = _LINUX_CAPABILITY_VERSION_3;
263 capheader.pid = 0;
264 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
265 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
266 0xff, CAP_NUM * sizeof(struct __user_cap_data_struct));
267 // Drop the capabilities of CAP_SYS_TIME
268 capdata[CAP_TO_INDEX(CAP_SYS_TIME)].permitted &= ~CAP_TO_MASK(CAP_SYS_TIME);
269 capdata[CAP_TO_INDEX(CAP_SYS_TIME)].effective &= ~CAP_TO_MASK(CAP_SYS_TIME);
270 capdata[CAP_TO_INDEX(CAP_SYS_TIME)].inheritable &= ~CAP_TO_MASK(CAP_SYS_TIME);
271 int ret = capset(&capheader, &capdata[0]);
272 if (ret != 0) {
273 return FALSE;
274 }
275 return 0;
276 }
277
DropAllCAP()278 int DropAllCAP()
279 {
280 struct __user_cap_header_struct capheader = { 0, 0 };
281 memset_s(&capheader, sizeof(struct __user_cap_header_struct), 0, sizeof(struct __user_cap_header_struct));
282 capheader.version = _LINUX_CAPABILITY_VERSION_3;
283 capheader.pid = 0;
284 struct __user_cap_data_struct capdata[CAP_NUM] = { { 0 }, { 0 } };
285 memset_s(capdata, CAP_NUM * sizeof(struct __user_cap_data_struct),
286 0, CAP_NUM * sizeof(struct __user_cap_data_struct));
287 // Drop all the capabilities
288 capdata[0].permitted = NO_CAP;
289 capdata[0].effective = NO_CAP;
290 capdata[0].inheritable = NO_CAP;
291 int ret = capset(&capheader, &capdata[0]);
292 if (ret != 0) {
293 return FALSE;
294 }
295 return 0;
296 }
297
RemoveDir(const char * dirname)298 int RemoveDir(const char *dirname)
299 {
300 int ret;
301 char curDir[] = ".";
302 char upDir[] = "..";
303 char updirname[SIZE512];
304 DIR *dir = nullptr;
305 struct dirent *dp = nullptr;
306 struct stat upDirStat = { 0 };
307 // Init capabilities
308 CapInit();
309 // The directory transferred by the parameter does not exist
310 if (access(dirname, F_OK != 0)) {
311 return 0;
312 } else {
313 chmod(dirname, RWX);
314 }
315 // Open the current-level directory
316 dir = opendir(dirname);
317 while ((dp = readdir(dir)) != nullptr) {
318 // The system skips the judgment and continues looping when the . or .. directory is encountered
319 if ((strcmp(curDir, dp->d_name) == 0) || (strcmp(upDir, dp->d_name) == 0)) {
320 continue;
321 }
322 // Combine the upper-level directory content
323 int spr = sprintf_s(updirname, SIZE512, "%s/%s", dirname, dp->d_name);
324 if (spr == FALSE) {
325 closedir(dir);
326 return FALSE;
327 }
328 // Obtains the status of the upper-level, file or directory
329 stat(updirname, &upDirStat);
330 // Directory files, recursively deleting contents in the directory
331 if (upDirStat.st_mode & S_IFDIR) {
332 // Invoke the function recursively to delete the content of the upper-level directory
333 RemoveDir(updirname);
334 } else {
335 // Common files, directly deleting
336 ret = unlink(updirname);
337 if (ret != 0) {
338 // Failed to delete the file
339 perror("Failed to delete the file");
340 LOG("ErrInfo: The file name is %s", updirname);
341 closedir(dir);
342 return FALSE;
343 }
344 }
345 }
346 // Close the current-level directory
347 closedir(dir);
348 // Delete the empty directory
349 ret = rmdir(dirname);
350 if (ret != 0) {
351 // Failed to delete the empty directory
352 perror("Failed to delete the empty directory");
353 LOG("ErrInfo: The directory name is %s", dirname);
354 return FALSE;
355 }
356 return 0;
357 }
358
SetUidGid(uid_t uid,gid_t gid)359 int SetUidGid(uid_t uid, gid_t gid)
360 {
361 // Set the process uid and gid
362 int retsetuid = setuid(uid);
363 if (retsetuid != 0) {
364 LOG("ErrInfo: Set uid=%d failed, now uid=%d", uid, getuid());
365 return FALSE;
366 }
367 int retsetgid = setgid(gid);
368 if (retsetgid != 0) {
369 LOG("ErrInfo: Set gid=%d failed, now gid=%d", gid, getgid());
370 return FALSE;
371 }
372 return 0;
373 }
374
CompareTime(timespec start,timespec end)375 timespec CompareTime(timespec start, timespec end)
376 {
377 // Compare time 'start' and time 'end'
378 timespec ret = { 0 };
379 int tp = 1000000000;
380 if ((end.tv_nsec - start.tv_nsec) < 0) {
381 ret.tv_sec = end.tv_sec - start.tv_sec - 1;
382 ret.tv_nsec = tp + end.tv_nsec - start.tv_nsec;
383 } else {
384 ret.tv_sec = end.tv_sec - start.tv_sec;
385 ret.tv_nsec = end.tv_nsec - start.tv_nsec;
386 }
387 return ret;
388 }
389
GetCurrentPath()390 char *GetCurrentPath()
391 {
392 // Obtain the current working directory
393 static char path[MAX_PATH_SIZE];
394 getcwd(path, MAX_PATH_SIZE);
395 return path;
396 }
397
398 // Check topDir file system, 0 is exist, -1 is non-exist
CheckFsMount(const char * topDir,const char * topDirMountInfo)399 int CheckFsMount(const char *topDir, const char *topDirMountInfo)
400 {
401 const int lenMax = 100;
402 int len;
403 char buf[lenMax] = {0};
404 const char mountInfoFile[] = "/proc/mounts";
405 // check topDir exist
406 if (access(topDir, F_OK) != 0) {
407 LOG("ErrInfo: '%s' not accessable, Test Stop!", topDir);
408 return -1;
409 }
410 FILE *fp = fopen(mountInfoFile, "r");
411 if (fp != nullptr) {
412 while (fgets(buf, sizeof(buf), fp) != NULL) {
413 len = strlen(buf);
414 if (strstr(buf, topDirMountInfo) != nullptr) {
415 fclose(fp);
416 return 0;
417 }
418 }
419 fclose(fp);
420 }
421 LOG("'%s' is not a '%s' not mount properly, Test Stop! please change another file type!", topDir, topDirMountInfo);
422 return -1;
423 }