• 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 "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             APPSPAWN_DUMP("        ****************************** %{public}u", index);
169             APPSPAWN_DUMP("        sandbox node source: %{public}s", pathNode->source ? pathNode->source : "null");
170             APPSPAWN_DUMP("        sandbox node target: %{public}s", pathNode->target ? pathNode->target : "null");
171             DumpMountPathMountNode(pathNode);
172             APPSPAWN_DUMP("        sandbox node apl: %{public}s",
173                 pathNode->appAplName ? pathNode->appAplName : "null");
174             APPSPAWN_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             APPSPAWN_DUMP("        ***********************************");
181             APPSPAWN_DUMP("        sandbox node target: %{public}s", linkNode->target ? linkNode->target : "null");
182             APPSPAWN_DUMP("        sandbox node linkName: %{public}s",
183                 linkNode->linkName ? linkNode->linkName : "null");
184             APPSPAWN_DUMP("        sandbox node destMode: %{public}x", linkNode->destMode);
185             APPSPAWN_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     APPSPAWN_DUMP("    sandboxSwitch %{public}s", section->sandboxSwitch ? "true" : "false");
259     APPSPAWN_DUMP("    sandboxShared %{public}s", section->sandboxShared ? "true" : "false");
260     APPSPAWN_DUMP("    gidCount: %{public}u", section->gidCount);
261     for (uint32_t index = 0; index < section->gidCount; index++) {
262         APPSPAWN_DUMP("        gidTable[%{public}u]: %{public}u", index, section->gidTable[index]);
263     }
264     APPSPAWN_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             APPSPAWN_DUMP("        name[%{public}d] %{public}s", i, groupNode->section.name);
269         }
270     }
271     APPSPAWN_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     APPSPAWN_DUMP("    ========================================= ");
389     APPSPAWN_DUMP("    Section %{public}s", permissionNode->section.name);
390     APPSPAWN_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     APPSPAWN_DUMP("    ========================================= ");
398     APPSPAWN_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     APPSPAWN_DUMP("    ========================================= ");
406     APPSPAWN_DUMP("    Section %{public}s", nameGroupNode->section.name);
407     APPSPAWN_DUMP("    Section dep mode %{public}s",
408         nameGroupNode->depMode == MOUNT_MODE_ALWAYS ? "always" : "not-exists");
409     if (nameGroupNode->depNode != NULL) {
410         APPSPAWN_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     APPSPAWN_DUMP("Sandbox root path: %{public}s", sandbox->rootPath);
473     APPSPAWN_DUMP("Sandbox sandboxNsFlags: %{public}x ", sandbox->sandboxNsFlags);
474     APPSPAWN_DUMP("Sandbox topSandboxSwitch: %{public}s", sandbox->topSandboxSwitch ? "true" : "false");
475     APPSPAWN_DUMP("Sandbox appFullMountEnable: %{public}s", sandbox->appFullMountEnable ? "true" : "false");
476     APPSPAWN_DUMP("Sandbox pidNamespaceSupport: %{public}s", sandbox->pidNamespaceSupport ? "true" : "false");
477     APPSPAWN_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 isolated 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/nweb sandbox config
519     if (IsNWebSpawnMode(content)) {
520         LoadAppSandboxConfig(sandbox, MODE_FOR_NWEB_SPAWN);
521     } else {
522         LoadAppSandboxConfig(sandbox, MODE_FOR_APP_SPAWN);
523     }
524     sandbox->maxPermissionIndex = PermissionRenumber(&sandbox->permissionQueue);
525 
526     content->content.sandboxNsFlags = 0;
527     if (IsNWebSpawnMode(content) || sandbox->pidNamespaceSupport) {
528         content->content.sandboxNsFlags = sandbox->sandboxNsFlags;
529     }
530     return 0;
531 }
532 
IsolatedSandboxHandleServerExit(AppSpawnMgr * content)533 APPSPAWN_STATIC int IsolatedSandboxHandleServerExit(AppSpawnMgr *content)
534 {
535     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_ISOLATED_SANDBOX);
536     APPSPAWN_CHECK(sandbox != NULL, return 0, "Isolated sandbox not load");
537 
538     return 0;
539 }
540 
SandboxHandleServerExit(AppSpawnMgr * content)541 APPSPAWN_STATIC int SandboxHandleServerExit(AppSpawnMgr *content)
542 {
543     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_SANDBOX);
544     APPSPAWN_CHECK(sandbox != NULL, return 0, "Sandbox not load");
545 
546     return 0;
547 }
548 
SpawnBuildSandboxEnv(AppSpawnMgr * content,AppSpawningCtx * property)549 int SpawnBuildSandboxEnv(AppSpawnMgr *content, AppSpawningCtx *property)
550 {
551     ExtDataType type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? EXT_DATA_ISOLATED_SANDBOX :
552         EXT_DATA_SANDBOX;
553     AppSpawnSandboxCfg *appSandbox = GetAppSpawnSandbox(content, type);
554     content->content.sandboxType = type;
555     APPSPAWN_CHECK(appSandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
556     // no sandbox
557     if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) {
558         return 0;
559     }
560     // CLONE_NEWPID 0x20000000
561     // CLONE_NEWNET 0x40000000
562     if ((content->content.sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID) {
563         int ret = getprocpid();
564         if (ret < 0) {
565             return ret;
566         }
567     }
568     int ret = MountSandboxConfigs(appSandbox, property, IsNWebSpawnMode(content));
569     appSandbox->mounted = 1;
570     // for module test do not create sandbox, use APP_FLAGS_IGNORE_SANDBOX to ignore sandbox result
571     if (CheckAppMsgFlagsSet(property, APP_FLAGS_IGNORE_SANDBOX)) {
572         APPSPAWN_LOGW("Do not care sandbox result %{public}d", ret);
573         return 0;
574     }
575     return ret == 0 ? 0 : APPSPAWN_SANDBOX_MOUNT_FAIL;
576 }
577 
AppendPermissionGid(const AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)578 static int AppendPermissionGid(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
579 {
580     AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
581     APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
582         "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
583 
584     APPSPAWN_LOGV("AppendPermissionGid %{public}s", GetProcessName(property));
585     ListNode *node = sandbox->permissionQueue.front.next;
586     while (node != &sandbox->permissionQueue.front) {
587         SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
588         if (!CheckAppPermissionFlagSet(property, (uint32_t)permissionNode->permissionIndex)) {
589             node = node->next;
590             continue;
591         }
592         if (permissionNode->section.gidCount == 0) {
593             node = node->next;
594             continue;
595         }
596         APPSPAWN_LOGV("Add permission %{public}s gid %{public}d to %{public}s",
597             permissionNode->section.name, permissionNode->section.gidTable[0], GetProcessName(property));
598 
599         size_t copyLen = permissionNode->section.gidCount;
600         if ((permissionNode->section.gidCount + dacInfo->gidCount) > APP_MAX_GIDS) {
601             APPSPAWN_LOGW("More gid for %{public}s msg count %{public}u permission %{public}u",
602                 GetProcessName(property), dacInfo->gidCount, permissionNode->section.gidCount);
603             copyLen = APP_MAX_GIDS - dacInfo->gidCount;
604         }
605         int ret = memcpy_s(&dacInfo->gidTable[dacInfo->gidCount], sizeof(gid_t) * copyLen,
606             permissionNode->section.gidTable, sizeof(gid_t) * copyLen);
607         if (ret != EOK) {
608             APPSPAWN_LOGW("Failed to append permission %{public}s gid to %{public}s",
609                 permissionNode->section.name, GetProcessName(property));
610             node = node->next;
611             continue;
612         }
613         dacInfo->gidCount += copyLen;
614         node = node->next;
615     }
616     return 0;
617 }
618 
AppendPackageNameGids(const AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)619 static int AppendPackageNameGids(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
620 {
621     AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
622     APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
623         "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
624 
625     SandboxPackageNameNode *sandboxNode =
626         (SandboxPackageNameNode *)GetSandboxSection(&sandbox->packageNameQueue, GetProcessName(property));
627     if (sandboxNode == NULL || sandboxNode->section.gidCount == 0) {
628         return 0;
629     }
630 
631     size_t copyLen = sandboxNode->section.gidCount;
632     if ((sandboxNode->section.gidCount + dacInfo->gidCount) > APP_MAX_GIDS) {
633         APPSPAWN_LOGW("More gid for %{public}s msg count %{public}u permission %{public}u",
634                       GetProcessName(property),
635                       dacInfo->gidCount,
636                       sandboxNode->section.gidCount);
637         copyLen = APP_MAX_GIDS - dacInfo->gidCount;
638     }
639     int ret = memcpy_s(&dacInfo->gidTable[dacInfo->gidCount], sizeof(gid_t) * copyLen,
640                        sandboxNode->section.gidTable, sizeof(gid_t) * copyLen);
641     if (ret != EOK) {
642         APPSPAWN_LOGW("Failed to append permission %{public}s gid to %{public}s",
643                       sandboxNode->section.name,
644                       GetProcessName(property));
645     }
646     dacInfo->gidCount += copyLen;
647 
648     return 0;
649 }
650 
UpdateMsgFlagsWithPermission(AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)651 static void UpdateMsgFlagsWithPermission(AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
652 {
653     int32_t allProcessIndex = GetPermissionIndexInQueue(&sandbox->permissionQueue, GET_ALL_PROCESSES_MODE);
654     int res = CheckAppPermissionFlagSet(property, (uint32_t)allProcessIndex);
655     if (res == 0) {
656         APPSPAWN_LOGV("Don't need set GET_ALL_PROCESSES_MODE flag");
657         return;
658     }
659 
660     int ret = SetAppSpawnMsgFlag(property->message, TLV_MSG_FLAGS, APP_FLAGS_GET_ALL_PROCESSES);
661     if (ret != 0) {
662         APPSPAWN_LOGE("Set GET_ALL_PROCESSES_MODE flag failed");
663     }
664     return;
665 }
666 
UpdatePermissionFlags(AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)667 static int UpdatePermissionFlags(AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
668 {
669     int32_t index = 0;
670     if (sandbox->appFullMountEnable) {
671         index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_CROSS_APP_MODE);
672     } else {
673         index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_ACCESS_COMMON_DIR_MODE);
674     }
675 
676     int32_t fileMgrIndex = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_ACCESS_MANAGER_MODE);
677     int32_t userFileIndex = GetPermissionIndexInQueue(&sandbox->permissionQueue, READ_WRITE_USER_FILE_MODE);
678     int fileMgrRes = CheckAppPermissionFlagSet(property, (uint32_t)fileMgrIndex);
679     int userFileRes = CheckAppPermissionFlagSet(property, (uint32_t)userFileIndex);
680     //If both FILE_ACCESS_MANAGER_MODE and READ_WRITE_USER_FILE_MODE exist, the value is invalid.
681     if (fileMgrRes != 0 && userFileRes != 0) {
682         APPSPAWN_LOGE("invalid msg request.");
683         return -1;
684     }
685     // If FILE_ACCESS_MANAGER_MODE and READ_WRITE_USER_FILE_MODE do not exist,set the flag bit.
686     if (index > 0 && (fileMgrIndex > 0 && userFileIndex > 0) && (fileMgrRes == 0 && userFileRes == 0)) {
687         if (SetAppPermissionFlags(property, index) != 0) {
688             return -1;
689         }
690     }
691     return 0;
692 }
693 
AppendGids(AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)694 static int AppendGids(AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
695 {
696     int ret = AppendPermissionGid(sandbox, property);
697     APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
698     ret = AppendPackageNameGids(sandbox, property);
699     APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
700     return ret;
701 }
702 
SpawnPrepareSandboxCfg(AppSpawnMgr * content,AppSpawningCtx * property)703 int SpawnPrepareSandboxCfg(AppSpawnMgr *content, AppSpawningCtx *property)
704 {
705     APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
706     APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1);
707     APPSPAWN_LOGV("Prepare sandbox config %{public}s", GetProcessName(property));
708     ExtDataType type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? EXT_DATA_ISOLATED_SANDBOX :
709         EXT_DATA_SANDBOX;
710     AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, type);
711     content->content.sandboxType = type;
712     APPSPAWN_CHECK(sandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
713 
714     int ret = UpdatePermissionFlags(sandbox, property);
715     if (ret != 0) {
716         APPSPAWN_LOGW("set sandbox permission flag failed.");
717         return APPSPAWN_SANDBOX_ERROR_SET_PERMISSION_FLAG_FAIL;
718     }
719     UpdateMsgFlagsWithPermission(sandbox, property);
720 
721     ret = AppendGids(sandbox, property);
722     APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
723     ret = StagedMountSystemConst(sandbox, property, IsNWebSpawnMode(content));
724     APPSPAWN_CHECK(ret == 0, return ret, "Failed to mount system-const for %{public}s", GetProcessName(property));
725     return 0;
726 }
727 
SandboxUnmountPath(const AppSpawnMgr * content,const AppSpawnedProcessInfo * appInfo)728 APPSPAWN_STATIC int SandboxUnmountPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo)
729 {
730     APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
731     APPSPAWN_CHECK_ONLY_EXPER(appInfo != NULL, return -1);
732     AppSpawnSandboxCfg *sandbox = NULL;
733     APPSPAWN_LOGV("Sandbox process %{public}s %{public}u exit", appInfo->name, appInfo->uid);
734     sandbox = GetAppSpawnSandbox(content, content->content.sandboxType);
735 
736     return UnmountDepPaths(sandbox, appInfo->uid);
737 }
738 
739 #ifdef APPSPAWN_SANDBOX_NEW
MODULE_CONSTRUCTOR(void)740 MODULE_CONSTRUCTOR(void)
741 {
742     APPSPAWN_LOGV("Load sandbox module ...");
743     (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadSandboxCfg);
744     (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadIsoLatedSandboxCfg);
745     (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, SandboxHandleServerExit);
746     (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, IsolatedSandboxHandleServerExit);
747     (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_SANDBOX, SpawnPrepareSandboxCfg);
748     (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SpawnBuildSandboxEnv);
749     (void)AddProcessMgrHook(STAGE_SERVER_APP_DIED, 0, SandboxUnmountPath);
750 }
751 
MODULE_DESTRUCTOR(void)752 MODULE_DESTRUCTOR(void)
753 {
754     ClearVariable();
755     ClearExpandAppSandboxConfigHandle();
756 }
757 #endif
758