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(§ion->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(§ion->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(§ion->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(§ion->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 != §ion->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(§ion->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(§ion->sandboxNode.node);
330 OH_ListInit(§ion->sandboxNode.node);
331 ClearSandboxSection(section);
332 free(section);
333 }
334
SandboxQueueClear(SandboxQueue * queue)335 static void SandboxQueueClear(SandboxQueue *queue)
336 {
337 ListNode *node = queue->front.next;
338 while (node != &queue->front) {
339 SandboxSection *sandboxNode = (SandboxSection *)ListEntry(node, SandboxMountNode, node);
340 DeleteSandboxSection(sandboxNode);
341 // get first
342 node = queue->front.next;
343 }
344 }
345
AppSpawnExtDataCompareDataId(ListNode * node,void * data)346 static int AppSpawnExtDataCompareDataId(ListNode *node, void *data)
347 {
348 AppSpawnExtData *extData = (AppSpawnExtData *)ListEntry(node, AppSpawnExtData, node);
349 return extData->dataId - *(uint32_t *)data;
350 }
351
GetAppSpawnSandbox(const AppSpawnMgr * content)352 AppSpawnSandboxCfg *GetAppSpawnSandbox(const AppSpawnMgr *content)
353 {
354 APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return NULL);
355 uint32_t dataId = EXT_DATA_SANDBOX;
356 ListNode *node = OH_ListFind(&content->extData, (void *)&dataId, AppSpawnExtDataCompareDataId);
357 if (node == NULL) {
358 return NULL;
359 }
360 return (AppSpawnSandboxCfg *)ListEntry(node, AppSpawnSandboxCfg, extData);
361 }
362
DeleteAppSpawnSandbox(AppSpawnSandboxCfg * sandbox)363 void DeleteAppSpawnSandbox(AppSpawnSandboxCfg *sandbox)
364 {
365 APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return);
366 APPSPAWN_LOGV("DeleteAppSpawnSandbox");
367 OH_ListRemove(&sandbox->extData.node);
368 OH_ListInit(&sandbox->extData.node);
369
370 // delete all queue
371 SandboxQueueClear(&sandbox->requiredQueue);
372 SandboxQueueClear(&sandbox->permissionQueue);
373 SandboxQueueClear(&sandbox->packageNameQueue);
374 SandboxQueueClear(&sandbox->spawnFlagsQueue);
375 SandboxQueueClear(&sandbox->nameGroupsQueue);
376 if (sandbox->rootPath) {
377 free(sandbox->rootPath);
378 }
379 free(sandbox->depGroupNodes);
380 sandbox->depGroupNodes = NULL;
381 free(sandbox);
382 sandbox = NULL;
383 }
384
DumpSandboxPermission(const SandboxMountNode * node,uint32_t index)385 static void DumpSandboxPermission(const SandboxMountNode *node, uint32_t index)
386 {
387 SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)node;
388 APPSPAPWN_DUMP(" ========================================= ");
389 APPSPAPWN_DUMP(" Section %{public}s", permissionNode->section.name);
390 APPSPAPWN_DUMP(" Section permission index %{public}d", permissionNode->permissionIndex);
391 DumpSandboxSection(&permissionNode->section);
392 }
393
DumpSandboxSectionNode(const SandboxMountNode * node,uint32_t index)394 static void DumpSandboxSectionNode(const SandboxMountNode *node, uint32_t index)
395 {
396 SandboxSection *section = (SandboxSection *)node;
397 APPSPAPWN_DUMP(" ========================================= ");
398 APPSPAPWN_DUMP(" Section %{public}s", section->name);
399 DumpSandboxSection(section);
400 }
401
DumpSandboxNameGroupNode(const SandboxMountNode * node,uint32_t index)402 static void DumpSandboxNameGroupNode(const SandboxMountNode *node, uint32_t index)
403 {
404 SandboxNameGroupNode *nameGroupNode = (SandboxNameGroupNode *)node;
405 APPSPAPWN_DUMP(" ========================================= ");
406 APPSPAPWN_DUMP(" Section %{public}s", nameGroupNode->section.name);
407 APPSPAPWN_DUMP(" Section dep mode %{public}s",
408 nameGroupNode->depMode == MOUNT_MODE_ALWAYS ? "always" : "not-exists");
409 if (nameGroupNode->depNode != NULL) {
410 APPSPAPWN_DUMP(" mount-paths-deps: ");
411 DumpMountPathMountNode(nameGroupNode->depNode);
412 }
413 DumpSandboxSection(&nameGroupNode->section);
414 }
415
416
DumpSandbox(struct TagAppSpawnExtData * data)417 static void DumpSandbox(struct TagAppSpawnExtData *data)
418 {
419 AppSpawnSandboxCfg *sandbox = (AppSpawnSandboxCfg *)data;
420 DumpAppSpawnSandboxCfg(sandbox);
421 }
422
InitSandboxQueue(SandboxQueue * queue,uint32_t type)423 static inline void InitSandboxQueue(SandboxQueue *queue, uint32_t type)
424 {
425 OH_ListInit(&queue->front);
426 queue->type = type;
427 }
428
FreeAppSpawnSandbox(struct TagAppSpawnExtData * data)429 static void FreeAppSpawnSandbox(struct TagAppSpawnExtData *data)
430 {
431 AppSpawnSandboxCfg *sandbox = ListEntry(data, AppSpawnSandboxCfg, extData);
432 // delete all var
433 DeleteAppSpawnSandbox(sandbox);
434 }
435
CreateAppSpawnSandbox(void)436 AppSpawnSandboxCfg *CreateAppSpawnSandbox(void)
437 {
438 // create sandbox
439 AppSpawnSandboxCfg *sandbox = (AppSpawnSandboxCfg *)calloc(1, sizeof(AppSpawnSandboxCfg));
440 APPSPAWN_CHECK(sandbox != NULL, return NULL, "Failed to create sandbox");
441
442 // ext data init
443 OH_ListInit(&sandbox->extData.node);
444 sandbox->extData.dataId = EXT_DATA_SANDBOX;
445 sandbox->extData.freeNode = FreeAppSpawnSandbox;
446 sandbox->extData.dumpNode = DumpSandbox;
447
448 // queue
449 InitSandboxQueue(&sandbox->requiredQueue, SANDBOX_TAG_REQUIRED);
450 InitSandboxQueue(&sandbox->permissionQueue, SANDBOX_TAG_PERMISSION);
451 InitSandboxQueue(&sandbox->packageNameQueue, SANDBOX_TAG_PACKAGE_NAME);
452 InitSandboxQueue(&sandbox->spawnFlagsQueue, SANDBOX_TAG_SPAWN_FLAGS);
453 InitSandboxQueue(&sandbox->nameGroupsQueue, SANDBOX_TAG_NAME_GROUP);
454
455 sandbox->topSandboxSwitch = 0;
456 sandbox->appFullMountEnable = 0;
457 sandbox->topSandboxSwitch = 0;
458 sandbox->pidNamespaceSupport = 0;
459 sandbox->sandboxNsFlags = 0;
460 sandbox->maxPermissionIndex = -1;
461 sandbox->depNodeCount = 0;
462 sandbox->depGroupNodes = NULL;
463
464 AddDefaultVariable();
465 AddDefaultExpandAppSandboxConfigHandle();
466 return sandbox;
467 }
468
DumpAppSpawnSandboxCfg(AppSpawnSandboxCfg * sandbox)469 void DumpAppSpawnSandboxCfg(AppSpawnSandboxCfg *sandbox)
470 {
471 APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return);
472 APPSPAPWN_DUMP("Sandbox root path: %{public}s", sandbox->rootPath);
473 APPSPAPWN_DUMP("Sandbox sandboxNsFlags: %{public}x ", sandbox->sandboxNsFlags);
474 APPSPAPWN_DUMP("Sandbox topSandboxSwitch: %{public}s", sandbox->topSandboxSwitch ? "true" : "false");
475 APPSPAPWN_DUMP("Sandbox appFullMountEnable: %{public}s", sandbox->appFullMountEnable ? "true" : "false");
476 APPSPAPWN_DUMP("Sandbox pidNamespaceSupport: %{public}s", sandbox->pidNamespaceSupport ? "true" : "false");
477 APPSPAPWN_DUMP("Sandbox common info: ");
478 DumpSandboxQueue(&sandbox->requiredQueue.front, DumpSandboxSectionNode);
479 DumpSandboxQueue(&sandbox->packageNameQueue.front, DumpSandboxSectionNode);
480 DumpSandboxQueue(&sandbox->permissionQueue.front, DumpSandboxPermission);
481 DumpSandboxQueue(&sandbox->spawnFlagsQueue.front, DumpSandboxSectionNode);
482 DumpSandboxQueue(&sandbox->nameGroupsQueue.front, DumpSandboxNameGroupNode);
483 }
484
PreLoadSandboxCfg(AppSpawnMgr * content)485 APPSPAWN_STATIC int PreLoadSandboxCfg(AppSpawnMgr *content)
486 {
487 AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content);
488 APPSPAWN_CHECK(sandbox == NULL, return 0, "Sandbox has been load");
489
490 sandbox = CreateAppSpawnSandbox();
491 APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return APPSPAWN_SYSTEM_ERROR);
492 OH_ListAddTail(&content->extData, &sandbox->extData.node);
493
494 // load app sandbox config
495 LoadAppSandboxConfig(sandbox, IsNWebSpawnMode(content));
496 sandbox->maxPermissionIndex = PermissionRenumber(&sandbox->permissionQueue);
497
498 content->content.sandboxNsFlags = 0;
499 if (IsNWebSpawnMode(content) || sandbox->pidNamespaceSupport) {
500 content->content.sandboxNsFlags = sandbox->sandboxNsFlags;
501 }
502 return 0;
503 }
504
SandboxHandleServerExit(AppSpawnMgr * content)505 APPSPAWN_STATIC int SandboxHandleServerExit(AppSpawnMgr *content)
506 {
507 AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content);
508 APPSPAWN_CHECK(sandbox != NULL, return 0, "Sandbox not load");
509
510 return 0;
511 }
512
SpawnBuildSandboxEnv(AppSpawnMgr * content,AppSpawningCtx * property)513 int SpawnBuildSandboxEnv(AppSpawnMgr *content, AppSpawningCtx *property)
514 {
515 AppSpawnSandboxCfg *appSandbox = GetAppSpawnSandbox(content);
516 APPSPAWN_CHECK(appSandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
517 // no sandbox
518 if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) {
519 return 0;
520 }
521 // CLONE_NEWPID 0x20000000
522 // CLONE_NEWNET 0x40000000
523 if ((content->content.sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID) {
524 int ret = getprocpid();
525 if (ret < 0) {
526 return ret;
527 }
528 }
529 int ret = MountSandboxConfigs(appSandbox, property, IsNWebSpawnMode(content));
530 appSandbox->mounted = 1;
531 // for module test do not create sandbox, use APP_FLAGS_IGNORE_SANDBOX to ignore sandbox result
532 if (CheckAppMsgFlagsSet(property, APP_FLAGS_IGNORE_SANDBOX)) {
533 APPSPAWN_LOGW("Do not care sandbox result %{public}d", ret);
534 return 0;
535 }
536 return ret == 0 ? 0 : APPSPAWN_SANDBOX_MOUNT_FAIL;
537 }
538
AppendPermissionGid(const AppSpawnSandboxCfg * sandbox,AppSpawningCtx * property)539 static int AppendPermissionGid(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
540 {
541 AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
542 APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
543 "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
544
545 APPSPAWN_LOGV("AppendPermissionGid %{public}s", GetProcessName(property));
546 ListNode *node = sandbox->permissionQueue.front.next;
547 while (node != &sandbox->permissionQueue.front) {
548 SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
549 if (!CheckAppPermissionFlagSet(property, (uint32_t)permissionNode->permissionIndex)) {
550 node = node->next;
551 continue;
552 }
553 if (permissionNode->section.gidCount == 0) {
554 node = node->next;
555 continue;
556 }
557 APPSPAWN_LOGV("Add permission %{public}s gid %{public}d to %{public}s",
558 permissionNode->section.name, permissionNode->section.gidTable[0], GetProcessName(property));
559
560 size_t copyLen = permissionNode->section.gidCount;
561 if ((permissionNode->section.gidCount + dacInfo->gidCount) > APP_MAX_GIDS) {
562 APPSPAWN_LOGW("More gid for %{public}s msg count %{public}u permission %{public}u",
563 GetProcessName(property), dacInfo->gidCount, permissionNode->section.gidCount);
564 copyLen = APP_MAX_GIDS - dacInfo->gidCount;
565 }
566 int ret = memcpy_s(&dacInfo->gidTable[dacInfo->gidCount], sizeof(gid_t) * copyLen,
567 permissionNode->section.gidTable, sizeof(gid_t) * copyLen);
568 if (ret != EOK) {
569 APPSPAWN_LOGW("Failed to append permission %{public}s gid to %{public}s",
570 permissionNode->section.name, GetProcessName(property));
571 node = node->next;
572 continue;
573 }
574 dacInfo->gidCount += copyLen;
575 node = node->next;
576 }
577 return 0;
578 }
579
SpawnPrepareSandboxCfg(AppSpawnMgr * content,AppSpawningCtx * property)580 int SpawnPrepareSandboxCfg(AppSpawnMgr *content, AppSpawningCtx *property)
581 {
582 APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
583 APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1);
584 APPSPAWN_LOGV("Prepare sandbox config %{public}s", GetProcessName(property));
585 AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content);
586 APPSPAWN_CHECK(sandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
587
588 if (sandbox->appFullMountEnable) {
589 int index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_CROSS_APP_MODE);
590 if (index > 0) {
591 SetAppPermissionFlags(property, index);
592 }
593 }
594 int ret = AppendPermissionGid(sandbox, property);
595 APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
596 ret = StagedMountSystemConst(sandbox, property, IsNWebSpawnMode(content));
597 APPSPAWN_CHECK(ret == 0, return ret, "Failed to mount system-const for %{public}s", GetProcessName(property));
598 return 0;
599 }
600
SandboxUnmountPath(const AppSpawnMgr * content,const AppSpawnedProcessInfo * appInfo)601 APPSPAWN_STATIC int SandboxUnmountPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo)
602 {
603 APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
604 APPSPAWN_CHECK_ONLY_EXPER(appInfo != NULL, return -1);
605 APPSPAWN_LOGV("Sandbox process %{public}s %{public}u exit", appInfo->name, appInfo->uid);
606 AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content);
607 return UnmountDepPaths(sandbox, appInfo->uid);
608 }
609
610 #ifdef APPSPAWN_SANDBOX_NEW
MODULE_CONSTRUCTOR(void)611 MODULE_CONSTRUCTOR(void)
612 {
613 APPSPAWN_LOGV("Load sandbox module ...");
614 (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadSandboxCfg);
615 (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, SandboxHandleServerExit);
616 (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_SANDBOX, SpawnPrepareSandboxCfg);
617 (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SpawnBuildSandboxEnv);
618 (void)AddProcessMgrHook(STAGE_SERVER_APP_DIED, 0, SandboxUnmountPath);
619 }
620
MODULE_DESTRUCTOR(void)621 MODULE_DESTRUCTOR(void)
622 {
623 ClearVariable();
624 ClearExpandAppSandboxConfigHandle();
625 }
626 #endif
627