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