• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }