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