• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 #undef _GNU_SOURCE
17 #define _GNU_SOURCE
18 #include <sched.h>
19 
20 #include "securec.h"
21 #include "appspawn_manager.h"
22 #include "appspawn_permission.h"
23 #include "appspawn_sandbox.h"
24 #include "appspawn_utils.h"
25 #include "modulemgr.h"
26 #include "parameter.h"
27 #include "sandbox_shared.h"
28 
FreePathMountNode(SandboxMountNode * node)29 static void FreePathMountNode(SandboxMountNode *node)
30 {
31     PathMountNode *sandboxNode = (PathMountNode *)node;
32     if (sandboxNode->source) {
33         free(sandboxNode->source);
34         sandboxNode->source = NULL;
35     }
36     if (sandboxNode->target) {
37         free(sandboxNode->target);
38         sandboxNode->target = NULL;
39     }
40     if (sandboxNode->appAplName) {
41         free(sandboxNode->appAplName);
42         sandboxNode->appAplName = NULL;
43     }
44     for (uint32_t i = 0; i < sandboxNode->decPolicyPaths.decPathCount; i++) {
45         if (sandboxNode->decPolicyPaths.decPath[i] != NULL) {
46             free(sandboxNode->decPolicyPaths.decPath[i]);
47             sandboxNode->decPolicyPaths.decPath[i] = NULL;
48         }
49     }
50     sandboxNode->decPolicyPaths.decPathCount = 0;
51     free(sandboxNode->decPolicyPaths.decPath);
52     sandboxNode->decPolicyPaths.decPath = NULL;
53     free(sandboxNode);
54 }
55 
FreeSymbolLinkNode(SandboxMountNode * node)56 static void FreeSymbolLinkNode(SandboxMountNode *node)
57 {
58     SymbolLinkNode *sandboxNode = (SymbolLinkNode *)node;
59     if (sandboxNode->target) {
60         free(sandboxNode->target);
61         sandboxNode->target = NULL;
62     }
63     if (sandboxNode->linkName) {
64         free(sandboxNode->linkName);
65         sandboxNode->linkName = NULL;
66     }
67     free(sandboxNode);
68 }
69 
SandboxNodeCompareProc(ListNode * node,ListNode * newNode)70 static int SandboxNodeCompareProc(ListNode *node, ListNode *newNode)
71 {
72     SandboxMountNode *sandbox1 = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node);
73     SandboxMountNode *sandbox2 = (SandboxMountNode *)ListEntry(newNode, SandboxMountNode, node);
74     return sandbox1->type - sandbox2->type;
75 }
76 
CreateSandboxMountNode(uint32_t dataLen,uint32_t type)77 SandboxMountNode *CreateSandboxMountNode(uint32_t dataLen, uint32_t type)
78 {
79     APPSPAWN_CHECK(dataLen >= sizeof(SandboxMountNode) && dataLen <= sizeof(PathMountNode),
80         return NULL, "Invalid dataLen %{public}u", dataLen);
81     SandboxMountNode *node = (SandboxMountNode *)calloc(1, dataLen);
82     APPSPAWN_CHECK(node != NULL, return NULL, "Failed to create mount node %{public}u", type);
83     OH_ListInit(&node->node);
84     node->type = type;
85     return node;
86 }
87 
AddSandboxMountNode(SandboxMountNode * node,SandboxSection * queue)88 void AddSandboxMountNode(SandboxMountNode *node, SandboxSection *queue)
89 {
90     APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return);
91     APPSPAWN_CHECK_ONLY_EXPER(queue != NULL, return);
92     OH_ListAddWithOrder(&queue->front, &node->node, SandboxNodeCompareProc);
93 }
94 
PathMountNodeCompare(ListNode * node,void * data)95 static int PathMountNodeCompare(ListNode *node, void *data)
96 {
97     PathMountNode *node1 = (PathMountNode *)ListEntry(node, SandboxMountNode, node);
98     PathMountNode *node2 = (PathMountNode *)data;
99     return (node1->sandboxNode.type == node2->sandboxNode.type) &&
100         (strcmp(node1->source, node2->source) == 0) &&
101         (strcmp(node1->target, node2->target) == 0) ? 0 : 1;
102 }
103 
SymbolLinkNodeCompare(ListNode * node,void * data)104 static int SymbolLinkNodeCompare(ListNode *node, void *data)
105 {
106     SymbolLinkNode *node1 = (SymbolLinkNode *)ListEntry(node, SandboxMountNode, node);
107     SymbolLinkNode *node2 = (SymbolLinkNode *)data;
108     return (node1->sandboxNode.type == node2->sandboxNode.type) &&
109         (strcmp(node1->target, node2->target) == 0) &&
110         (strcmp(node1->linkName, node2->linkName) == 0) ? 0 : 1;
111 }
112 
GetPathMountNode(const SandboxSection * section,int type,const char * source,const char * target)113 PathMountNode *GetPathMountNode(const SandboxSection *section, int type, const char *source, const char *target)
114 {
115     APPSPAWN_CHECK_ONLY_EXPER(section != NULL, return NULL);
116     APPSPAWN_CHECK_ONLY_EXPER(source != NULL && target != NULL, return NULL);
117     PathMountNode pathNode = {};
118     pathNode.sandboxNode.type = type;
119     pathNode.source = (char *)source;
120     pathNode.target = (char *)target;
121     ListNode *node = OH_ListFind(&section->front, (void *)&pathNode, PathMountNodeCompare);
122     if (node == NULL) {
123         return NULL;
124     }
125     return (PathMountNode *)ListEntry(node, SandboxMountNode, node);
126 }
127 
GetSymbolLinkNode(const SandboxSection * section,const char * target,const char * linkName)128 SymbolLinkNode *GetSymbolLinkNode(const SandboxSection *section, const char *target, const char *linkName)
129 {
130     APPSPAWN_CHECK_ONLY_EXPER(section != NULL, return NULL);
131     APPSPAWN_CHECK_ONLY_EXPER(linkName != NULL && target != NULL, return NULL);
132     SymbolLinkNode linkNode = {};
133     linkNode.sandboxNode.type = SANDBOX_TAG_SYMLINK;
134     linkNode.target = (char *)target;
135     linkNode.linkName = (char *)linkName;
136     ListNode *node = OH_ListFind(&section->front, (void *)&linkNode, SymbolLinkNodeCompare);
137     if (node == NULL) {
138         return NULL;
139     }
140     return (SymbolLinkNode *)ListEntry(node, SandboxMountNode, node);
141 }
142 
DeleteSandboxMountNode(SandboxMountNode * sandboxNode)143 void DeleteSandboxMountNode(SandboxMountNode *sandboxNode)
144 {
145     APPSPAWN_CHECK_ONLY_EXPER(sandboxNode != NULL, return);
146     OH_ListRemove(&sandboxNode->node);
147     OH_ListInit(&sandboxNode->node);
148     switch (sandboxNode->type) {
149         case SANDBOX_TAG_MOUNT_PATH:
150         case SANDBOX_TAG_MOUNT_FILE:
151             FreePathMountNode(sandboxNode);
152             break;
153         case SANDBOX_TAG_SYMLINK:
154             FreeSymbolLinkNode(sandboxNode);
155             break;
156         default:
157             APPSPAWN_LOGE("Invalid type %{public}u", sandboxNode->type);
158             free(sandboxNode);
159             break;
160     }
161 }
162 
GetFirstSandboxMountNode(const SandboxSection * section)163 SandboxMountNode *GetFirstSandboxMountNode(const SandboxSection *section)
164 {
165     if (section == NULL || ListEmpty(section->front)) {
166         return NULL;
167     }
168     return (SandboxMountNode *)ListEntry(section->front.next, SandboxMountNode, node);
169 }
170 
DumpSandboxMountNode(const SandboxMountNode * sandboxNode,uint32_t index)171 void DumpSandboxMountNode(const SandboxMountNode *sandboxNode, uint32_t index)
172 {
173     APPSPAWN_CHECK_ONLY_EXPER(sandboxNode != NULL, return);
174     switch (sandboxNode->type) {
175         case SANDBOX_TAG_MOUNT_PATH:
176         case SANDBOX_TAG_MOUNT_FILE: {
177             PathMountNode *pathNode = (PathMountNode *)sandboxNode;
178             APPSPAWN_DUMP("        ****************************** %{public}u", index);
179             APPSPAWN_DUMP("        sandbox node source: %{public}s", pathNode->source ? pathNode->source : "null");
180             APPSPAWN_DUMP("        sandbox node target: %{public}s", pathNode->target ? pathNode->target : "null");
181             DumpMountPathMountNode(pathNode);
182             APPSPAWN_DUMP("        sandbox node apl: %{public}s",
183                 pathNode->appAplName ? pathNode->appAplName : "null");
184             APPSPAWN_DUMP("        sandbox node checkErrorFlag: %{public}s",
185                 pathNode->checkErrorFlag ? "true" : "false");
186             break;
187         }
188         case SANDBOX_TAG_SYMLINK: {
189             SymbolLinkNode *linkNode = (SymbolLinkNode *)sandboxNode;
190             APPSPAWN_DUMP("        ***********************************");
191             APPSPAWN_DUMP("        sandbox node target: %{public}s", linkNode->target ? linkNode->target : "null");
192             APPSPAWN_DUMP("        sandbox node linkName: %{public}s",
193                 linkNode->linkName ? linkNode->linkName : "null");
194             APPSPAWN_DUMP("        sandbox node destMode: %{public}x", linkNode->destMode);
195             APPSPAWN_DUMP("        sandbox node checkErrorFlag: %{public}s",
196                 linkNode->checkErrorFlag ? "true" : "false");
197             break;
198         }
199         default:
200             break;
201     }
202 }
203 
InitSandboxSection(SandboxSection * section,int type)204 static inline void InitSandboxSection(SandboxSection *section, int type)
205 {
206     OH_ListInit(&section->front);
207     section->sandboxSwitch = 0;
208     section->sandboxShared = 0;
209     section->number = 0;
210     section->gidCount = 0;
211     section->gidTable = NULL;
212     section->nameGroups = NULL;
213     section->name = NULL;
214     OH_ListInit(&section->sandboxNode.node);
215     section->sandboxNode.type = type;
216 }
217 
ClearSandboxSection(SandboxSection * section)218 static void ClearSandboxSection(SandboxSection *section)
219 {
220     if (section->gidTable) {
221         free(section->gidTable);
222         section->gidTable = NULL;
223     }
224     // free name group
225     if (section->nameGroups) {
226         free(section->nameGroups);
227         section->nameGroups = NULL;
228     }
229     if (section->name) {
230         free(section->name);
231         section->name = NULL;
232     }
233     if (section->sandboxNode.type == SANDBOX_TAG_NAME_GROUP) {
234         SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)section;
235         if (groupNode->depNode) {
236             DeleteSandboxMountNode((SandboxMountNode *)groupNode->depNode);
237         }
238     }
239     // free mount path
240     ListNode *node = section->front.next;
241     while (node != &section->front) {
242         SandboxMountNode *sandboxNode = ListEntry(node, SandboxMountNode, node);
243         // delete node
244         OH_ListRemove(&sandboxNode->node);
245         OH_ListInit(&sandboxNode->node);
246         DeleteSandboxMountNode(sandboxNode);
247         // get next
248         node = section->front.next;
249     }
250 }
251 
DumpSandboxQueue(const ListNode * front,void (* dumpSandboxMountNode)(const SandboxMountNode * node,uint32_t count))252 static void DumpSandboxQueue(const ListNode *front,
253     void (*dumpSandboxMountNode)(const SandboxMountNode *node, uint32_t count))
254 {
255     uint32_t count = 0;
256     ListNode *node = front->next;
257     while (node != front) {
258         SandboxMountNode *sandboxNode = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node);
259         count++;
260         dumpSandboxMountNode(sandboxNode, count);
261         // get next
262         node = node->next;
263     }
264 }
265 
DumpSandboxSection(const SandboxSection * section)266 static void DumpSandboxSection(const SandboxSection *section)
267 {
268     APPSPAWN_DUMP("    sandboxSwitch %{public}s", section->sandboxSwitch ? "true" : "false");
269     APPSPAWN_DUMP("    sandboxShared %{public}s", section->sandboxShared ? "true" : "false");
270     APPSPAWN_DUMP("    gidCount: %{public}u", section->gidCount);
271     for (uint32_t index = 0; index < section->gidCount; index++) {
272         APPSPAWN_DUMP("        gidTable[%{public}u]: %{public}u", index, section->gidTable[index]);
273     }
274     APPSPAWN_DUMP("    mount group count: %{public}u", section->number);
275     for (uint32_t i = 0; i < section->number; i++) {
276         if (section->nameGroups[i]) {
277             SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)section->nameGroups[i];
278             APPSPAWN_DUMP("        name[%{public}d] %{public}s", i, groupNode->section.name);
279         }
280     }
281     APPSPAWN_DUMP("    mount-paths: ");
282     DumpSandboxQueue(&section->front, DumpSandboxMountNode);
283 }
284 
CreateSandboxSection(const char * name,uint32_t dataLen,uint32_t type)285 SandboxSection *CreateSandboxSection(const char *name, uint32_t dataLen, uint32_t type)
286 {
287     APPSPAWN_CHECK(type < SANDBOX_TAG_INVALID && type >= SANDBOX_TAG_PERMISSION,
288         return NULL, "Invalid type %{public}u", type);
289     APPSPAWN_CHECK(name != NULL && strlen(name) > 0, return NULL, "Invalid name %{public}u", type);
290     APPSPAWN_CHECK(dataLen >= sizeof(SandboxSection), return NULL, "Invalid dataLen %{public}u", dataLen);
291     APPSPAWN_CHECK(dataLen <= sizeof(SandboxNameGroupNode), return NULL, "Invalid dataLen %{public}u", dataLen);
292     SandboxSection *section = (SandboxSection *)calloc(1, dataLen);
293     APPSPAWN_CHECK(section != NULL, return NULL, "Failed to create base node");
294     InitSandboxSection(section, type);
295     section->name = strdup(name);
296     if (section->name == NULL) {
297         ClearSandboxSection(section);
298         free(section);
299         return NULL;
300     }
301     return section;
302 }
303 
SandboxConditionalNodeCompareName(ListNode * node,void * data)304 static int SandboxConditionalNodeCompareName(ListNode *node, void *data)
305 {
306     SandboxSection *tmpNode = (SandboxSection *)ListEntry(node, SandboxMountNode, node);
307     return strcmp(tmpNode->name, (char *)data);
308 }
309 
SandboxConditionalNodeCompareNode(ListNode * node,ListNode * newNode)310 static int SandboxConditionalNodeCompareNode(ListNode *node, ListNode *newNode)
311 {
312     SandboxSection *tmpNode = (SandboxSection *)ListEntry(node, SandboxMountNode, node);
313     SandboxSection *tmpNewNode = (SandboxSection *)ListEntry(newNode, SandboxMountNode, node);
314     return strcmp(tmpNode->name, tmpNewNode->name);
315 }
316 
GetSandboxSection(const SandboxQueue * queue,const char * name)317 SandboxSection *GetSandboxSection(const SandboxQueue *queue, const char *name)
318 {
319     APPSPAWN_CHECK_ONLY_EXPER(name != NULL && queue != NULL, return NULL);
320     ListNode *node = OH_ListFind(&queue->front, (void *)name, SandboxConditionalNodeCompareName);
321     if (node == NULL) {
322         return NULL;
323     }
324     return (SandboxSection *)ListEntry(node, SandboxMountNode, node);
325 }
326 
AddSandboxSection(SandboxSection * node,SandboxQueue * queue)327 void AddSandboxSection(SandboxSection *node, SandboxQueue *queue)
328 {
329     APPSPAWN_CHECK_ONLY_EXPER(node != NULL && queue != NULL, return);
330     if (ListEmpty(node->sandboxNode.node)) {
331         OH_ListAddWithOrder(&queue->front, &node->sandboxNode.node, SandboxConditionalNodeCompareNode);
332     }
333 }
334 
DeleteSandboxSection(SandboxSection * section)335 void DeleteSandboxSection(SandboxSection *section)
336 {
337     APPSPAWN_CHECK_ONLY_EXPER(section != NULL, return);
338     // delete node
339     OH_ListRemove(&section->sandboxNode.node);
340     OH_ListInit(&section->sandboxNode.node);
341     ClearSandboxSection(section);
342     free(section);
343 }
344 
SandboxQueueClear(SandboxQueue * queue)345 static void SandboxQueueClear(SandboxQueue *queue)
346 {
347     ListNode *node = queue->front.next;
348     while (node != &queue->front) {
349         SandboxSection *sandboxNode = (SandboxSection *)ListEntry(node, SandboxMountNode, node);
350         DeleteSandboxSection(sandboxNode);
351         // get first
352         node = queue->front.next;
353     }
354 }
355 
AppSpawnExtDataCompareDataId(ListNode * node,void * data)356 static int AppSpawnExtDataCompareDataId(ListNode *node, void *data)
357 {
358     AppSpawnExtData *extData = (AppSpawnExtData *)ListEntry(node, AppSpawnExtData, node);
359     return extData->dataId - *(uint32_t *)data;
360 }
361 
GetAppSpawnSandbox(const AppSpawnMgr * content,ExtDataType type)362 AppSpawnSandboxCfg *GetAppSpawnSandbox(const AppSpawnMgr *content, ExtDataType type)
363 {
364     APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return NULL);
365     uint32_t dataId = type;
366     ListNode *node = OH_ListFind(&content->extData, (void *)&dataId, AppSpawnExtDataCompareDataId);
367     if (node == NULL) {
368         return NULL;
369     }
370     return (AppSpawnSandboxCfg *)ListEntry(node, AppSpawnSandboxCfg, extData);
371 }
372 
DeleteAppSpawnSandbox(AppSpawnSandboxCfg * sandbox)373 void DeleteAppSpawnSandbox(AppSpawnSandboxCfg *sandbox)
374 {
375     APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return);
376     APPSPAWN_LOGV("DeleteAppSpawnSandbox");
377     OH_ListRemove(&sandbox->extData.node);
378     OH_ListInit(&sandbox->extData.node);
379 
380     // delete all queue
381     SandboxQueueClear(&sandbox->requiredQueue);
382     SandboxQueueClear(&sandbox->permissionQueue);
383     SandboxQueueClear(&sandbox->packageNameQueue);
384     SandboxQueueClear(&sandbox->spawnFlagsQueue);
385     SandboxQueueClear(&sandbox->nameGroupsQueue);
386     if (sandbox->rootPath) {
387         free(sandbox->rootPath);
388     }
389     free(sandbox->depGroupNodes);
390     sandbox->depGroupNodes = NULL;
391     free(sandbox);
392     sandbox = NULL;
393 }
394 
DumpSandboxPermission(const SandboxMountNode * node,uint32_t index)395 static void DumpSandboxPermission(const SandboxMountNode *node, uint32_t index)
396 {
397     SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)node;
398     APPSPAWN_DUMP("    ========================================= ");
399     APPSPAWN_DUMP("    Section %{public}s", permissionNode->section.name);
400     APPSPAWN_DUMP("    Section permission index %{public}d", permissionNode->permissionIndex);
401     DumpSandboxSection(&permissionNode->section);
402 }
403 
DumpSandboxSectionNode(const SandboxMountNode * node,uint32_t index)404 static void DumpSandboxSectionNode(const SandboxMountNode *node, uint32_t index)
405 {
406     SandboxSection *section = (SandboxSection *)node;
407     APPSPAWN_DUMP("    ========================================= ");
408     APPSPAWN_DUMP("    Section %{public}s", section->name);
409     DumpSandboxSection(section);
410 }
411 
DumpSandboxNameGroupNode(const SandboxMountNode * node,uint32_t index)412 static void DumpSandboxNameGroupNode(const SandboxMountNode *node, uint32_t index)
413 {
414     SandboxNameGroupNode *nameGroupNode = (SandboxNameGroupNode *)node;
415     APPSPAWN_DUMP("    ========================================= ");
416     APPSPAWN_DUMP("    Section %{public}s", nameGroupNode->section.name);
417     APPSPAWN_DUMP("    Section dep mode %{public}s",
418         nameGroupNode->depMode == MOUNT_MODE_ALWAYS ? "always" : "not-exists");
419     if (nameGroupNode->depNode != NULL) {
420         APPSPAWN_DUMP("    mount-paths-deps: ");
421         DumpMountPathMountNode(nameGroupNode->depNode);
422     }
423     DumpSandboxSection(&nameGroupNode->section);
424 }
425 
426 
DumpSandbox(struct TagAppSpawnExtData * data)427 static void DumpSandbox(struct TagAppSpawnExtData *data)
428 {
429     AppSpawnSandboxCfg *sandbox = (AppSpawnSandboxCfg *)data;
430     DumpAppSpawnSandboxCfg(sandbox);
431 }
432 
InitSandboxQueue(SandboxQueue * queue,uint32_t type)433 static inline void InitSandboxQueue(SandboxQueue *queue, uint32_t type)
434 {
435     OH_ListInit(&queue->front);
436     queue->type = type;
437 }
438 
FreeAppSpawnSandbox(struct TagAppSpawnExtData * data)439 static void FreeAppSpawnSandbox(struct TagAppSpawnExtData *data)
440 {
441     AppSpawnSandboxCfg *sandbox = ListEntry(data, AppSpawnSandboxCfg, extData);
442     // delete all var
443     DeleteAppSpawnSandbox(sandbox);
444 }
445 
CreateAppSpawnSandbox(ExtDataType type)446 AppSpawnSandboxCfg *CreateAppSpawnSandbox(ExtDataType type)
447 {
448     // create sandbox
449     AppSpawnSandboxCfg *sandbox = (AppSpawnSandboxCfg *)calloc(1, sizeof(AppSpawnSandboxCfg));
450     APPSPAWN_CHECK(sandbox != NULL, return NULL, "Failed to create sandbox");
451 
452     // ext data init
453     OH_ListInit(&sandbox->extData.node);
454     sandbox->extData.dataId = type;
455     sandbox->extData.freeNode = FreeAppSpawnSandbox;
456     sandbox->extData.dumpNode = DumpSandbox;
457 
458     // queue
459     InitSandboxQueue(&sandbox->requiredQueue, SANDBOX_TAG_REQUIRED);
460     InitSandboxQueue(&sandbox->permissionQueue, SANDBOX_TAG_PERMISSION);
461     InitSandboxQueue(&sandbox->packageNameQueue, SANDBOX_TAG_PACKAGE_NAME);
462     InitSandboxQueue(&sandbox->spawnFlagsQueue, SANDBOX_TAG_SPAWN_FLAGS);
463     InitSandboxQueue(&sandbox->nameGroupsQueue, SANDBOX_TAG_NAME_GROUP);
464 
465     sandbox->topSandboxSwitch = 0;
466     sandbox->appFullMountEnable = 0;
467     sandbox->topSandboxSwitch = 0;
468     sandbox->pidNamespaceSupport = 0;
469     sandbox->sandboxNsFlags = 0;
470     sandbox->maxPermissionIndex = -1;
471     sandbox->depNodeCount = 0;
472     sandbox->depGroupNodes = NULL;
473 
474     AddDefaultVariable();
475     AddDefaultExpandAppSandboxConfigHandle();
476     return sandbox;
477 }
478 
DumpAppSpawnSandboxCfg(AppSpawnSandboxCfg * sandbox)479 void DumpAppSpawnSandboxCfg(AppSpawnSandboxCfg *sandbox)
480 {
481     APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return);
482     APPSPAWN_DUMP("Sandbox root path: %{public}s", sandbox->rootPath);
483     APPSPAWN_DUMP("Sandbox sandboxNsFlags: %{public}x ", sandbox->sandboxNsFlags);
484     APPSPAWN_DUMP("Sandbox topSandboxSwitch: %{public}s", sandbox->topSandboxSwitch ? "true" : "false");
485     APPSPAWN_DUMP("Sandbox appFullMountEnable: %{public}s", sandbox->appFullMountEnable ? "true" : "false");
486     APPSPAWN_DUMP("Sandbox pidNamespaceSupport: %{public}s", sandbox->pidNamespaceSupport ? "true" : "false");
487     APPSPAWN_DUMP("Sandbox common info: ");
488     DumpSandboxQueue(&sandbox->requiredQueue.front, DumpSandboxSectionNode);
489     DumpSandboxQueue(&sandbox->packageNameQueue.front, DumpSandboxSectionNode);
490     DumpSandboxQueue(&sandbox->permissionQueue.front, DumpSandboxPermission);
491     DumpSandboxQueue(&sandbox->spawnFlagsQueue.front, DumpSandboxSectionNode);
492     DumpSandboxQueue(&sandbox->nameGroupsQueue.front, DumpSandboxNameGroupNode);
493 }
494 
PreLoadSandboxCfgByType(AppSpawnMgr * content,ExtDataType type)495 static int PreLoadSandboxCfgByType(AppSpawnMgr *content, ExtDataType type)
496 {
497     if (type >= EXT_DATA_COUNT || type < EXT_DATA_APP_SANDBOX) {
498         return APPSPAWN_ARG_INVALID;
499     }
500 
501     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, type);
502     APPSPAWN_CHECK(sandbox == NULL, return 0, "type %{public}d sandbox has been load", type);
503 
504     sandbox = CreateAppSpawnSandbox(type);
505     APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return APPSPAWN_SYSTEM_ERROR);
506     OH_ListAddTail(&content->extData, &sandbox->extData.node);
507 
508     // load sandbox config by type
509     LoadAppSandboxConfig(sandbox, type);
510     sandbox->maxPermissionIndex = PermissionRenumber(&sandbox->permissionQueue);
511 
512     content->content.sandboxNsFlags = 0;
513     if (IsNWebSpawnMode(content) || sandbox->pidNamespaceSupport) {
514         content->content.sandboxNsFlags = sandbox->sandboxNsFlags;
515     }
516     return 0;
517 }
518 
PreLoadDebugSandboxCfg(AppSpawnMgr * content)519 APPSPAWN_STATIC int PreLoadDebugSandboxCfg(AppSpawnMgr *content)
520 {
521     if (IsNWebSpawnMode(content)) {
522         return 0;
523     }
524 
525     int ret = PreLoadSandboxCfgByType(content, EXT_DATA_DEBUG_HAP_SANDBOX);
526     APPSPAWN_CHECK(ret == 0, return ret, "debug hap sandbox cfg preload failed");
527     return 0;
528 }
529 
PreLoadIsoLatedSandboxCfg(AppSpawnMgr * content)530 APPSPAWN_STATIC int PreLoadIsoLatedSandboxCfg(AppSpawnMgr *content)
531 {
532     if (IsNWebSpawnMode(content)) {
533         return 0;
534     }
535 
536     int ret = PreLoadSandboxCfgByType(content, EXT_DATA_ISOLATED_SANDBOX);
537     APPSPAWN_CHECK(ret == 0, return ret, "isolated sandbox cfg preload failed");
538     return 0;
539 }
540 
PreLoadAppSandboxCfg(AppSpawnMgr * content)541 APPSPAWN_STATIC int PreLoadAppSandboxCfg(AppSpawnMgr *content)
542 {
543     if (IsNWebSpawnMode(content)) {
544         return 0;
545     }
546 
547     int ret = PreLoadSandboxCfgByType(content, EXT_DATA_APP_SANDBOX);
548     APPSPAWN_CHECK(ret == 0, return ret, "app sandbox cfg preload failed");
549     return 0;
550 }
551 
PreLoadNWebSandboxCfg(AppSpawnMgr * content)552 APPSPAWN_STATIC int PreLoadNWebSandboxCfg(AppSpawnMgr *content)
553 {
554     if (IsNWebSpawnMode(content)) {
555         int ret = PreLoadSandboxCfgByType(content, EXT_DATA_RENDER_SANDBOX);
556         APPSPAWN_CHECK(ret == 0, return ret, "render sandbox cfg preload failed");
557 
558         ret = PreLoadSandboxCfgByType(content, EXT_DATA_GPU_SANDBOX);
559         APPSPAWN_CHECK(ret == 0, return ret, "gpu sandbox cfg preload failed");
560     }
561     return 0;
562 }
563 
IsolatedSandboxHandleServerExit(AppSpawnMgr * content)564 APPSPAWN_STATIC int IsolatedSandboxHandleServerExit(AppSpawnMgr *content)
565 {
566     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_ISOLATED_SANDBOX);
567     APPSPAWN_CHECK(sandbox != NULL, return 0, "Isolated sandbox not load");
568 
569     return 0;
570 }
571 
SandboxHandleServerExit(AppSpawnMgr * content)572 APPSPAWN_STATIC int SandboxHandleServerExit(AppSpawnMgr *content)
573 {
574     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_APP_SANDBOX);
575     APPSPAWN_CHECK(sandbox != NULL, return 0, "Sandbox not load");
576 
577     return 0;
578 }
579 
GetSandboxType(AppSpawnMgr * content,AppSpawningCtx * property)580 static ExtDataType GetSandboxType(AppSpawnMgr *content, AppSpawningCtx *property)
581 {
582     ExtDataType type = EXT_DATA_APP_SANDBOX;
583     if (IsNWebSpawnMode(content)) {
584         char *processType = (char *)GetAppPropertyExt(property, MSG_EXT_NAME_PROCESS_TYPE, NULL);
585         APPSPAWN_CHECK(processType != NULL, return type, "Invalid processType data");
586         if (strcmp(processType, "render") == 0) {
587             type = EXT_DATA_RENDER_SANDBOX;
588         } else if (strcmp(processType, "gpu") == 0) {
589             type = EXT_DATA_GPU_SANDBOX;
590         }
591     } else {
592         type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? EXT_DATA_ISOLATED_SANDBOX :
593                                                                                 EXT_DATA_APP_SANDBOX;
594     }
595     return type;
596 }
597 
598 /**
599  * 构建沙箱环境有以下条件
600  * 1.如果是孵化普通hap,ExtDataType为EXT_DATA_APP_SANDBOX
601  * 2.如果是孵化普通hap且hap中携带APP_FLAGS_ISOLATED_SANDBOX_TYPE标志位,ExtDataType为EXT_DATA_ISOLATED_SANDBOX
602  * 3.如果是孵化render进程,ExtDataType为EXT_DATA_RENDER_SANDBOX
603  * 4.如果是孵化gpu进程,ExtDataType为EXT_DATA_GPU_SANDBOX
604  * 5.如果孵化hap过程中,携带APP_FLAG_DEBUGABLE标志位同时开启了开发者模式,需增量配置ExtDataType为EXT_DATA_DEBUG_HAP_SANDBOX
605  */
606 
SpawnBuildSandboxEnv(AppSpawnMgr * content,AppSpawningCtx * property)607 static int SpawnBuildSandboxEnv(AppSpawnMgr *content, AppSpawningCtx *property)
608 {
609     // Don't build sandbox env
610     if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) {
611         return 0;
612     }
613 
614     ExtDataType type = GetSandboxType(content, property);
615     AppSpawnSandboxCfg *appSandbox = GetAppSpawnSandbox(content, type);
616     APPSPAWN_CHECK(appSandbox != NULL, return APPSPAWN_SANDBOX_INVALID, "Failed to get sandbox for %{public}s",
617                    GetProcessName(property));
618     content->content.sandboxType = type;
619 
620     // CLONE_NEWPID 0x20000000
621     // CLONE_NEWNET 0x40000000
622     if ((content->content.sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID) {
623         int ret = getprocpid();
624         if (ret < 0) {
625             APPSPAWN_LOGE("getprocpid failed, ret: %{public}d errno: %{public}d", ret, errno);
626             return ret;
627         }
628     }
629     int ret = MountSandboxConfigs(appSandbox, property, IsNWebSpawnMode(content));
630     appSandbox->mounted = 1;
631     // for module test do not create sandbox, use APP_FLAGS_IGNORE_SANDBOX to ignore sandbox result
632     if (CheckAppMsgFlagsSet(property, APP_FLAGS_IGNORE_SANDBOX)) {
633         APPSPAWN_LOGW("Do not care sandbox result %{public}d", ret);
634         return 0;
635     }
636     return ret == 0 ? 0 : APPSPAWN_SANDBOX_MOUNT_FAIL;
637 }
638 
AppendPermissionGid(const AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)639 static int AppendPermissionGid(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
640 {
641     AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
642     APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
643         "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
644 
645     APPSPAWN_LOGV("AppendPermissionGid %{public}s", GetProcessName(property));
646     ListNode *node = sandbox->permissionQueue.front.next;
647     while (node != &sandbox->permissionQueue.front) {
648         SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
649         if (!CheckAppPermissionFlagSet(property, (uint32_t)permissionNode->permissionIndex)) {
650             node = node->next;
651             continue;
652         }
653         if (permissionNode->section.gidCount == 0) {
654             node = node->next;
655             continue;
656         }
657         APPSPAWN_LOGV("Add permission %{public}s gid %{public}d to %{public}s",
658             permissionNode->section.name, permissionNode->section.gidTable[0], GetProcessName(property));
659 
660         size_t copyLen = permissionNode->section.gidCount;
661         if ((permissionNode->section.gidCount + dacInfo->gidCount) > APP_MAX_GIDS) {
662             APPSPAWN_LOGW("More gid for %{public}s msg count %{public}u permission %{public}u",
663                 GetProcessName(property), dacInfo->gidCount, permissionNode->section.gidCount);
664             copyLen = APP_MAX_GIDS - dacInfo->gidCount;
665         }
666         int ret = memcpy_s(&dacInfo->gidTable[dacInfo->gidCount], sizeof(gid_t) * copyLen,
667             permissionNode->section.gidTable, sizeof(gid_t) * copyLen);
668         if (ret != EOK) {
669             APPSPAWN_LOGW("Failed to append permission %{public}s gid to %{public}s",
670                 permissionNode->section.name, GetProcessName(property));
671             node = node->next;
672             continue;
673         }
674         dacInfo->gidCount += copyLen;
675         node = node->next;
676     }
677     return 0;
678 }
679 
AppendPackageNameGids(const AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)680 static int AppendPackageNameGids(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
681 {
682     AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
683     APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
684         "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
685 
686     SandboxPackageNameNode *sandboxNode =
687         (SandboxPackageNameNode *)GetSandboxSection(&sandbox->packageNameQueue, GetProcessName(property));
688     if (sandboxNode == NULL || sandboxNode->section.gidCount == 0) {
689         return 0;
690     }
691 
692     size_t copyLen = sandboxNode->section.gidCount;
693     if ((sandboxNode->section.gidCount + dacInfo->gidCount) > APP_MAX_GIDS) {
694         APPSPAWN_LOGW("More gid for %{public}s msg count %{public}u permission %{public}u",
695                       GetProcessName(property),
696                       dacInfo->gidCount,
697                       sandboxNode->section.gidCount);
698         copyLen = APP_MAX_GIDS - dacInfo->gidCount;
699     }
700     int ret = memcpy_s(&dacInfo->gidTable[dacInfo->gidCount], sizeof(gid_t) * copyLen,
701                        sandboxNode->section.gidTable, sizeof(gid_t) * copyLen);
702     if (ret != EOK) {
703         APPSPAWN_LOGW("Failed to append permission %{public}s gid to %{public}s",
704                       sandboxNode->section.name,
705                       GetProcessName(property));
706     }
707     dacInfo->gidCount += copyLen;
708 
709     return 0;
710 }
711 
UpdateMsgFlagsWithPermission(AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property,const char * permissionMode,uint32_t flag)712 static void UpdateMsgFlagsWithPermission(AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property,
713     const char *permissionMode, uint32_t flag)
714 {
715     int32_t processIndex = GetPermissionIndexInQueue(&sandbox->permissionQueue, permissionMode);
716     int res = CheckAppPermissionFlagSet(property, (uint32_t)processIndex);
717     if (res == 0) {
718         APPSPAWN_LOGV("Don't need set %{public}s flag", permissionMode);
719         return;
720     }
721 
722     int ret = SetAppSpawnMsgFlag(property->message, TLV_MSG_FLAGS, flag);
723     if (ret != 0) {
724         APPSPAWN_LOGE("Set %{public}s flag failed", permissionMode);
725     }
726     return;
727 }
728 
UpdatePermissionFlags(AppSpawnMgr * content,AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)729 static int UpdatePermissionFlags(AppSpawnMgr *content, AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
730 {
731     if (IsNWebSpawnMode(content)) {
732         return 0;
733     }
734 
735     int32_t index = 0;
736     if (sandbox->appFullMountEnable) {
737         index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_CROSS_APP_MODE);
738     } else {
739         index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_ACCESS_COMMON_DIR_MODE);
740     }
741 
742     int32_t fileMgrIndex = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_ACCESS_MANAGER_MODE);
743     int32_t userFileIndex = GetPermissionIndexInQueue(&sandbox->permissionQueue, READ_WRITE_USER_FILE_MODE);
744     int fileMgrRes = CheckAppPermissionFlagSet(property, (uint32_t)fileMgrIndex);
745     int userFileRes = CheckAppPermissionFlagSet(property, (uint32_t)userFileIndex);
746     //If both FILE_ACCESS_MANAGER_MODE and READ_WRITE_USER_FILE_MODE exist, the value is invalid.
747     if (fileMgrRes != 0 && userFileRes != 0) {
748         APPSPAWN_LOGE("invalid msg request.");
749         return -1;
750     }
751     // If FILE_ACCESS_MANAGER_MODE and READ_WRITE_USER_FILE_MODE do not exist,set the flag bit.
752     if (index > 0 && (fileMgrIndex > 0 && userFileIndex > 0) && (fileMgrRes == 0 && userFileRes == 0)) {
753         if (SetAppPermissionFlags(property, index) != 0) {
754             return -1;
755         }
756     }
757     return 0;
758 }
759 
AppendGids(AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)760 static int AppendGids(AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
761 {
762     int ret = AppendPermissionGid(sandbox, property);
763     APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
764     ret = AppendPackageNameGids(sandbox, property);
765     APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
766     return ret;
767 }
768 
SpawnPrepareSandboxCfg(AppSpawnMgr * content,AppSpawningCtx * property)769 int SpawnPrepareSandboxCfg(AppSpawnMgr *content, AppSpawningCtx *property)
770 {
771     APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
772     APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1);
773     APPSPAWN_LOGV("Prepare sandbox config %{public}s", GetProcessName(property));
774     ExtDataType type = GetSandboxType(content, property);
775     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, type);
776     APPSPAWN_CHECK(sandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
777     content->content.sandboxType = type;
778 
779     int ret = UpdatePermissionFlags(content, sandbox, property);
780     if (ret != 0) {
781         APPSPAWN_LOGW("set sandbox permission flag failed.");
782         return APPSPAWN_SANDBOX_ERROR_SET_PERMISSION_FLAG_FAIL;
783     }
784     UpdateMsgFlagsWithPermission(sandbox, property, GET_ALL_PROCESSES_MODE, APP_FLAGS_GET_ALL_PROCESSES);
785     UpdateMsgFlagsWithPermission(sandbox, property, APP_ALLOW_IOURING, APP_FLAGS_ALLOW_IOURING);
786 
787     ret = AppendGids(sandbox, property);
788     APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
789     ret = StagedMountSystemConst(sandbox, property, IsNWebSpawnMode(content));
790     APPSPAWN_CHECK(ret == 0, return ret, "Failed to mount system-const for %{public}s", GetProcessName(property));
791     return 0;
792 }
793 
SpawnMountDirToShared(AppSpawnMgr * content,AppSpawningCtx * property)794 static int SpawnMountDirToShared(AppSpawnMgr *content, AppSpawningCtx *property)
795 {
796     ExtDataType type = GetSandboxType(content, property);
797     AppSpawnSandboxCfg *appSandbox = GetAppSpawnSandbox(content, type);
798     APPSPAWN_CHECK(appSandbox != NULL, return APPSPAWN_SANDBOX_INVALID,
799                    "Failed to get sandbox cfg for %{public}s", GetProcessName(property));
800     content->content.sandboxType = type;
801 
802     SandboxContext *context = GetSandboxContext();  // need free after mount
803     APPSPAWN_CHECK_ONLY_EXPER(context != NULL, return APPSPAWN_SYSTEM_ERROR);
804     int ret = InitSandboxContext(context, appSandbox, property, IsNWebSpawnMode(content));  // need free after mount
805     APPSPAWN_CHECK_ONLY_EXPER(ret == 0, DeleteSandboxContext(&context);
806                                         return ret);
807 
808     ret = MountDirsToShared(content, context, appSandbox);
809     APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Failed to mount dirs to shared");
810     DeleteSandboxContext(&context);
811     return ret;
812 }
813 
814 #ifdef APPSPAWN_SANDBOX_NEW
MODULE_CONSTRUCTOR(void)815 MODULE_CONSTRUCTOR(void)
816 {
817     APPSPAWN_LOGV("Load sandbox module ...");
818     (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadAppSandboxCfg);
819     (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadIsoLatedSandboxCfg);
820     (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadNWebSandboxCfg);
821     (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadDebugSandboxCfg);
822     (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, SandboxHandleServerExit);
823     (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, IsolatedSandboxHandleServerExit);
824     (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_SANDBOX, SpawnPrepareSandboxCfg);
825     (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_SANDBOX, SpawnMountDirToShared);
826     (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SpawnBuildSandboxEnv);
827 }
828 
MODULE_DESTRUCTOR(void)829 MODULE_DESTRUCTOR(void)
830 {
831     ClearVariable();
832     ClearExpandAppSandboxConfigHandle();
833 }
834 #endif
835