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 "appspawn_manager.h"
21 #include "appspawn_permission.h"
22 #include "appspawn_sandbox.h"
23 #include "appspawn_utils.h"
24 #include "modulemgr.h"
25 #include "parameter.h"
26 #include "securec.h"
27 
FreePathMountNode(SandboxMountNode * node)28 static void FreePathMountNode(SandboxMountNode *node)
29 {
30     PathMountNode *sandboxNode = (PathMountNode *)node;
31     if (sandboxNode->source) {
32         free(sandboxNode->source);
33         sandboxNode->source = NULL;
34     }
35     if (sandboxNode->target) {
36         free(sandboxNode->target);
37         sandboxNode->target = NULL;
38     }
39     if (sandboxNode->appAplName) {
40         free(sandboxNode->appAplName);
41         sandboxNode->appAplName = NULL;
42     }
43     free(sandboxNode);
44 }
45 
FreeSymbolLinkNode(SandboxMountNode * node)46 static void FreeSymbolLinkNode(SandboxMountNode *node)
47 {
48     SymbolLinkNode *sandboxNode = (SymbolLinkNode *)node;
49     if (sandboxNode->target) {
50         free(sandboxNode->target);
51         sandboxNode->target = NULL;
52     }
53     if (sandboxNode->linkName) {
54         free(sandboxNode->linkName);
55         sandboxNode->linkName = NULL;
56     }
57     free(sandboxNode);
58 }
59 
SandboxNodeCompareProc(ListNode * node,ListNode * newNode)60 static int SandboxNodeCompareProc(ListNode *node, ListNode *newNode)
61 {
62     SandboxMountNode *sandbox1 = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node);
63     SandboxMountNode *sandbox2 = (SandboxMountNode *)ListEntry(newNode, SandboxMountNode, node);
64     return sandbox1->type - sandbox2->type;
65 }
66 
CreateSandboxMountNode(uint32_t dataLen,uint32_t type)67 SandboxMountNode *CreateSandboxMountNode(uint32_t dataLen, uint32_t type)
68 {
69     APPSPAWN_CHECK(dataLen >= sizeof(SandboxMountNode) && dataLen <= sizeof(PathMountNode),
70         return NULL, "Invalid dataLen %{public}u", dataLen);
71     SandboxMountNode *node = (SandboxMountNode *)calloc(1, dataLen);
72     APPSPAWN_CHECK(node != NULL, return NULL, "Failed to create mount node %{public}u", type);
73     OH_ListInit(&node->node);
74     node->type = type;
75     return node;
76 }
77 
AddSandboxMountNode(SandboxMountNode * node,SandboxSection * queue)78 void AddSandboxMountNode(SandboxMountNode *node, SandboxSection *queue)
79 {
80     APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return);
81     APPSPAWN_CHECK_ONLY_EXPER(queue != NULL, return);
82     OH_ListAddWithOrder(&queue->front, &node->node, SandboxNodeCompareProc);
83 }
84 
PathMountNodeCompare(ListNode * node,void * data)85 static int PathMountNodeCompare(ListNode *node, void *data)
86 {
87     PathMountNode *node1 = (PathMountNode *)ListEntry(node, SandboxMountNode, node);
88     PathMountNode *node2 = (PathMountNode *)data;
89     return (node1->sandboxNode.type == node2->sandboxNode.type) &&
90         (strcmp(node1->source, node2->source) == 0) &&
91         (strcmp(node1->target, node2->target) == 0) ? 0 : 1;
92 }
93 
SymbolLinkNodeCompare(ListNode * node,void * data)94 static int SymbolLinkNodeCompare(ListNode *node, void *data)
95 {
96     SymbolLinkNode *node1 = (SymbolLinkNode *)ListEntry(node, SandboxMountNode, node);
97     SymbolLinkNode *node2 = (SymbolLinkNode *)data;
98     return (node1->sandboxNode.type == node2->sandboxNode.type) &&
99         (strcmp(node1->target, node2->target) == 0) &&
100         (strcmp(node1->linkName, node2->linkName) == 0) ? 0 : 1;
101 }
102 
GetPathMountNode(const SandboxSection * section,int type,const char * source,const char * target)103 PathMountNode *GetPathMountNode(const SandboxSection *section, int type, const char *source, const char *target)
104 {
105     APPSPAWN_CHECK_ONLY_EXPER(section != NULL, return NULL);
106     APPSPAWN_CHECK_ONLY_EXPER(source != NULL && target != NULL, return NULL);
107     PathMountNode pathNode = {};
108     pathNode.sandboxNode.type = type;
109     pathNode.source = (char *)source;
110     pathNode.target = (char *)target;
111     ListNode *node = OH_ListFind(&section->front, (void *)&pathNode, PathMountNodeCompare);
112     if (node == NULL) {
113         return NULL;
114     }
115     return (PathMountNode *)ListEntry(node, SandboxMountNode, node);
116 }
117 
GetSymbolLinkNode(const SandboxSection * section,const char * target,const char * linkName)118 SymbolLinkNode *GetSymbolLinkNode(const SandboxSection *section, const char *target, const char *linkName)
119 {
120     APPSPAWN_CHECK_ONLY_EXPER(section != NULL, return NULL);
121     APPSPAWN_CHECK_ONLY_EXPER(linkName != NULL && target != NULL, return NULL);
122     SymbolLinkNode linkNode = {};
123     linkNode.sandboxNode.type = SANDBOX_TAG_SYMLINK;
124     linkNode.target = (char *)target;
125     linkNode.linkName = (char *)linkName;
126     ListNode *node = OH_ListFind(&section->front, (void *)&linkNode, SymbolLinkNodeCompare);
127     if (node == NULL) {
128         return NULL;
129     }
130     return (SymbolLinkNode *)ListEntry(node, SandboxMountNode, node);
131 }
132 
DeleteSandboxMountNode(SandboxMountNode * sandboxNode)133 void DeleteSandboxMountNode(SandboxMountNode *sandboxNode)
134 {
135     APPSPAWN_CHECK_ONLY_EXPER(sandboxNode != NULL, return);
136     OH_ListRemove(&sandboxNode->node);
137     OH_ListInit(&sandboxNode->node);
138     switch (sandboxNode->type) {
139         case SANDBOX_TAG_MOUNT_PATH:
140         case SANDBOX_TAG_MOUNT_FILE:
141             FreePathMountNode(sandboxNode);
142             break;
143         case SANDBOX_TAG_SYMLINK:
144             FreeSymbolLinkNode(sandboxNode);
145             break;
146         default:
147             APPSPAWN_LOGE("Invalid type %{public}u", sandboxNode->type);
148             free(sandboxNode);
149             break;
150     }
151 }
152 
GetFirstSandboxMountNode(const SandboxSection * section)153 SandboxMountNode *GetFirstSandboxMountNode(const SandboxSection *section)
154 {
155     if (section == NULL || ListEmpty(section->front)) {
156         return NULL;
157     }
158     return (SandboxMountNode *)ListEntry(section->front.next, SandboxMountNode, node);
159 }
160 
DumpSandboxMountNode(const SandboxMountNode * sandboxNode,uint32_t index)161 void DumpSandboxMountNode(const SandboxMountNode *sandboxNode, uint32_t index)
162 {
163     APPSPAWN_CHECK_ONLY_EXPER(sandboxNode != NULL, return);
164     switch (sandboxNode->type) {
165         case SANDBOX_TAG_MOUNT_PATH:
166         case SANDBOX_TAG_MOUNT_FILE: {
167             PathMountNode *pathNode = (PathMountNode *)sandboxNode;
168             APPSPAPWN_DUMP("        ****************************** %{public}u", index);
169             APPSPAPWN_DUMP("        sandbox node source: %{public}s", pathNode->source ? pathNode->source : "null");
170             APPSPAPWN_DUMP("        sandbox node target: %{public}s", pathNode->target ? pathNode->target : "null");
171             DumpMountPathMountNode(pathNode);
172             APPSPAPWN_DUMP("        sandbox node apl: %{public}s",
173                 pathNode->appAplName ? pathNode->appAplName : "null");
174             APPSPAPWN_DUMP("        sandbox node checkErrorFlag: %{public}s",
175                 pathNode->checkErrorFlag ? "true" : "false");
176             break;
177         }
178         case SANDBOX_TAG_SYMLINK: {
179             SymbolLinkNode *linkNode = (SymbolLinkNode *)sandboxNode;
180             APPSPAPWN_DUMP("        ***********************************");
181             APPSPAPWN_DUMP("        sandbox node target: %{public}s", linkNode->target ? linkNode->target : "null");
182             APPSPAPWN_DUMP("        sandbox node linkName: %{public}s",
183                 linkNode->linkName ? linkNode->linkName : "null");
184             APPSPAPWN_DUMP("        sandbox node destMode: %{public}x", linkNode->destMode);
185             APPSPAPWN_DUMP("        sandbox node checkErrorFlag: %{public}s",
186                 linkNode->checkErrorFlag ? "true" : "false");
187             break;
188         }
189         default:
190             break;
191     }
192 }
193 
InitSandboxSection(SandboxSection * section,int type)194 static inline void InitSandboxSection(SandboxSection *section, int type)
195 {
196     OH_ListInit(&section->front);
197     section->sandboxSwitch = 0;
198     section->sandboxShared = 0;
199     section->number = 0;
200     section->gidCount = 0;
201     section->gidTable = NULL;
202     section->nameGroups = NULL;
203     section->name = NULL;
204     OH_ListInit(&section->sandboxNode.node);
205     section->sandboxNode.type = type;
206 }
207 
ClearSandboxSection(SandboxSection * section)208 static void ClearSandboxSection(SandboxSection *section)
209 {
210     if (section->gidTable) {
211         free(section->gidTable);
212         section->gidTable = NULL;
213     }
214     // free name group
215     if (section->nameGroups) {
216         free(section->nameGroups);
217         section->nameGroups = NULL;
218     }
219     if (section->name) {
220         free(section->name);
221         section->name = NULL;
222     }
223     if (section->sandboxNode.type == SANDBOX_TAG_NAME_GROUP) {
224         SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)section;
225         if (groupNode->depNode) {
226             DeleteSandboxMountNode((SandboxMountNode *)groupNode->depNode);
227         }
228     }
229     // free mount path
230     ListNode *node = section->front.next;
231     while (node != &section->front) {
232         SandboxMountNode *sandboxNode = ListEntry(node, SandboxMountNode, node);
233         // delete node
234         OH_ListRemove(&sandboxNode->node);
235         OH_ListInit(&sandboxNode->node);
236         DeleteSandboxMountNode(sandboxNode);
237         // get next
238         node = section->front.next;
239     }
240 }
241 
DumpSandboxQueue(const ListNode * front,void (* dumpSandboxMountNode)(const SandboxMountNode * node,uint32_t count))242 static void DumpSandboxQueue(const ListNode *front,
243     void (*dumpSandboxMountNode)(const SandboxMountNode *node, uint32_t count))
244 {
245     uint32_t count = 0;
246     ListNode *node = front->next;
247     while (node != front) {
248         SandboxMountNode *sandboxNode = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node);
249         count++;
250         dumpSandboxMountNode(sandboxNode, count);
251         // get next
252         node = node->next;
253     }
254 }
255 
DumpSandboxSection(const SandboxSection * section)256 static void DumpSandboxSection(const SandboxSection *section)
257 {
258     APPSPAPWN_DUMP("    sandboxSwitch %{public}s", section->sandboxSwitch ? "true" : "false");
259     APPSPAPWN_DUMP("    sandboxShared %{public}s", section->sandboxShared ? "true" : "false");
260     APPSPAPWN_DUMP("    gidCount: %{public}u", section->gidCount);
261     for (uint32_t index = 0; index < section->gidCount; index++) {
262         APPSPAPWN_DUMP("        gidTable[%{public}u]: %{public}u", index, section->gidTable[index]);
263     }
264     APPSPAPWN_DUMP("    mount group count: %{public}u", section->number);
265     for (uint32_t i = 0; i < section->number; i++) {
266         if (section->nameGroups[i]) {
267             SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)section->nameGroups[i];
268             APPSPAPWN_DUMP("        name[%{public}d] %{public}s", i, groupNode->section.name);
269         }
270     }
271     APPSPAPWN_DUMP("    mount-paths: ");
272     DumpSandboxQueue(&section->front, DumpSandboxMountNode);
273 }
274 
CreateSandboxSection(const char * name,uint32_t dataLen,uint32_t type)275 SandboxSection *CreateSandboxSection(const char *name, uint32_t dataLen, uint32_t type)
276 {
277     APPSPAWN_CHECK(type < SANDBOX_TAG_INVALID && type >= SANDBOX_TAG_PERMISSION,
278         return NULL, "Invalid type %{public}u", type);
279     APPSPAWN_CHECK(name != NULL && strlen(name) > 0, return NULL, "Invalid name %{public}u", type);
280     APPSPAWN_CHECK(dataLen >= sizeof(SandboxSection), return NULL, "Invalid dataLen %{public}u", dataLen);
281     APPSPAWN_CHECK(dataLen <= sizeof(SandboxNameGroupNode), return NULL, "Invalid dataLen %{public}u", dataLen);
282     SandboxSection *section = (SandboxSection *)calloc(1, dataLen);
283     APPSPAWN_CHECK(section != NULL, return NULL, "Failed to create base node");
284     InitSandboxSection(section, type);
285     section->name = strdup(name);
286     if (section->name == NULL) {
287         ClearSandboxSection(section);
288         free(section);
289         return NULL;
290     }
291     return section;
292 }
293 
SandboxConditionalNodeCompareName(ListNode * node,void * data)294 static int SandboxConditionalNodeCompareName(ListNode *node, void *data)
295 {
296     SandboxSection *tmpNode = (SandboxSection *)ListEntry(node, SandboxMountNode, node);
297     return strcmp(tmpNode->name, (char *)data);
298 }
299 
SandboxConditionalNodeCompareNode(ListNode * node,ListNode * newNode)300 static int SandboxConditionalNodeCompareNode(ListNode *node, ListNode *newNode)
301 {
302     SandboxSection *tmpNode = (SandboxSection *)ListEntry(node, SandboxMountNode, node);
303     SandboxSection *tmpNewNode = (SandboxSection *)ListEntry(newNode, SandboxMountNode, node);
304     return strcmp(tmpNode->name, tmpNewNode->name);
305 }
306 
GetSandboxSection(const SandboxQueue * queue,const char * name)307 SandboxSection *GetSandboxSection(const SandboxQueue *queue, const char *name)
308 {
309     APPSPAWN_CHECK_ONLY_EXPER(name != NULL && queue != NULL, return NULL);
310     ListNode *node = OH_ListFind(&queue->front, (void *)name, SandboxConditionalNodeCompareName);
311     if (node == NULL) {
312         return NULL;
313     }
314     return (SandboxSection *)ListEntry(node, SandboxMountNode, node);
315 }
316 
AddSandboxSection(SandboxSection * node,SandboxQueue * queue)317 void AddSandboxSection(SandboxSection *node, SandboxQueue *queue)
318 {
319     APPSPAWN_CHECK_ONLY_EXPER(node != NULL && queue != NULL, return);
320     if (ListEmpty(node->sandboxNode.node)) {
321         OH_ListAddWithOrder(&queue->front, &node->sandboxNode.node, SandboxConditionalNodeCompareNode);
322     }
323 }
324 
DeleteSandboxSection(SandboxSection * section)325 void DeleteSandboxSection(SandboxSection *section)
326 {
327     APPSPAWN_CHECK_ONLY_EXPER(section != NULL, return);
328     // delete node
329     OH_ListRemove(&section->sandboxNode.node);
330     OH_ListInit(&section->sandboxNode.node);
331     ClearSandboxSection(section);
332     free(section);
333 }
334 
SandboxQueueClear(SandboxQueue * queue)335 static void SandboxQueueClear(SandboxQueue *queue)
336 {
337     ListNode *node = queue->front.next;
338     while (node != &queue->front) {
339         SandboxSection *sandboxNode = (SandboxSection *)ListEntry(node, SandboxMountNode, node);
340         DeleteSandboxSection(sandboxNode);
341         // get first
342         node = queue->front.next;
343     }
344 }
345 
AppSpawnExtDataCompareDataId(ListNode * node,void * data)346 static int AppSpawnExtDataCompareDataId(ListNode *node, void *data)
347 {
348     AppSpawnExtData *extData = (AppSpawnExtData *)ListEntry(node, AppSpawnExtData, node);
349     return extData->dataId - *(uint32_t *)data;
350 }
351 
GetAppSpawnSandbox(const AppSpawnMgr * content)352 AppSpawnSandboxCfg *GetAppSpawnSandbox(const AppSpawnMgr *content)
353 {
354     APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return NULL);
355     uint32_t dataId = EXT_DATA_SANDBOX;
356     ListNode *node = OH_ListFind(&content->extData, (void *)&dataId, AppSpawnExtDataCompareDataId);
357     if (node == NULL) {
358         return NULL;
359     }
360     return (AppSpawnSandboxCfg *)ListEntry(node, AppSpawnSandboxCfg, extData);
361 }
362 
DeleteAppSpawnSandbox(AppSpawnSandboxCfg * sandbox)363 void DeleteAppSpawnSandbox(AppSpawnSandboxCfg *sandbox)
364 {
365     APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return);
366     APPSPAWN_LOGV("DeleteAppSpawnSandbox");
367     OH_ListRemove(&sandbox->extData.node);
368     OH_ListInit(&sandbox->extData.node);
369 
370     // delete all queue
371     SandboxQueueClear(&sandbox->requiredQueue);
372     SandboxQueueClear(&sandbox->permissionQueue);
373     SandboxQueueClear(&sandbox->packageNameQueue);
374     SandboxQueueClear(&sandbox->spawnFlagsQueue);
375     SandboxQueueClear(&sandbox->nameGroupsQueue);
376     if (sandbox->rootPath) {
377         free(sandbox->rootPath);
378     }
379     free(sandbox->depGroupNodes);
380     sandbox->depGroupNodes = NULL;
381     free(sandbox);
382     sandbox = NULL;
383 }
384 
DumpSandboxPermission(const SandboxMountNode * node,uint32_t index)385 static void DumpSandboxPermission(const SandboxMountNode *node, uint32_t index)
386 {
387     SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)node;
388     APPSPAPWN_DUMP("    ========================================= ");
389     APPSPAPWN_DUMP("    Section %{public}s", permissionNode->section.name);
390     APPSPAPWN_DUMP("    Section permission index %{public}d", permissionNode->permissionIndex);
391     DumpSandboxSection(&permissionNode->section);
392 }
393 
DumpSandboxSectionNode(const SandboxMountNode * node,uint32_t index)394 static void DumpSandboxSectionNode(const SandboxMountNode *node, uint32_t index)
395 {
396     SandboxSection *section = (SandboxSection *)node;
397     APPSPAPWN_DUMP("    ========================================= ");
398     APPSPAPWN_DUMP("    Section %{public}s", section->name);
399     DumpSandboxSection(section);
400 }
401 
DumpSandboxNameGroupNode(const SandboxMountNode * node,uint32_t index)402 static void DumpSandboxNameGroupNode(const SandboxMountNode *node, uint32_t index)
403 {
404     SandboxNameGroupNode *nameGroupNode = (SandboxNameGroupNode *)node;
405     APPSPAPWN_DUMP("    ========================================= ");
406     APPSPAPWN_DUMP("    Section %{public}s", nameGroupNode->section.name);
407     APPSPAPWN_DUMP("    Section dep mode %{public}s",
408         nameGroupNode->depMode == MOUNT_MODE_ALWAYS ? "always" : "not-exists");
409     if (nameGroupNode->depNode != NULL) {
410         APPSPAPWN_DUMP("    mount-paths-deps: ");
411         DumpMountPathMountNode(nameGroupNode->depNode);
412     }
413     DumpSandboxSection(&nameGroupNode->section);
414 }
415 
416 
DumpSandbox(struct TagAppSpawnExtData * data)417 static void DumpSandbox(struct TagAppSpawnExtData *data)
418 {
419     AppSpawnSandboxCfg *sandbox = (AppSpawnSandboxCfg *)data;
420     DumpAppSpawnSandboxCfg(sandbox);
421 }
422 
InitSandboxQueue(SandboxQueue * queue,uint32_t type)423 static inline void InitSandboxQueue(SandboxQueue *queue, uint32_t type)
424 {
425     OH_ListInit(&queue->front);
426     queue->type = type;
427 }
428 
FreeAppSpawnSandbox(struct TagAppSpawnExtData * data)429 static void FreeAppSpawnSandbox(struct TagAppSpawnExtData *data)
430 {
431     AppSpawnSandboxCfg *sandbox = ListEntry(data, AppSpawnSandboxCfg, extData);
432     // delete all var
433     DeleteAppSpawnSandbox(sandbox);
434 }
435 
CreateAppSpawnSandbox(void)436 AppSpawnSandboxCfg *CreateAppSpawnSandbox(void)
437 {
438     // create sandbox
439     AppSpawnSandboxCfg *sandbox = (AppSpawnSandboxCfg *)calloc(1, sizeof(AppSpawnSandboxCfg));
440     APPSPAWN_CHECK(sandbox != NULL, return NULL, "Failed to create sandbox");
441 
442     // ext data init
443     OH_ListInit(&sandbox->extData.node);
444     sandbox->extData.dataId = EXT_DATA_SANDBOX;
445     sandbox->extData.freeNode = FreeAppSpawnSandbox;
446     sandbox->extData.dumpNode = DumpSandbox;
447 
448     // queue
449     InitSandboxQueue(&sandbox->requiredQueue, SANDBOX_TAG_REQUIRED);
450     InitSandboxQueue(&sandbox->permissionQueue, SANDBOX_TAG_PERMISSION);
451     InitSandboxQueue(&sandbox->packageNameQueue, SANDBOX_TAG_PACKAGE_NAME);
452     InitSandboxQueue(&sandbox->spawnFlagsQueue, SANDBOX_TAG_SPAWN_FLAGS);
453     InitSandboxQueue(&sandbox->nameGroupsQueue, SANDBOX_TAG_NAME_GROUP);
454 
455     sandbox->topSandboxSwitch = 0;
456     sandbox->appFullMountEnable = 0;
457     sandbox->topSandboxSwitch = 0;
458     sandbox->pidNamespaceSupport = 0;
459     sandbox->sandboxNsFlags = 0;
460     sandbox->maxPermissionIndex = -1;
461     sandbox->depNodeCount = 0;
462     sandbox->depGroupNodes = NULL;
463 
464     AddDefaultVariable();
465     AddDefaultExpandAppSandboxConfigHandle();
466     return sandbox;
467 }
468 
DumpAppSpawnSandboxCfg(AppSpawnSandboxCfg * sandbox)469 void DumpAppSpawnSandboxCfg(AppSpawnSandboxCfg *sandbox)
470 {
471     APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return);
472     APPSPAPWN_DUMP("Sandbox root path: %{public}s", sandbox->rootPath);
473     APPSPAPWN_DUMP("Sandbox sandboxNsFlags: %{public}x ", sandbox->sandboxNsFlags);
474     APPSPAPWN_DUMP("Sandbox topSandboxSwitch: %{public}s", sandbox->topSandboxSwitch ? "true" : "false");
475     APPSPAPWN_DUMP("Sandbox appFullMountEnable: %{public}s", sandbox->appFullMountEnable ? "true" : "false");
476     APPSPAPWN_DUMP("Sandbox pidNamespaceSupport: %{public}s", sandbox->pidNamespaceSupport ? "true" : "false");
477     APPSPAPWN_DUMP("Sandbox common info: ");
478     DumpSandboxQueue(&sandbox->requiredQueue.front, DumpSandboxSectionNode);
479     DumpSandboxQueue(&sandbox->packageNameQueue.front, DumpSandboxSectionNode);
480     DumpSandboxQueue(&sandbox->permissionQueue.front, DumpSandboxPermission);
481     DumpSandboxQueue(&sandbox->spawnFlagsQueue.front, DumpSandboxSectionNode);
482     DumpSandboxQueue(&sandbox->nameGroupsQueue.front, DumpSandboxNameGroupNode);
483 }
484 
PreLoadSandboxCfg(AppSpawnMgr * content)485 APPSPAWN_STATIC int PreLoadSandboxCfg(AppSpawnMgr *content)
486 {
487     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content);
488     APPSPAWN_CHECK(sandbox == NULL, return 0, "Sandbox has been load");
489 
490     sandbox = CreateAppSpawnSandbox();
491     APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return APPSPAWN_SYSTEM_ERROR);
492     OH_ListAddTail(&content->extData, &sandbox->extData.node);
493 
494     // load app sandbox config
495     LoadAppSandboxConfig(sandbox, IsNWebSpawnMode(content));
496     sandbox->maxPermissionIndex = PermissionRenumber(&sandbox->permissionQueue);
497 
498     content->content.sandboxNsFlags = 0;
499     if (IsNWebSpawnMode(content) || sandbox->pidNamespaceSupport) {
500         content->content.sandboxNsFlags = sandbox->sandboxNsFlags;
501     }
502     return 0;
503 }
504 
SandboxHandleServerExit(AppSpawnMgr * content)505 APPSPAWN_STATIC int SandboxHandleServerExit(AppSpawnMgr *content)
506 {
507     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content);
508     APPSPAWN_CHECK(sandbox != NULL, return 0, "Sandbox not load");
509 
510     return 0;
511 }
512 
SpawnBuildSandboxEnv(AppSpawnMgr * content,AppSpawningCtx * property)513 int SpawnBuildSandboxEnv(AppSpawnMgr *content, AppSpawningCtx *property)
514 {
515     AppSpawnSandboxCfg *appSandbox = GetAppSpawnSandbox(content);
516     APPSPAWN_CHECK(appSandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
517     // no sandbox
518     if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) {
519         return 0;
520     }
521     // CLONE_NEWPID 0x20000000
522     // CLONE_NEWNET 0x40000000
523     if ((content->content.sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID) {
524         int ret = getprocpid();
525         if (ret < 0) {
526             return ret;
527         }
528     }
529     int ret = MountSandboxConfigs(appSandbox, property, IsNWebSpawnMode(content));
530     appSandbox->mounted = 1;
531     // for module test do not create sandbox, use APP_FLAGS_IGNORE_SANDBOX to ignore sandbox result
532     if (CheckAppMsgFlagsSet(property, APP_FLAGS_IGNORE_SANDBOX)) {
533         APPSPAWN_LOGW("Do not care sandbox result %{public}d", ret);
534         return 0;
535     }
536     return ret == 0 ? 0 : APPSPAWN_SANDBOX_MOUNT_FAIL;
537 }
538 
AppendPermissionGid(const AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)539 static int AppendPermissionGid(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
540 {
541     AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
542     APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
543         "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
544 
545     APPSPAWN_LOGV("AppendPermissionGid %{public}s", GetProcessName(property));
546     ListNode *node = sandbox->permissionQueue.front.next;
547     while (node != &sandbox->permissionQueue.front) {
548         SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
549         if (!CheckAppPermissionFlagSet(property, (uint32_t)permissionNode->permissionIndex)) {
550             node = node->next;
551             continue;
552         }
553         if (permissionNode->section.gidCount == 0) {
554             node = node->next;
555             continue;
556         }
557         APPSPAWN_LOGV("Add permission %{public}s gid %{public}d to %{public}s",
558             permissionNode->section.name, permissionNode->section.gidTable[0], GetProcessName(property));
559 
560         size_t copyLen = permissionNode->section.gidCount;
561         if ((permissionNode->section.gidCount + dacInfo->gidCount) > APP_MAX_GIDS) {
562             APPSPAWN_LOGW("More gid for %{public}s msg count %{public}u permission %{public}u",
563                 GetProcessName(property), dacInfo->gidCount, permissionNode->section.gidCount);
564             copyLen = APP_MAX_GIDS - dacInfo->gidCount;
565         }
566         int ret = memcpy_s(&dacInfo->gidTable[dacInfo->gidCount], sizeof(gid_t) * copyLen,
567             permissionNode->section.gidTable, sizeof(gid_t) * copyLen);
568         if (ret != EOK) {
569             APPSPAWN_LOGW("Failed to append permission %{public}s gid to %{public}s",
570                 permissionNode->section.name, GetProcessName(property));
571             node = node->next;
572             continue;
573         }
574         dacInfo->gidCount += copyLen;
575         node = node->next;
576     }
577     return 0;
578 }
579 
SpawnPrepareSandboxCfg(AppSpawnMgr * content,AppSpawningCtx * property)580 int SpawnPrepareSandboxCfg(AppSpawnMgr *content, AppSpawningCtx *property)
581 {
582     APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
583     APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1);
584     APPSPAWN_LOGV("Prepare sandbox config %{public}s", GetProcessName(property));
585     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content);
586     APPSPAWN_CHECK(sandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
587 
588     if (sandbox->appFullMountEnable) {
589         int index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_CROSS_APP_MODE);
590         if (index > 0) {
591             SetAppPermissionFlags(property, index);
592         }
593     }
594     int ret = AppendPermissionGid(sandbox, property);
595     APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
596     ret = StagedMountSystemConst(sandbox, property, IsNWebSpawnMode(content));
597     APPSPAWN_CHECK(ret == 0, return ret, "Failed to mount system-const for %{public}s", GetProcessName(property));
598     return 0;
599 }
600 
SandboxUnmountPath(const AppSpawnMgr * content,const AppSpawnedProcessInfo * appInfo)601 APPSPAWN_STATIC int SandboxUnmountPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo)
602 {
603     APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
604     APPSPAWN_CHECK_ONLY_EXPER(appInfo != NULL, return -1);
605     APPSPAWN_LOGV("Sandbox process %{public}s %{public}u exit", appInfo->name, appInfo->uid);
606     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content);
607     return UnmountDepPaths(sandbox, appInfo->uid);
608 }
609 
610 #ifdef APPSPAWN_SANDBOX_NEW
MODULE_CONSTRUCTOR(void)611 MODULE_CONSTRUCTOR(void)
612 {
613     APPSPAWN_LOGV("Load sandbox module ...");
614     (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadSandboxCfg);
615     (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, SandboxHandleServerExit);
616     (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_SANDBOX, SpawnPrepareSandboxCfg);
617     (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SpawnBuildSandboxEnv);
618     (void)AddProcessMgrHook(STAGE_SERVER_APP_DIED, 0, SandboxUnmountPath);
619 }
620 
MODULE_DESTRUCTOR(void)621 MODULE_DESTRUCTOR(void)
622 {
623     ClearVariable();
624     ClearExpandAppSandboxConfigHandle();
625 }
626 #endif
627