1/* 2* Copyright (c) 2022 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#include "sandbox.h" 17 18#include <limits.h> 19#include <string.h> 20#include <unistd.h> 21#include <sched.h> 22#include <sys/mount.h> 23#include <sys/stat.h> 24#include <sys/syscall.h> 25#include <errno.h> 26#include "beget_ext.h" 27#include "config_policy_utils.h" 28#include "init_utils.h" 29#include "cJSON.h" 30#include "list.h" 31#include "sandbox_namespace.h" 32#include "securec.h" 33 34#define SANDBOX_ROOT_TAG "sandbox-root" 35#define SANDBOX_MOUNT_PATH_TAG "mount-bind-paths" 36#define SANDBOX_MOUNT_FILE_TAG "mount-bind-files" 37#define SANDBOX_SOURCE "src-path" 38#define SANDBOX_TARGET "sandbox-path" 39#define SANDBOX_FLAGS "sandbox-flags" 40#define SANDBOX_IGNORE_ERRORS "ignore" 41#define SANDBOX_SYMLINK_TAG "symbol-links" 42#define SANDBOX_SYMLINK_TARGET "target-name" 43#define SANDBOX_SYMLINK_NAME "link-name" 44 45#define SANDBOX_SYSTEM_CONFIG_FILE "etc/sandbox/system-sandbox.json" 46#define SANDBOX_CHIPSET_CONFIG_FILE "etc/sandbox/chipset-sandbox.json" 47 48#ifdef STARTUP_INIT_TEST 49#define SANDBOX_TEST_CONFIG_FILE "/data/init_ut/test-sandbox.json" 50#endif 51 52#define SANDBOX_MOUNT_FLAGS_MS_BIND "bind" 53#define SANDBOX_MOUNT_FLAGS_MS_PRIVATE "private" 54#define SANDBOX_MOUNT_FLAGS_MS_REC "rec" 55#define SANDBOX_MOUNT_FLAGS_MS_MOVE "move" 56 57struct SandboxMountFlags { 58 const char *flag; 59 unsigned long value; 60}; 61 62static const struct SandboxMountFlags FLAGS[] = { 63 { 64 .flag = "bind", 65 .value = MS_BIND, 66 }, 67 { 68 .flag = "private", 69 .value = MS_PRIVATE, 70 }, 71 { 72 .flag = "rec", 73 .value = MS_REC, 74 }, 75 { 76 .flag = "move", 77 .value = MS_MOVE, 78 } 79}; 80 81static sandbox_t g_systemSandbox = {}; 82static sandbox_t g_chipsetSandbox = {}; 83#ifdef STARTUP_INIT_TEST 84static sandbox_t g_testSandbox = {}; 85#endif 86 87struct SandboxMap { 88 const char *name; 89 sandbox_t *sandbox; 90 const char *configfile; 91}; 92 93static const struct SandboxMap MAP[] = { 94 { 95 .name = "system", 96 .sandbox = &g_systemSandbox, 97 .configfile = SANDBOX_SYSTEM_CONFIG_FILE, 98 }, 99 { 100 .name = "chipset", 101 .sandbox = &g_chipsetSandbox, 102 .configfile = SANDBOX_CHIPSET_CONFIG_FILE, 103 }, 104#ifdef STARTUP_INIT_TEST 105 { 106 .name = "test", 107 .sandbox = &g_testSandbox, 108 .configfile = SANDBOX_TEST_CONFIG_FILE, 109 } 110#endif 111}; 112 113static unsigned long GetSandboxMountFlags(cJSON *item) 114{ 115 BEGET_ERROR_CHECK(item != NULL, return 0, "Invalid parameter."); 116 char *str = cJSON_GetStringValue(item); 117 BEGET_CHECK(str != NULL, return 0); 118 for (size_t i = 0; i < ARRAY_LENGTH(FLAGS); i++) { 119 if (strcmp(str, FLAGS[i].flag) == 0) { 120 return FLAGS[i].value; 121 } 122 } 123 return 0; 124} 125 126static void FreeSandboxMountInfo(ListNode *list) 127{ 128 if (list == NULL) { 129 return; 130 } 131 mountlist_t *info = ListEntry(list, mountlist_t, node); 132 if (info == NULL) { 133 return; 134 } 135 if (info->source != NULL) { 136 free(info->source); 137 info->source = NULL; 138 } 139 if (info->target != NULL) { 140 free(info->target); 141 info->target = NULL; 142 } 143 free(info); 144 info = NULL; 145 return; 146} 147 148static void FreeSandboxLinkInfo(ListNode *list) 149{ 150 if (list == NULL) { 151 return; 152 } 153 linklist_t *info = ListEntry(list, linklist_t, node); 154 if (info == NULL) { 155 return; 156 } 157 if (info->target != NULL) { 158 free(info->target); 159 info->target = NULL; 160 } 161 if (info->linkName != NULL) { 162 free(info->linkName); 163 info->linkName = NULL; 164 } 165 free(info); 166 info = NULL; 167 return; 168} 169 170static int CompareSandboxListForMountTarget(ListNode *list, void *data) 171{ 172 if ((list == NULL) || (data == NULL)) { 173 return -1; 174 } 175 mountlist_t *info = ListEntry(list, mountlist_t, node); 176 if (info == NULL) { 177 return -1; 178 } 179 const char *mountTarget = (const char *)data; 180 return strcmp(info->target, mountTarget); 181} 182 183static void RemoveOldSandboxMountListNode(ListNode *head, const char *targetMount) 184{ 185 if ((head == NULL) || (targetMount == NULL)) { 186 return; 187 } 188 ListNode *node = OH_ListFind(head, (void *)targetMount, CompareSandboxListForMountTarget); 189 if (node == NULL) { 190 return; 191 } 192 OH_ListRemove(node); 193 FreeSandboxMountInfo(node); 194} 195 196static int CompareSandboxListForLinkName(ListNode *list, void *data) 197{ 198 if ((list == NULL) || (data == NULL)) { 199 return -1; 200 } 201 linklist_t *info = ListEntry(list, linklist_t, node); 202 if (info == NULL) { 203 return -1; 204 } 205 const char *linkName = (const char *)data; 206 return strcmp(info->linkName, linkName); 207} 208 209static void RemoveOldSandboxLinkListNode(ListNode *head, const char *linkName) 210{ 211 if ((head == NULL) || (linkName == NULL)) { 212 return; 213 } 214 ListNode *node = OH_ListFind(head, (void *)linkName, CompareSandboxListForLinkName); 215 if (node == NULL) { 216 return; 217 } 218 OH_ListRemove(node); 219 FreeSandboxLinkInfo(node); 220} 221 222typedef int (*AddInfoToSandboxCallback)(sandbox_t *sandbox, cJSON *item, const char *type); 223 224static int AddMountInfoToSandbox(sandbox_t *sandbox, cJSON *item, const char *type) 225{ 226 BEGET_CHECK(sandbox != NULL && item != NULL && type != NULL, return -1); 227 char *srcPath = cJSON_GetStringValue(cJSON_GetObjectItem(item, SANDBOX_SOURCE)); 228 BEGET_INFO_CHECK(srcPath != NULL, return 0, "Get src-path is null"); 229 char *dstPath = cJSON_GetStringValue(cJSON_GetObjectItem(item, SANDBOX_TARGET)); 230 BEGET_INFO_CHECK(dstPath != NULL, return 0, "Get sandbox-path is null"); 231 cJSON *obj = cJSON_GetObjectItem(item, SANDBOX_FLAGS); 232 BEGET_INFO_CHECK(obj != NULL, return 0, "Get sandbox-flags is null"); 233 int ret = cJSON_IsArray(obj); 234 BEGET_INFO_CHECK(ret, return 0, "Sandbox-flags is not array"); 235 int count = cJSON_GetArraySize(obj); 236 BEGET_INFO_CHECK(count > 0, return 0, "Get sandbox-flags array size is zero"); 237 mountlist_t *tmpMount = (mountlist_t *)calloc(1, sizeof(mountlist_t)); 238 BEGET_ERROR_CHECK(tmpMount != NULL, return -1, "Failed calloc err=%d", errno); 239 tmpMount->source = strdup(srcPath); 240 BEGET_ERROR_CHECK(tmpMount->source != NULL, free(tmpMount); return -1, "Failed to dup source"); 241 tmpMount->target = strdup(dstPath); 242 BEGET_ERROR_CHECK(tmpMount->target != NULL, free(tmpMount); return -1, "Failed to dup target"); 243 for (int i = 0; i < count; i++) { 244 cJSON *item = cJSON_GetArrayItem(obj, i); 245 tmpMount->flags |= GetSandboxMountFlags(item); 246 } 247 tmpMount->ignoreErrors = false; 248 obj = cJSON_GetObjectItem(item, SANDBOX_IGNORE_ERRORS); 249 if (obj != NULL) { 250 if (cJSON_GetNumberValue(obj) == 1) { 251 tmpMount->ignoreErrors = true; 252 } 253 } 254 OH_ListInit(&tmpMount->node); 255 if (strcmp(type, SANDBOX_MOUNT_PATH_TAG) == 0) { 256 tmpMount->tag = SANDBOX_TAG_MOUNT_PATH; 257 RemoveOldSandboxMountListNode(&sandbox->pathMountsHead, dstPath); 258 OH_ListAddTail(&sandbox->pathMountsHead, &tmpMount->node); 259 } else if (strcmp(type, SANDBOX_MOUNT_FILE_TAG) == 0) { 260 tmpMount->tag = SANDBOX_TAG_MOUNT_FILE; 261 RemoveOldSandboxMountListNode(&sandbox->fileMountsHead, dstPath); 262 OH_ListAddTail(&sandbox->fileMountsHead, &tmpMount->node); 263 } 264 return 0; 265} 266 267static int AddSymbolLinksToSandbox(sandbox_t *sandbox, cJSON *item, const char *type) 268{ 269 BEGET_CHECK(!(sandbox == NULL || item == NULL || type == NULL), return -1); 270 BEGET_ERROR_CHECK(strcmp(type, SANDBOX_SYMLINK_TAG) == 0, return -1, "Type is not sandbox symbolLink."); 271 char *target = cJSON_GetStringValue(cJSON_GetObjectItem(item, SANDBOX_SYMLINK_TARGET)); 272 BEGET_ERROR_CHECK(target != NULL, return 0, "Get target-name is null"); 273 char *name = cJSON_GetStringValue(cJSON_GetObjectItem(item, SANDBOX_SYMLINK_NAME)); 274 BEGET_ERROR_CHECK(name != NULL, return 0, "Get link-name is null"); 275 linklist_t *tmpLink = (linklist_t *)calloc(1, sizeof(linklist_t)); 276 BEGET_ERROR_CHECK(tmpLink != NULL, return -1, "Failed calloc err=%d", errno); 277 tmpLink->target = strdup(target); 278 BEGET_ERROR_CHECK(tmpLink->target != NULL, free(tmpLink); return -1, "Failed to dup target"); 279 tmpLink->linkName = strdup(name); 280 BEGET_ERROR_CHECK(tmpLink->linkName != NULL, free(tmpLink); return -1, "Failed to dup linkName"); 281 OH_ListInit(&tmpLink->node); 282 RemoveOldSandboxLinkListNode(&sandbox->linksHead, tmpLink->linkName); 283 OH_ListAddTail(&sandbox->linksHead, &tmpLink->node); 284 return 0; 285} 286 287static int GetSandboxInfo(sandbox_t *sandbox, cJSON *root, const char *itemName) 288{ 289 BEGET_ERROR_CHECK(!(sandbox == NULL || root == NULL || itemName == NULL), return -1, 290 "Get sandbox mount info with invalid argument"); 291 cJSON *obj = cJSON_GetObjectItem(root, itemName); 292 BEGET_WARNING_CHECK(obj != NULL, return 0, "Cannot find item \' %s \' in sandbox config", itemName); 293 BEGET_WARNING_CHECK(cJSON_IsArray(obj), return 0, "ItemName %s with invalid type, should be array", itemName); 294 295 int counts = cJSON_GetArraySize(obj); 296 BEGET_WARNING_CHECK(counts > 0, return 0, "Item %s array size is zero.", itemName); 297 AddInfoToSandboxCallback func = NULL; 298 if (strcmp(itemName, SANDBOX_MOUNT_PATH_TAG) == 0) { 299 func = AddMountInfoToSandbox; 300 } else if (strcmp(itemName, SANDBOX_MOUNT_FILE_TAG) == 0) { 301 func = AddMountInfoToSandbox; 302 } else if (strcmp(itemName, SANDBOX_SYMLINK_TAG) == 0) { 303 func = AddSymbolLinksToSandbox; 304 } else { 305 BEGET_LOGE("Item %s is not support.", itemName); 306 return -1; 307 } 308 for (int i = 0; i < counts; i++) { 309 cJSON *item = cJSON_GetArrayItem(obj, i); 310 BEGET_ERROR_CHECK(item != NULL, return -1, "Failed get json array item %d", i); 311 BEGET_ERROR_CHECK(func(sandbox, item, itemName) == 0, return -1, "Failed add info to sandbox."); 312 } 313 return 0; 314} 315 316static int ParseSandboxConfig(cJSON *root, sandbox_t *sandbox) 317{ 318 BEGET_ERROR_CHECK(!(root == NULL || sandbox == NULL), return -1, "Invalid parameter."); 319 // sandbox rootpath must initialize according to the system configuration, and it can only be initialized once. 320 if (sandbox->rootPath == NULL) { 321 cJSON *sandboxRoot = cJSON_GetObjectItem(root, SANDBOX_ROOT_TAG); 322 BEGET_ERROR_CHECK(sandboxRoot != NULL, return -1, 323 "Cannot find item \' %s \' in sandbox config", SANDBOX_ROOT_TAG); 324 325 char *rootdir = cJSON_GetStringValue(sandboxRoot); 326 if (rootdir != NULL) { 327 sandbox->rootPath = strdup(rootdir); 328 BEGET_ERROR_CHECK(sandbox->rootPath != NULL, return -1, 329 "Get sandbox root path out of memory"); 330 } 331 } 332 BEGET_ERROR_CHECK(GetSandboxInfo(sandbox, root, SANDBOX_MOUNT_PATH_TAG) == 0, return -1, 333 "config info %s error", SANDBOX_MOUNT_PATH_TAG); 334 BEGET_ERROR_CHECK(GetSandboxInfo(sandbox, root, SANDBOX_MOUNT_FILE_TAG) == 0, return -1, 335 "config info %s error", SANDBOX_MOUNT_FILE_TAG); 336 BEGET_ERROR_CHECK(GetSandboxInfo(sandbox, root, SANDBOX_SYMLINK_TAG) == 0, return -1, 337 "config info %s error", SANDBOX_SYMLINK_TAG); 338 return 0; 339} 340 341static const struct SandboxMap *GetSandboxMapByName(const char *name) 342{ 343 BEGET_ERROR_CHECK(name != NULL, return NULL, "Sandbox map name is NULL."); 344 int len = ARRAY_LENGTH(MAP); 345 for (int i = 0; i < len; i++) { 346 if (strcmp(MAP[i].name, name) == 0) { 347 return &MAP[i]; 348 } 349 } 350 return NULL; 351} 352 353static int ParseInitSandboxConfigFile(sandbox_t *sandbox, const char *sandboxConfigFile, const char *name) 354{ 355 char *contents = ReadFileToBuf(sandboxConfigFile); 356 if (contents == NULL) { 357 return 0; 358 } 359 cJSON *root = cJSON_Parse(contents); 360 free(contents); 361 BEGET_ERROR_CHECK(root != NULL, return -1, "Parse sandbox config \' %s \' failed", sandboxConfigFile); 362 int ret = ParseSandboxConfig(root, sandbox); 363 cJSON_Delete(root); 364 if (ret < 0) { 365 DestroySandbox(name); 366 return -1; 367 } 368 return 0; 369} 370 371static void ParseInitSandboxConfigPath(sandbox_t *sandbox, const char *sandboxConfig, const char *name) 372{ 373 CfgFiles *files = GetCfgFiles(sandboxConfig); 374 for (int i = 0; files && i < MAX_CFG_POLICY_DIRS_CNT; i++) { 375 if (files->paths[i]) { 376 BEGET_LOGI("Parse sandbox cfg file is %s", files->paths[i]); 377 if (ParseInitSandboxConfigFile(sandbox, files->paths[i], name) < 0) { 378 break; 379 } 380 } 381 } 382 FreeCfgFiles(files); 383} 384 385static void InitSandbox(sandbox_t *sandbox, const char *sandboxConfig, const char *name) 386{ 387 BEGET_ERROR_CHECK(!(sandbox == NULL || sandboxConfig == NULL || name == NULL), return, 388 "Init sandbox with invalid arguments"); 389 if (sandbox->isCreated) { 390 BEGET_LOGE("Sandbox %s has created.", name); 391 return; 392 } 393 if (UnshareNamespace(CLONE_NEWNS) < 0) { 394 return; 395 } 396 sandbox->ns = GetNamespaceFd("/proc/self/ns/mnt"); 397 BEGET_ERROR_CHECK(!(sandbox->ns < 0), return, "Get sandbox namespace fd is failed"); 398 399 BEGET_ERROR_CHECK(strcpy_s(sandbox->name, MAX_BUFFER_LEN - 1, name) == 0, return, "Failed to copy sandbox name"); 400 OH_ListInit(&sandbox->pathMountsHead); 401 OH_ListInit(&sandbox->fileMountsHead); 402 OH_ListInit(&sandbox->linksHead); 403 // parse json config 404#ifdef STARTUP_INIT_TEST 405 (void)ParseInitSandboxConfigFile(sandbox, sandboxConfig, name); 406#else 407 ParseInitSandboxConfigPath(sandbox, sandboxConfig, name); 408#endif 409 return; 410} 411 412static int CheckAndMakeDir(const char *dir, mode_t mode) 413{ 414 struct stat sb; 415 416 if ((stat(dir, &sb) == 0) && S_ISDIR(sb.st_mode)) { 417 BEGET_LOGI("Mount point \' %s \' already exist, no need to mkdir", dir); 418 return 0; 419 } else { 420 if (errno == ENOENT) { 421 BEGET_ERROR_CHECK(MakeDirRecursive(dir, mode) == 0, return -1, 422 "Failed MakeDirRecursive %s, err=%d", dir, errno); 423 } else { 424 BEGET_LOGW("Failed to access mount point \' %s \', err = %d", dir, errno); 425 return -1; 426 } 427 } 428 return 0; 429} 430 431static int BindMount(const char *source, const char *target, unsigned long flags, SandboxTag tag) 432{ 433 if (source == NULL || target == NULL) { 434 BEGET_LOGE("Mount with invalid arguments"); 435 errno = EINVAL; 436 return -1; 437 } 438 unsigned long tmpflags = flags; 439 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 440 if (tag == SANDBOX_TAG_MOUNT_PATH) { 441 BEGET_ERROR_CHECK(CheckAndMakeDir(target, mode) == 0, return -1, "Failed make %s dir.", target); 442 } else if (tag == SANDBOX_TAG_MOUNT_FILE) { 443 BEGET_ERROR_CHECK(CheckAndCreatFile(target, mode) == 0, return -1, "Failed make %s file.", target); 444 } else { 445 BEGET_LOGE("Tag is error."); 446 return -1; 447 } 448 449 BEGET_WARNING_CHECK((tmpflags & MS_BIND) != 0, tmpflags |= MS_BIND, 450 "Not configure mount bind, must configure mount bind flag."); 451 452 // do mount 453 if (mount(source, target, NULL, tmpflags, NULL) != 0) { 454 BEGET_LOGE("Failed to bind mount \' %s \' to \' %s \', err = %d", source, target, errno); 455 if (errno != ENOTDIR) { // mount errno is 'Not a directory' can ignore 456 return -1; 457 } 458 } 459 460 return 0; 461} 462 463static bool IsValidSandbox(sandbox_t *sandbox) 464{ 465 BEGET_ERROR_CHECK(sandbox != NULL, return false, "preparing sandbox with invalid argument"); 466 467 if (sandbox->rootPath == NULL) { 468 return false; 469 } 470 471 return true; 472} 473 474static int MountSandboxNode(ListNode *list, void *data) 475{ 476 if ((list == NULL) || (data == NULL)) { 477 return 0; 478 } 479 const char *rootPath = (const char *)data; 480 mountlist_t *info = ListEntry(list, mountlist_t, node); 481 char target[PATH_MAX] = {}; 482 BEGET_ERROR_CHECK(snprintf_s(target, PATH_MAX, PATH_MAX - 1, "%s%s", rootPath, info->target) > 0, 483 return -1, "Failed snprintf_s err=%d", errno); 484 int rc = BindMount(info->source, target, info->flags, info->tag); 485 if (rc != 0) { 486 BEGET_LOGW("Failed bind mount %s to %s.", info->source, target); 487 if (info->ignoreErrors == false) { 488 return -1; 489 } 490 } 491 return 0; 492} 493 494static int MountSandboxInfo(struct ListNode *head, const char *rootPath, SandboxTag tag) 495{ 496 if ((head == NULL) || (rootPath == NULL)) { 497 return 0; 498 } 499 int ret = OH_ListTraversal(head, (void *)rootPath, MountSandboxNode, 1); 500 return ret; 501} 502 503static int LinkSandboxNode(ListNode *list, void *data) 504{ 505 if ((list == NULL) || (data == NULL)) { 506 return 0; 507 } 508 const char *rootPath = (const char *)data; 509 linklist_t *info = ListEntry(list, linklist_t, node); 510 char linkName[PATH_MAX] = {0}; 511 BEGET_ERROR_CHECK(!(snprintf_s(linkName, PATH_MAX, PATH_MAX - 1, "%s%s", rootPath, info->linkName) < 0), 512 return -1, "snprintf_s failed, err=%d", errno); 513 int rc = symlink(info->target, linkName); 514 if (rc != 0) { 515 if (errno == EEXIST) { 516 BEGET_LOGW("symbol link name \' %s \' already exist", linkName); 517 } else { 518 BEGET_LOGE("Failed to link \' %s \' to \' %s \', err = %d", info->target, linkName, errno); 519 return -1; 520 } 521 } 522 return 0; 523} 524 525static int LinkSandboxInfo(struct ListNode *head, const char *rootPath) 526{ 527 if ((head == NULL) || (rootPath == NULL)) { 528 return 0; 529 } 530 int ret = OH_ListTraversal(head, (void *)rootPath, LinkSandboxNode, 1); 531 return ret; 532} 533 534int PrepareSandbox(const char *name) 535{ 536 BEGET_ERROR_CHECK(name != NULL, return -1, "Prepare sandbox name is NULL."); 537 BEGET_ERROR_CHECK(getuid() == 0, return -1, "Current process uid is not root, exit."); 538 const struct SandboxMap *map = GetSandboxMapByName(name); 539 BEGET_ERROR_CHECK(map != NULL, return -1, "Cannot get sandbox map by name %s.", name); 540 sandbox_t *sandbox = map->sandbox; 541 BEGET_CHECK(IsValidSandbox(sandbox) == true, return -1); 542 BEGET_INFO_CHECK(sandbox->isCreated == false, return 0, "Sandbox %s already created", sandbox->name); 543 BEGET_CHECK(sandbox->rootPath != NULL, return -1); 544 mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 545 BEGET_ERROR_CHECK(CheckAndMakeDir(sandbox->rootPath, mode) == 0, return -1, "Failed root %s.", sandbox->rootPath); 546 int rc = mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL); 547 BEGET_ERROR_CHECK(rc == 0, return -1, "Failed set mount slave err = %d", errno); 548 rc = BindMount(sandbox->rootPath, sandbox->rootPath, MS_BIND | MS_REC, SANDBOX_TAG_MOUNT_PATH); 549 BEGET_ERROR_CHECK(rc == 0, return -1, "Failed to mount rootpath bind err = %d", errno); 550 551 // 1) walk through all mounts and do bind mount 552 rc = MountSandboxInfo(&sandbox->pathMountsHead, sandbox->rootPath, SANDBOX_TAG_MOUNT_PATH); 553 BEGET_CHECK(rc == 0, return -1); 554 555 rc = MountSandboxInfo(&sandbox->fileMountsHead, sandbox->rootPath, SANDBOX_TAG_MOUNT_FILE); 556 BEGET_CHECK(rc == 0, return -1); 557 558 // 2) walk through all links and do symbol link 559 rc = LinkSandboxInfo(&sandbox->linksHead, sandbox->rootPath); 560 BEGET_CHECK(rc == 0, return -1); 561 562 BEGET_ERROR_CHECK(chdir(sandbox->rootPath) == 0, return -1, "Change to %s, err = %d", sandbox->rootPath, errno); 563 BEGET_ERROR_CHECK(syscall(SYS_pivot_root, sandbox->rootPath, sandbox->rootPath) == 0, return -1, 564 "Failed system call pivot root, err=%d", errno); 565 BEGET_ERROR_CHECK(umount2(".", MNT_DETACH) == 0, return -1, "Failed umount2 MNT_DETACH, err=%d", errno); 566 sandbox->isCreated = true; 567 return 0; 568} 569 570bool InitSandboxWithName(const char *name) 571{ 572 bool isFound = false; 573 if (name == NULL) { 574 BEGET_LOGE("Init sandbox name is NULL."); 575 return isFound; 576 } 577 const struct SandboxMap *map = GetSandboxMapByName(name); 578 if (map != NULL) { 579 InitSandbox(map->sandbox, map->configfile, name); 580 isFound = true; 581 } 582 583 if (!isFound) { 584 BEGET_LOGE("Cannot find sandbox with name %s.", name); 585 } 586 return isFound; 587} 588 589void DestroySandbox(const char *name) 590{ 591 if (name == NULL) { 592 BEGET_LOGE("Destroy sandbox name is NULL."); 593 return; 594 } 595 const struct SandboxMap *map = GetSandboxMapByName(name); 596 if (map == NULL) { 597 BEGET_LOGE("Cannot get sandbox map by name %s.", name); 598 return; 599 } 600 sandbox_t *sandbox = map->sandbox; 601 602 BEGET_CHECK(sandbox != NULL, return); 603 604 if (sandbox->rootPath != NULL) { 605 free(sandbox->rootPath); 606 sandbox->rootPath = NULL; 607 } 608 OH_ListRemoveAll(&sandbox->linksHead, FreeSandboxLinkInfo); 609 OH_ListRemoveAll(&sandbox->fileMountsHead, FreeSandboxMountInfo); 610 OH_ListRemoveAll(&sandbox->pathMountsHead, FreeSandboxMountInfo); 611 612 if (sandbox->ns > 0) { 613 (void)close(sandbox->ns); 614 } 615 sandbox->isCreated = false; 616 return; 617} 618 619int EnterSandbox(const char *name) 620{ 621 if (name == NULL) { 622 BEGET_LOGE("Sandbox name is NULL."); 623 return -1; 624 } 625 const struct SandboxMap *map = GetSandboxMapByName(name); 626 if (map == NULL) { 627 BEGET_LOGE("Cannot get sandbox map by name %s.", name); 628 return -1; 629 } 630 sandbox_t *sandbox = map->sandbox; 631 632 BEGET_CHECK(sandbox != NULL, return -1); 633 if (sandbox->isCreated == false) { 634 BEGET_LOGE("Sandbox %s has not been created.", name); 635 return -1; 636 } 637 if (sandbox->ns > 0) { 638 BEGET_ERROR_CHECK(!(SetNamespace(sandbox->ns, CLONE_NEWNS) < 0), return -1, 639 "Cannot enter mount namespace for sandbox \' %s \', err=%d.", name, errno); 640 } else { 641 BEGET_LOGE("Sandbox \' %s \' namespace fd is invalid.", name); 642 return -1; 643 } 644 return 0; 645} 646 647static int DumpSandboxMountInfo(ListNode *list, void *data) 648{ 649 if (list == NULL) { 650 return -1; 651 } 652 mountlist_t *info = ListEntry(list, mountlist_t, node); 653 if (info != NULL) { 654 if (info->source != NULL) { 655 printf("Sandbox mounts list source: %s \n", info->source); 656 } 657 if (info->target != NULL) { 658 printf("Sandbox mounts list target: %s \n", info->target); 659 } 660 } 661 return 0; 662} 663 664static int DumpSandboxLinkInfo(ListNode *list, void *data) 665{ 666 if (list == NULL) { 667 return -1; 668 } 669 linklist_t *info = ListEntry(list, linklist_t, node); 670 if (info != NULL) { 671 if (info->linkName != NULL) { 672 printf("Sandbox link list name: %s \n", info->linkName); 673 } 674 if (info->target != NULL) { 675 printf("Sandbox link list target: %s \n", info->target); 676 } 677 } 678 return 0; 679} 680 681void DumpSandboxByName(const char *name) 682{ 683 if (name == NULL) { 684 BEGET_LOGE("Init sandbox name is NULL."); 685 return; 686 } 687 const struct SandboxMap *map = GetSandboxMapByName(name); 688 if (map == NULL) { 689 return; 690 } 691 printf("Sandbox Map name: %s \n", map->name); 692 printf("Sandbox Map config file: %s. \n", map->configfile); 693 printf("Sandbox name: %s. \n", map->sandbox->name); 694 printf("Sandbox root path is %s. \n", map->sandbox->rootPath); 695 printf("Sandbox mounts info: \n"); 696 OH_ListTraversal(&map->sandbox->pathMountsHead, NULL, DumpSandboxMountInfo, 0); 697 OH_ListTraversal(&map->sandbox->fileMountsHead, NULL, DumpSandboxMountInfo, 0); 698 printf("Sandbox links info: \n"); 699 OH_ListTraversal(&map->sandbox->linksHead, NULL, DumpSandboxLinkInfo, 0); 700 return; 701} 702