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