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, ExtDataType type)352 AppSpawnSandboxCfg *GetAppSpawnSandbox(const AppSpawnMgr *content, ExtDataType type)
353 {
354     APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return NULL);
355     uint32_t dataId = type;
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(ExtDataType type)436 AppSpawnSandboxCfg *CreateAppSpawnSandbox(ExtDataType type)
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 = type;
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 
PreLoadIsoLatedSandboxCfg(AppSpawnMgr *content)485 APPSPAWN_STATIC int PreLoadIsoLatedSandboxCfg(AppSpawnMgr *content)
486 {
487     if (IsNWebSpawnMode(content)) {
488         return 0;
489     }
490 
491     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_ISOLATED_SANDBOX);
492     APPSPAWN_CHECK(sandbox == NULL, return 0, "Isolated sandbox has been load");
493 
494     sandbox = CreateAppSpawnSandbox(EXT_DATA_ISOLATED_SANDBOX);
495     APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return APPSPAWN_SYSTEM_ERROR);
496     OH_ListAddTail(&content->extData, &sandbox->extData.node);
497 
498     // load app sandbox config
499     LoadAppSandboxConfig(sandbox, MODE_FOR_NATIVE_SPAWN);
500     sandbox->maxPermissionIndex = PermissionRenumber(&sandbox->permissionQueue);
501 
502     content->content.sandboxNsFlags = 0;
503     if (sandbox->pidNamespaceSupport) {
504         content->content.sandboxNsFlags = sandbox->sandboxNsFlags;
505     }
506     return 0;
507 }
508 
PreLoadSandboxCfg(AppSpawnMgr *content)509 APPSPAWN_STATIC int PreLoadSandboxCfg(AppSpawnMgr *content)
510 {
511     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_SANDBOX);
512     APPSPAWN_CHECK(sandbox == NULL, return 0, "Sandbox has been load");
513 
514     sandbox = CreateAppSpawnSandbox(EXT_DATA_SANDBOX);
515     APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return APPSPAWN_SYSTEM_ERROR);
516     OH_ListAddTail(&content->extData, &sandbox->extData.node);
517 
518     // load app sandbox config
519     LoadAppSandboxConfig(sandbox, content->content.mode);
520     sandbox->maxPermissionIndex = PermissionRenumber(&sandbox->permissionQueue);
521 
522     content->content.sandboxNsFlags = 0;
523     if (IsNWebSpawnMode(content) || sandbox->pidNamespaceSupport) {
524         content->content.sandboxNsFlags = sandbox->sandboxNsFlags;
525     }
526     return 0;
527 }
528 
IsolatedSandboxHandleServerExit(AppSpawnMgr *content)529 APPSPAWN_STATIC int IsolatedSandboxHandleServerExit(AppSpawnMgr *content)
530 {
531     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_ISOLATED_SANDBOX);
532     APPSPAWN_CHECK(sandbox != NULL, return 0, "Isolated sandbox not load");
533 
534     return 0;
535 }
536 
SandboxHandleServerExit(AppSpawnMgr *content)537 APPSPAWN_STATIC int SandboxHandleServerExit(AppSpawnMgr *content)
538 {
539     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_SANDBOX);
540     APPSPAWN_CHECK(sandbox != NULL, return 0, "Sandbox not load");
541 
542     return 0;
543 }
544 
SpawnBuildSandboxEnv(AppSpawnMgr *content, AppSpawningCtx *property)545 int SpawnBuildSandboxEnv(AppSpawnMgr *content, AppSpawningCtx *property)
546 {
547     ExtDataType type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? EXT_DATA_ISOLATED_SANDBOX :
548         EXT_DATA_SANDBOX;
549     AppSpawnSandboxCfg *appSandbox = GetAppSpawnSandbox(content, type);
550     APPSPAWN_CHECK(appSandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
551     // no sandbox
552     if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) {
553         return 0;
554     }
555     // CLONE_NEWPID 0x20000000
556     // CLONE_NEWNET 0x40000000
557     if ((content->content.sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID) {
558         int ret = getprocpid();
559         if (ret < 0) {
560             return ret;
561         }
562     }
563     int ret = MountSandboxConfigs(appSandbox, property, IsNWebSpawnMode(content));
564     appSandbox->mounted = 1;
565     // for module test do not create sandbox, use APP_FLAGS_IGNORE_SANDBOX to ignore sandbox result
566     if (CheckAppMsgFlagsSet(property, APP_FLAGS_IGNORE_SANDBOX)) {
567         APPSPAWN_LOGW("Do not care sandbox result %{public}d", ret);
568         return 0;
569     }
570     return ret == 0 ? 0 : APPSPAWN_SANDBOX_MOUNT_FAIL;
571 }
572 
AppendPermissionGid(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)573 static int AppendPermissionGid(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
574 {
575     AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
576     APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
577         "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
578 
579     APPSPAWN_LOGV("AppendPermissionGid %{public}s", GetProcessName(property));
580     ListNode *node = sandbox->permissionQueue.front.next;
581     while (node != &sandbox->permissionQueue.front) {
582         SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
583         if (!CheckAppPermissionFlagSet(property, (uint32_t)permissionNode->permissionIndex)) {
584             node = node->next;
585             continue;
586         }
587         if (permissionNode->section.gidCount == 0) {
588             node = node->next;
589             continue;
590         }
591         APPSPAWN_LOGV("Add permission %{public}s gid %{public}d to %{public}s",
592             permissionNode->section.name, permissionNode->section.gidTable[0], GetProcessName(property));
593 
594         size_t copyLen = permissionNode->section.gidCount;
595         if ((permissionNode->section.gidCount + dacInfo->gidCount) > APP_MAX_GIDS) {
596             APPSPAWN_LOGW("More gid for %{public}s msg count %{public}u permission %{public}u",
597                 GetProcessName(property), dacInfo->gidCount, permissionNode->section.gidCount);
598             copyLen = APP_MAX_GIDS - dacInfo->gidCount;
599         }
600         int ret = memcpy_s(&dacInfo->gidTable[dacInfo->gidCount], sizeof(gid_t) * copyLen,
601             permissionNode->section.gidTable, sizeof(gid_t) * copyLen);
602         if (ret != EOK) {
603             APPSPAWN_LOGW("Failed to append permission %{public}s gid to %{public}s",
604                 permissionNode->section.name, GetProcessName(property));
605             node = node->next;
606             continue;
607         }
608         dacInfo->gidCount += copyLen;
609         node = node->next;
610     }
611     return 0;
612 }
613 
AppendPackageNameGids(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)614 static int AppendPackageNameGids(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
615 {
616     AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
617     APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
618         "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
619 
620     SandboxPackageNameNode *sandboxNode =
621         (SandboxPackageNameNode *)GetSandboxSection(&sandbox->packageNameQueue, GetProcessName(property));
622     if (sandboxNode == NULL || sandboxNode->section.gidCount == 0) {
623         return 0;
624     }
625 
626     size_t copyLen = sandboxNode->section.gidCount;
627     if ((sandboxNode->section.gidCount + dacInfo->gidCount) > APP_MAX_GIDS) {
628         APPSPAWN_LOGW("More gid for %{public}s msg count %{public}u permission %{public}u",
629                       GetProcessName(property),
630                       dacInfo->gidCount,
631                       sandboxNode->section.gidCount);
632         copyLen = APP_MAX_GIDS - dacInfo->gidCount;
633     }
634     int ret = memcpy_s(&dacInfo->gidTable[dacInfo->gidCount], sizeof(gid_t) * copyLen,
635                        sandboxNode->section.gidTable, sizeof(gid_t) * copyLen);
636     if (ret != EOK) {
637         APPSPAWN_LOGW("Failed to append permission %{public}s gid to %{public}s",
638                       sandboxNode->section.name,
639                       GetProcessName(property));
640     }
641     dacInfo->gidCount += copyLen;
642 
643     return 0;
644 }
645 
SpawnPrepareSandboxCfg(AppSpawnMgr *content, AppSpawningCtx *property)646 int SpawnPrepareSandboxCfg(AppSpawnMgr *content, AppSpawningCtx *property)
647 {
648     APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
649     APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1);
650     APPSPAWN_LOGV("Prepare sandbox config %{public}s", GetProcessName(property));
651     ExtDataType type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? EXT_DATA_ISOLATED_SANDBOX :
652         EXT_DATA_SANDBOX;
653     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, type);
654     APPSPAWN_CHECK(sandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
655 
656     int32_t index = 0;
657     if (sandbox->appFullMountEnable) {
658         index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_CROSS_APP_MODE);
659     } else {
660         index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_ACCESS_COMMON_DIR_MODE);
661     }
662 
663     int32_t fileMgrIndex = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_ACCESS_MANAGER_MODE);
664     if (index > 0 && (CheckAppMsgFlagsSet(property, (uint32_t)fileMgrIndex) == 0)) {
665         if (SetAppPermissionFlags(property, index) != 0) {
666             return -1;
667         }
668     }
669 
670     int ret = AppendPermissionGid(sandbox, property);
671     APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
672     ret = AppendPackageNameGids(sandbox, property);
673     APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
674     ret = StagedMountSystemConst(sandbox, property, IsNWebSpawnMode(content));
675     APPSPAWN_CHECK(ret == 0, return ret, "Failed to mount system-const for %{public}s", GetProcessName(property));
676     return 0;
677 }
678 
SandboxUnmountPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo)679 APPSPAWN_STATIC int SandboxUnmountPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo)
680 {
681     APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
682     APPSPAWN_CHECK_ONLY_EXPER(appInfo != NULL, return -1);
683     AppSpawnSandboxCfg *sandbox = NULL;
684     APPSPAWN_LOGV("Sandbox process %{public}s %{public}u exit", appInfo->name, appInfo->uid);
685     if (content->content.mode == MODE_FOR_NATIVE_SPAWN) {
686         sandbox = GetAppSpawnSandbox(content, EXT_DATA_ISOLATED_SANDBOX);
687     } else {
688         sandbox = GetAppSpawnSandbox(content, EXT_DATA_SANDBOX);
689     }
690     return UnmountDepPaths(sandbox, appInfo->uid);
691 }
692 
693 #ifdef APPSPAWN_SANDBOX_NEW
MODULE_CONSTRUCTOR(void)694 MODULE_CONSTRUCTOR(void)
695 {
696     APPSPAWN_LOGV("Load sandbox module ...");
697     (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadSandboxCfg);
698     (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadIsoLatedSandboxCfg);
699     (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, SandboxHandleServerExit);
700     (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, IsolatedSandboxHandleServerExit);
701     (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_SANDBOX, SpawnPrepareSandboxCfg);
702     (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SpawnBuildSandboxEnv);
703     (void)AddProcessMgrHook(STAGE_SERVER_APP_DIED, 0, SandboxUnmountPath);
704 }
705 
MODULE_DESTRUCTOR(void)706 MODULE_DESTRUCTOR(void)
707 {
708     ClearVariable();
709     ClearExpandAppSandboxConfigHandle();
710 }
711 #endif
712