169570cc8Sopenharmony_ci/*
269570cc8Sopenharmony_ci * Copyright (C) 2024 Huawei Device Co., Ltd.
369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License.
569570cc8Sopenharmony_ci * You may obtain a copy of the License at
669570cc8Sopenharmony_ci *
769570cc8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
869570cc8Sopenharmony_ci *
969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and
1369570cc8Sopenharmony_ci * limitations under the License.
1469570cc8Sopenharmony_ci */
1569570cc8Sopenharmony_ci
1669570cc8Sopenharmony_ci#undef _GNU_SOURCE
1769570cc8Sopenharmony_ci#define _GNU_SOURCE
1869570cc8Sopenharmony_ci#include <sched.h>
1969570cc8Sopenharmony_ci
2069570cc8Sopenharmony_ci#include "appspawn_manager.h"
2169570cc8Sopenharmony_ci#include "appspawn_permission.h"
2269570cc8Sopenharmony_ci#include "appspawn_sandbox.h"
2369570cc8Sopenharmony_ci#include "appspawn_utils.h"
2469570cc8Sopenharmony_ci#include "modulemgr.h"
2569570cc8Sopenharmony_ci#include "parameter.h"
2669570cc8Sopenharmony_ci#include "securec.h"
2769570cc8Sopenharmony_ci
2869570cc8Sopenharmony_cistatic void FreePathMountNode(SandboxMountNode *node)
2969570cc8Sopenharmony_ci{
3069570cc8Sopenharmony_ci    PathMountNode *sandboxNode = (PathMountNode *)node;
3169570cc8Sopenharmony_ci    if (sandboxNode->source) {
3269570cc8Sopenharmony_ci        free(sandboxNode->source);
3369570cc8Sopenharmony_ci        sandboxNode->source = NULL;
3469570cc8Sopenharmony_ci    }
3569570cc8Sopenharmony_ci    if (sandboxNode->target) {
3669570cc8Sopenharmony_ci        free(sandboxNode->target);
3769570cc8Sopenharmony_ci        sandboxNode->target = NULL;
3869570cc8Sopenharmony_ci    }
3969570cc8Sopenharmony_ci    if (sandboxNode->appAplName) {
4069570cc8Sopenharmony_ci        free(sandboxNode->appAplName);
4169570cc8Sopenharmony_ci        sandboxNode->appAplName = NULL;
4269570cc8Sopenharmony_ci    }
4369570cc8Sopenharmony_ci    free(sandboxNode);
4469570cc8Sopenharmony_ci}
4569570cc8Sopenharmony_ci
4669570cc8Sopenharmony_cistatic void FreeSymbolLinkNode(SandboxMountNode *node)
4769570cc8Sopenharmony_ci{
4869570cc8Sopenharmony_ci    SymbolLinkNode *sandboxNode = (SymbolLinkNode *)node;
4969570cc8Sopenharmony_ci    if (sandboxNode->target) {
5069570cc8Sopenharmony_ci        free(sandboxNode->target);
5169570cc8Sopenharmony_ci        sandboxNode->target = NULL;
5269570cc8Sopenharmony_ci    }
5369570cc8Sopenharmony_ci    if (sandboxNode->linkName) {
5469570cc8Sopenharmony_ci        free(sandboxNode->linkName);
5569570cc8Sopenharmony_ci        sandboxNode->linkName = NULL;
5669570cc8Sopenharmony_ci    }
5769570cc8Sopenharmony_ci    free(sandboxNode);
5869570cc8Sopenharmony_ci}
5969570cc8Sopenharmony_ci
6069570cc8Sopenharmony_cistatic int SandboxNodeCompareProc(ListNode *node, ListNode *newNode)
6169570cc8Sopenharmony_ci{
6269570cc8Sopenharmony_ci    SandboxMountNode *sandbox1 = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node);
6369570cc8Sopenharmony_ci    SandboxMountNode *sandbox2 = (SandboxMountNode *)ListEntry(newNode, SandboxMountNode, node);
6469570cc8Sopenharmony_ci    return sandbox1->type - sandbox2->type;
6569570cc8Sopenharmony_ci}
6669570cc8Sopenharmony_ci
6769570cc8Sopenharmony_ciSandboxMountNode *CreateSandboxMountNode(uint32_t dataLen, uint32_t type)
6869570cc8Sopenharmony_ci{
6969570cc8Sopenharmony_ci    APPSPAWN_CHECK(dataLen >= sizeof(SandboxMountNode) && dataLen <= sizeof(PathMountNode),
7069570cc8Sopenharmony_ci        return NULL, "Invalid dataLen %{public}u", dataLen);
7169570cc8Sopenharmony_ci    SandboxMountNode *node = (SandboxMountNode *)calloc(1, dataLen);
7269570cc8Sopenharmony_ci    APPSPAWN_CHECK(node != NULL, return NULL, "Failed to create mount node %{public}u", type);
7369570cc8Sopenharmony_ci    OH_ListInit(&node->node);
7469570cc8Sopenharmony_ci    node->type = type;
7569570cc8Sopenharmony_ci    return node;
7669570cc8Sopenharmony_ci}
7769570cc8Sopenharmony_ci
7869570cc8Sopenharmony_civoid AddSandboxMountNode(SandboxMountNode *node, SandboxSection *queue)
7969570cc8Sopenharmony_ci{
8069570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(node != NULL, return);
8169570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(queue != NULL, return);
8269570cc8Sopenharmony_ci    OH_ListAddWithOrder(&queue->front, &node->node, SandboxNodeCompareProc);
8369570cc8Sopenharmony_ci}
8469570cc8Sopenharmony_ci
8569570cc8Sopenharmony_cistatic int PathMountNodeCompare(ListNode *node, void *data)
8669570cc8Sopenharmony_ci{
8769570cc8Sopenharmony_ci    PathMountNode *node1 = (PathMountNode *)ListEntry(node, SandboxMountNode, node);
8869570cc8Sopenharmony_ci    PathMountNode *node2 = (PathMountNode *)data;
8969570cc8Sopenharmony_ci    return (node1->sandboxNode.type == node2->sandboxNode.type) &&
9069570cc8Sopenharmony_ci        (strcmp(node1->source, node2->source) == 0) &&
9169570cc8Sopenharmony_ci        (strcmp(node1->target, node2->target) == 0) ? 0 : 1;
9269570cc8Sopenharmony_ci}
9369570cc8Sopenharmony_ci
9469570cc8Sopenharmony_cistatic int SymbolLinkNodeCompare(ListNode *node, void *data)
9569570cc8Sopenharmony_ci{
9669570cc8Sopenharmony_ci    SymbolLinkNode *node1 = (SymbolLinkNode *)ListEntry(node, SandboxMountNode, node);
9769570cc8Sopenharmony_ci    SymbolLinkNode *node2 = (SymbolLinkNode *)data;
9869570cc8Sopenharmony_ci    return (node1->sandboxNode.type == node2->sandboxNode.type) &&
9969570cc8Sopenharmony_ci        (strcmp(node1->target, node2->target) == 0) &&
10069570cc8Sopenharmony_ci        (strcmp(node1->linkName, node2->linkName) == 0) ? 0 : 1;
10169570cc8Sopenharmony_ci}
10269570cc8Sopenharmony_ci
10369570cc8Sopenharmony_ciPathMountNode *GetPathMountNode(const SandboxSection *section, int type, const char *source, const char *target)
10469570cc8Sopenharmony_ci{
10569570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(section != NULL, return NULL);
10669570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(source != NULL && target != NULL, return NULL);
10769570cc8Sopenharmony_ci    PathMountNode pathNode = {};
10869570cc8Sopenharmony_ci    pathNode.sandboxNode.type = type;
10969570cc8Sopenharmony_ci    pathNode.source = (char *)source;
11069570cc8Sopenharmony_ci    pathNode.target = (char *)target;
11169570cc8Sopenharmony_ci    ListNode *node = OH_ListFind(&section->front, (void *)&pathNode, PathMountNodeCompare);
11269570cc8Sopenharmony_ci    if (node == NULL) {
11369570cc8Sopenharmony_ci        return NULL;
11469570cc8Sopenharmony_ci    }
11569570cc8Sopenharmony_ci    return (PathMountNode *)ListEntry(node, SandboxMountNode, node);
11669570cc8Sopenharmony_ci}
11769570cc8Sopenharmony_ci
11869570cc8Sopenharmony_ciSymbolLinkNode *GetSymbolLinkNode(const SandboxSection *section, const char *target, const char *linkName)
11969570cc8Sopenharmony_ci{
12069570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(section != NULL, return NULL);
12169570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(linkName != NULL && target != NULL, return NULL);
12269570cc8Sopenharmony_ci    SymbolLinkNode linkNode = {};
12369570cc8Sopenharmony_ci    linkNode.sandboxNode.type = SANDBOX_TAG_SYMLINK;
12469570cc8Sopenharmony_ci    linkNode.target = (char *)target;
12569570cc8Sopenharmony_ci    linkNode.linkName = (char *)linkName;
12669570cc8Sopenharmony_ci    ListNode *node = OH_ListFind(&section->front, (void *)&linkNode, SymbolLinkNodeCompare);
12769570cc8Sopenharmony_ci    if (node == NULL) {
12869570cc8Sopenharmony_ci        return NULL;
12969570cc8Sopenharmony_ci    }
13069570cc8Sopenharmony_ci    return (SymbolLinkNode *)ListEntry(node, SandboxMountNode, node);
13169570cc8Sopenharmony_ci}
13269570cc8Sopenharmony_ci
13369570cc8Sopenharmony_civoid DeleteSandboxMountNode(SandboxMountNode *sandboxNode)
13469570cc8Sopenharmony_ci{
13569570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(sandboxNode != NULL, return);
13669570cc8Sopenharmony_ci    OH_ListRemove(&sandboxNode->node);
13769570cc8Sopenharmony_ci    OH_ListInit(&sandboxNode->node);
13869570cc8Sopenharmony_ci    switch (sandboxNode->type) {
13969570cc8Sopenharmony_ci        case SANDBOX_TAG_MOUNT_PATH:
14069570cc8Sopenharmony_ci        case SANDBOX_TAG_MOUNT_FILE:
14169570cc8Sopenharmony_ci            FreePathMountNode(sandboxNode);
14269570cc8Sopenharmony_ci            break;
14369570cc8Sopenharmony_ci        case SANDBOX_TAG_SYMLINK:
14469570cc8Sopenharmony_ci            FreeSymbolLinkNode(sandboxNode);
14569570cc8Sopenharmony_ci            break;
14669570cc8Sopenharmony_ci        default:
14769570cc8Sopenharmony_ci            APPSPAWN_LOGE("Invalid type %{public}u", sandboxNode->type);
14869570cc8Sopenharmony_ci            free(sandboxNode);
14969570cc8Sopenharmony_ci            break;
15069570cc8Sopenharmony_ci    }
15169570cc8Sopenharmony_ci}
15269570cc8Sopenharmony_ci
15369570cc8Sopenharmony_ciSandboxMountNode *GetFirstSandboxMountNode(const SandboxSection *section)
15469570cc8Sopenharmony_ci{
15569570cc8Sopenharmony_ci    if (section == NULL || ListEmpty(section->front)) {
15669570cc8Sopenharmony_ci        return NULL;
15769570cc8Sopenharmony_ci    }
15869570cc8Sopenharmony_ci    return (SandboxMountNode *)ListEntry(section->front.next, SandboxMountNode, node);
15969570cc8Sopenharmony_ci}
16069570cc8Sopenharmony_ci
16169570cc8Sopenharmony_civoid DumpSandboxMountNode(const SandboxMountNode *sandboxNode, uint32_t index)
16269570cc8Sopenharmony_ci{
16369570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(sandboxNode != NULL, return);
16469570cc8Sopenharmony_ci    switch (sandboxNode->type) {
16569570cc8Sopenharmony_ci        case SANDBOX_TAG_MOUNT_PATH:
16669570cc8Sopenharmony_ci        case SANDBOX_TAG_MOUNT_FILE: {
16769570cc8Sopenharmony_ci            PathMountNode *pathNode = (PathMountNode *)sandboxNode;
16869570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        ****************************** %{public}u", index);
16969570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        sandbox node source: %{public}s", pathNode->source ? pathNode->source : "null");
17069570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        sandbox node target: %{public}s", pathNode->target ? pathNode->target : "null");
17169570cc8Sopenharmony_ci            DumpMountPathMountNode(pathNode);
17269570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        sandbox node apl: %{public}s",
17369570cc8Sopenharmony_ci                pathNode->appAplName ? pathNode->appAplName : "null");
17469570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        sandbox node checkErrorFlag: %{public}s",
17569570cc8Sopenharmony_ci                pathNode->checkErrorFlag ? "true" : "false");
17669570cc8Sopenharmony_ci            break;
17769570cc8Sopenharmony_ci        }
17869570cc8Sopenharmony_ci        case SANDBOX_TAG_SYMLINK: {
17969570cc8Sopenharmony_ci            SymbolLinkNode *linkNode = (SymbolLinkNode *)sandboxNode;
18069570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        ***********************************");
18169570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        sandbox node target: %{public}s", linkNode->target ? linkNode->target : "null");
18269570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        sandbox node linkName: %{public}s",
18369570cc8Sopenharmony_ci                linkNode->linkName ? linkNode->linkName : "null");
18469570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        sandbox node destMode: %{public}x", linkNode->destMode);
18569570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        sandbox node checkErrorFlag: %{public}s",
18669570cc8Sopenharmony_ci                linkNode->checkErrorFlag ? "true" : "false");
18769570cc8Sopenharmony_ci            break;
18869570cc8Sopenharmony_ci        }
18969570cc8Sopenharmony_ci        default:
19069570cc8Sopenharmony_ci            break;
19169570cc8Sopenharmony_ci    }
19269570cc8Sopenharmony_ci}
19369570cc8Sopenharmony_ci
19469570cc8Sopenharmony_cistatic inline void InitSandboxSection(SandboxSection *section, int type)
19569570cc8Sopenharmony_ci{
19669570cc8Sopenharmony_ci    OH_ListInit(&section->front);
19769570cc8Sopenharmony_ci    section->sandboxSwitch = 0;
19869570cc8Sopenharmony_ci    section->sandboxShared = 0;
19969570cc8Sopenharmony_ci    section->number = 0;
20069570cc8Sopenharmony_ci    section->gidCount = 0;
20169570cc8Sopenharmony_ci    section->gidTable = NULL;
20269570cc8Sopenharmony_ci    section->nameGroups = NULL;
20369570cc8Sopenharmony_ci    section->name = NULL;
20469570cc8Sopenharmony_ci    OH_ListInit(&section->sandboxNode.node);
20569570cc8Sopenharmony_ci    section->sandboxNode.type = type;
20669570cc8Sopenharmony_ci}
20769570cc8Sopenharmony_ci
20869570cc8Sopenharmony_cistatic void ClearSandboxSection(SandboxSection *section)
20969570cc8Sopenharmony_ci{
21069570cc8Sopenharmony_ci    if (section->gidTable) {
21169570cc8Sopenharmony_ci        free(section->gidTable);
21269570cc8Sopenharmony_ci        section->gidTable = NULL;
21369570cc8Sopenharmony_ci    }
21469570cc8Sopenharmony_ci    // free name group
21569570cc8Sopenharmony_ci    if (section->nameGroups) {
21669570cc8Sopenharmony_ci        free(section->nameGroups);
21769570cc8Sopenharmony_ci        section->nameGroups = NULL;
21869570cc8Sopenharmony_ci    }
21969570cc8Sopenharmony_ci    if (section->name) {
22069570cc8Sopenharmony_ci        free(section->name);
22169570cc8Sopenharmony_ci        section->name = NULL;
22269570cc8Sopenharmony_ci    }
22369570cc8Sopenharmony_ci    if (section->sandboxNode.type == SANDBOX_TAG_NAME_GROUP) {
22469570cc8Sopenharmony_ci        SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)section;
22569570cc8Sopenharmony_ci        if (groupNode->depNode) {
22669570cc8Sopenharmony_ci            DeleteSandboxMountNode((SandboxMountNode *)groupNode->depNode);
22769570cc8Sopenharmony_ci        }
22869570cc8Sopenharmony_ci    }
22969570cc8Sopenharmony_ci    // free mount path
23069570cc8Sopenharmony_ci    ListNode *node = section->front.next;
23169570cc8Sopenharmony_ci    while (node != &section->front) {
23269570cc8Sopenharmony_ci        SandboxMountNode *sandboxNode = ListEntry(node, SandboxMountNode, node);
23369570cc8Sopenharmony_ci        // delete node
23469570cc8Sopenharmony_ci        OH_ListRemove(&sandboxNode->node);
23569570cc8Sopenharmony_ci        OH_ListInit(&sandboxNode->node);
23669570cc8Sopenharmony_ci        DeleteSandboxMountNode(sandboxNode);
23769570cc8Sopenharmony_ci        // get next
23869570cc8Sopenharmony_ci        node = section->front.next;
23969570cc8Sopenharmony_ci    }
24069570cc8Sopenharmony_ci}
24169570cc8Sopenharmony_ci
24269570cc8Sopenharmony_cistatic void DumpSandboxQueue(const ListNode *front,
24369570cc8Sopenharmony_ci    void (*dumpSandboxMountNode)(const SandboxMountNode *node, uint32_t count))
24469570cc8Sopenharmony_ci{
24569570cc8Sopenharmony_ci    uint32_t count = 0;
24669570cc8Sopenharmony_ci    ListNode *node = front->next;
24769570cc8Sopenharmony_ci    while (node != front) {
24869570cc8Sopenharmony_ci        SandboxMountNode *sandboxNode = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node);
24969570cc8Sopenharmony_ci        count++;
25069570cc8Sopenharmony_ci        dumpSandboxMountNode(sandboxNode, count);
25169570cc8Sopenharmony_ci        // get next
25269570cc8Sopenharmony_ci        node = node->next;
25369570cc8Sopenharmony_ci    }
25469570cc8Sopenharmony_ci}
25569570cc8Sopenharmony_ci
25669570cc8Sopenharmony_cistatic void DumpSandboxSection(const SandboxSection *section)
25769570cc8Sopenharmony_ci{
25869570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    sandboxSwitch %{public}s", section->sandboxSwitch ? "true" : "false");
25969570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    sandboxShared %{public}s", section->sandboxShared ? "true" : "false");
26069570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    gidCount: %{public}u", section->gidCount);
26169570cc8Sopenharmony_ci    for (uint32_t index = 0; index < section->gidCount; index++) {
26269570cc8Sopenharmony_ci        APPSPAPWN_DUMP("        gidTable[%{public}u]: %{public}u", index, section->gidTable[index]);
26369570cc8Sopenharmony_ci    }
26469570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    mount group count: %{public}u", section->number);
26569570cc8Sopenharmony_ci    for (uint32_t i = 0; i < section->number; i++) {
26669570cc8Sopenharmony_ci        if (section->nameGroups[i]) {
26769570cc8Sopenharmony_ci            SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)section->nameGroups[i];
26869570cc8Sopenharmony_ci            APPSPAPWN_DUMP("        name[%{public}d] %{public}s", i, groupNode->section.name);
26969570cc8Sopenharmony_ci        }
27069570cc8Sopenharmony_ci    }
27169570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    mount-paths: ");
27269570cc8Sopenharmony_ci    DumpSandboxQueue(&section->front, DumpSandboxMountNode);
27369570cc8Sopenharmony_ci}
27469570cc8Sopenharmony_ci
27569570cc8Sopenharmony_ciSandboxSection *CreateSandboxSection(const char *name, uint32_t dataLen, uint32_t type)
27669570cc8Sopenharmony_ci{
27769570cc8Sopenharmony_ci    APPSPAWN_CHECK(type < SANDBOX_TAG_INVALID && type >= SANDBOX_TAG_PERMISSION,
27869570cc8Sopenharmony_ci        return NULL, "Invalid type %{public}u", type);
27969570cc8Sopenharmony_ci    APPSPAWN_CHECK(name != NULL && strlen(name) > 0, return NULL, "Invalid name %{public}u", type);
28069570cc8Sopenharmony_ci    APPSPAWN_CHECK(dataLen >= sizeof(SandboxSection), return NULL, "Invalid dataLen %{public}u", dataLen);
28169570cc8Sopenharmony_ci    APPSPAWN_CHECK(dataLen <= sizeof(SandboxNameGroupNode), return NULL, "Invalid dataLen %{public}u", dataLen);
28269570cc8Sopenharmony_ci    SandboxSection *section = (SandboxSection *)calloc(1, dataLen);
28369570cc8Sopenharmony_ci    APPSPAWN_CHECK(section != NULL, return NULL, "Failed to create base node");
28469570cc8Sopenharmony_ci    InitSandboxSection(section, type);
28569570cc8Sopenharmony_ci    section->name = strdup(name);
28669570cc8Sopenharmony_ci    if (section->name == NULL) {
28769570cc8Sopenharmony_ci        ClearSandboxSection(section);
28869570cc8Sopenharmony_ci        free(section);
28969570cc8Sopenharmony_ci        return NULL;
29069570cc8Sopenharmony_ci    }
29169570cc8Sopenharmony_ci    return section;
29269570cc8Sopenharmony_ci}
29369570cc8Sopenharmony_ci
29469570cc8Sopenharmony_cistatic int SandboxConditionalNodeCompareName(ListNode *node, void *data)
29569570cc8Sopenharmony_ci{
29669570cc8Sopenharmony_ci    SandboxSection *tmpNode = (SandboxSection *)ListEntry(node, SandboxMountNode, node);
29769570cc8Sopenharmony_ci    return strcmp(tmpNode->name, (char *)data);
29869570cc8Sopenharmony_ci}
29969570cc8Sopenharmony_ci
30069570cc8Sopenharmony_cistatic int SandboxConditionalNodeCompareNode(ListNode *node, ListNode *newNode)
30169570cc8Sopenharmony_ci{
30269570cc8Sopenharmony_ci    SandboxSection *tmpNode = (SandboxSection *)ListEntry(node, SandboxMountNode, node);
30369570cc8Sopenharmony_ci    SandboxSection *tmpNewNode = (SandboxSection *)ListEntry(newNode, SandboxMountNode, node);
30469570cc8Sopenharmony_ci    return strcmp(tmpNode->name, tmpNewNode->name);
30569570cc8Sopenharmony_ci}
30669570cc8Sopenharmony_ci
30769570cc8Sopenharmony_ciSandboxSection *GetSandboxSection(const SandboxQueue *queue, const char *name)
30869570cc8Sopenharmony_ci{
30969570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(name != NULL && queue != NULL, return NULL);
31069570cc8Sopenharmony_ci    ListNode *node = OH_ListFind(&queue->front, (void *)name, SandboxConditionalNodeCompareName);
31169570cc8Sopenharmony_ci    if (node == NULL) {
31269570cc8Sopenharmony_ci        return NULL;
31369570cc8Sopenharmony_ci    }
31469570cc8Sopenharmony_ci    return (SandboxSection *)ListEntry(node, SandboxMountNode, node);
31569570cc8Sopenharmony_ci}
31669570cc8Sopenharmony_ci
31769570cc8Sopenharmony_civoid AddSandboxSection(SandboxSection *node, SandboxQueue *queue)
31869570cc8Sopenharmony_ci{
31969570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(node != NULL && queue != NULL, return);
32069570cc8Sopenharmony_ci    if (ListEmpty(node->sandboxNode.node)) {
32169570cc8Sopenharmony_ci        OH_ListAddWithOrder(&queue->front, &node->sandboxNode.node, SandboxConditionalNodeCompareNode);
32269570cc8Sopenharmony_ci    }
32369570cc8Sopenharmony_ci}
32469570cc8Sopenharmony_ci
32569570cc8Sopenharmony_civoid DeleteSandboxSection(SandboxSection *section)
32669570cc8Sopenharmony_ci{
32769570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(section != NULL, return);
32869570cc8Sopenharmony_ci    // delete node
32969570cc8Sopenharmony_ci    OH_ListRemove(&section->sandboxNode.node);
33069570cc8Sopenharmony_ci    OH_ListInit(&section->sandboxNode.node);
33169570cc8Sopenharmony_ci    ClearSandboxSection(section);
33269570cc8Sopenharmony_ci    free(section);
33369570cc8Sopenharmony_ci}
33469570cc8Sopenharmony_ci
33569570cc8Sopenharmony_cistatic void SandboxQueueClear(SandboxQueue *queue)
33669570cc8Sopenharmony_ci{
33769570cc8Sopenharmony_ci    ListNode *node = queue->front.next;
33869570cc8Sopenharmony_ci    while (node != &queue->front) {
33969570cc8Sopenharmony_ci        SandboxSection *sandboxNode = (SandboxSection *)ListEntry(node, SandboxMountNode, node);
34069570cc8Sopenharmony_ci        DeleteSandboxSection(sandboxNode);
34169570cc8Sopenharmony_ci        // get first
34269570cc8Sopenharmony_ci        node = queue->front.next;
34369570cc8Sopenharmony_ci    }
34469570cc8Sopenharmony_ci}
34569570cc8Sopenharmony_ci
34669570cc8Sopenharmony_cistatic int AppSpawnExtDataCompareDataId(ListNode *node, void *data)
34769570cc8Sopenharmony_ci{
34869570cc8Sopenharmony_ci    AppSpawnExtData *extData = (AppSpawnExtData *)ListEntry(node, AppSpawnExtData, node);
34969570cc8Sopenharmony_ci    return extData->dataId - *(uint32_t *)data;
35069570cc8Sopenharmony_ci}
35169570cc8Sopenharmony_ci
35269570cc8Sopenharmony_ciAppSpawnSandboxCfg *GetAppSpawnSandbox(const AppSpawnMgr *content, ExtDataType type)
35369570cc8Sopenharmony_ci{
35469570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return NULL);
35569570cc8Sopenharmony_ci    uint32_t dataId = type;
35669570cc8Sopenharmony_ci    ListNode *node = OH_ListFind(&content->extData, (void *)&dataId, AppSpawnExtDataCompareDataId);
35769570cc8Sopenharmony_ci    if (node == NULL) {
35869570cc8Sopenharmony_ci        return NULL;
35969570cc8Sopenharmony_ci    }
36069570cc8Sopenharmony_ci    return (AppSpawnSandboxCfg *)ListEntry(node, AppSpawnSandboxCfg, extData);
36169570cc8Sopenharmony_ci}
36269570cc8Sopenharmony_ci
36369570cc8Sopenharmony_civoid DeleteAppSpawnSandbox(AppSpawnSandboxCfg *sandbox)
36469570cc8Sopenharmony_ci{
36569570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return);
36669570cc8Sopenharmony_ci    APPSPAWN_LOGV("DeleteAppSpawnSandbox");
36769570cc8Sopenharmony_ci    OH_ListRemove(&sandbox->extData.node);
36869570cc8Sopenharmony_ci    OH_ListInit(&sandbox->extData.node);
36969570cc8Sopenharmony_ci
37069570cc8Sopenharmony_ci    // delete all queue
37169570cc8Sopenharmony_ci    SandboxQueueClear(&sandbox->requiredQueue);
37269570cc8Sopenharmony_ci    SandboxQueueClear(&sandbox->permissionQueue);
37369570cc8Sopenharmony_ci    SandboxQueueClear(&sandbox->packageNameQueue);
37469570cc8Sopenharmony_ci    SandboxQueueClear(&sandbox->spawnFlagsQueue);
37569570cc8Sopenharmony_ci    SandboxQueueClear(&sandbox->nameGroupsQueue);
37669570cc8Sopenharmony_ci    if (sandbox->rootPath) {
37769570cc8Sopenharmony_ci        free(sandbox->rootPath);
37869570cc8Sopenharmony_ci    }
37969570cc8Sopenharmony_ci    free(sandbox->depGroupNodes);
38069570cc8Sopenharmony_ci    sandbox->depGroupNodes = NULL;
38169570cc8Sopenharmony_ci    free(sandbox);
38269570cc8Sopenharmony_ci    sandbox = NULL;
38369570cc8Sopenharmony_ci}
38469570cc8Sopenharmony_ci
38569570cc8Sopenharmony_cistatic void DumpSandboxPermission(const SandboxMountNode *node, uint32_t index)
38669570cc8Sopenharmony_ci{
38769570cc8Sopenharmony_ci    SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)node;
38869570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    ========================================= ");
38969570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    Section %{public}s", permissionNode->section.name);
39069570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    Section permission index %{public}d", permissionNode->permissionIndex);
39169570cc8Sopenharmony_ci    DumpSandboxSection(&permissionNode->section);
39269570cc8Sopenharmony_ci}
39369570cc8Sopenharmony_ci
39469570cc8Sopenharmony_cistatic void DumpSandboxSectionNode(const SandboxMountNode *node, uint32_t index)
39569570cc8Sopenharmony_ci{
39669570cc8Sopenharmony_ci    SandboxSection *section = (SandboxSection *)node;
39769570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    ========================================= ");
39869570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    Section %{public}s", section->name);
39969570cc8Sopenharmony_ci    DumpSandboxSection(section);
40069570cc8Sopenharmony_ci}
40169570cc8Sopenharmony_ci
40269570cc8Sopenharmony_cistatic void DumpSandboxNameGroupNode(const SandboxMountNode *node, uint32_t index)
40369570cc8Sopenharmony_ci{
40469570cc8Sopenharmony_ci    SandboxNameGroupNode *nameGroupNode = (SandboxNameGroupNode *)node;
40569570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    ========================================= ");
40669570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    Section %{public}s", nameGroupNode->section.name);
40769570cc8Sopenharmony_ci    APPSPAPWN_DUMP("    Section dep mode %{public}s",
40869570cc8Sopenharmony_ci        nameGroupNode->depMode == MOUNT_MODE_ALWAYS ? "always" : "not-exists");
40969570cc8Sopenharmony_ci    if (nameGroupNode->depNode != NULL) {
41069570cc8Sopenharmony_ci        APPSPAPWN_DUMP("    mount-paths-deps: ");
41169570cc8Sopenharmony_ci        DumpMountPathMountNode(nameGroupNode->depNode);
41269570cc8Sopenharmony_ci    }
41369570cc8Sopenharmony_ci    DumpSandboxSection(&nameGroupNode->section);
41469570cc8Sopenharmony_ci}
41569570cc8Sopenharmony_ci
41669570cc8Sopenharmony_ci
41769570cc8Sopenharmony_cistatic void DumpSandbox(struct TagAppSpawnExtData *data)
41869570cc8Sopenharmony_ci{
41969570cc8Sopenharmony_ci    AppSpawnSandboxCfg *sandbox = (AppSpawnSandboxCfg *)data;
42069570cc8Sopenharmony_ci    DumpAppSpawnSandboxCfg(sandbox);
42169570cc8Sopenharmony_ci}
42269570cc8Sopenharmony_ci
42369570cc8Sopenharmony_cistatic inline void InitSandboxQueue(SandboxQueue *queue, uint32_t type)
42469570cc8Sopenharmony_ci{
42569570cc8Sopenharmony_ci    OH_ListInit(&queue->front);
42669570cc8Sopenharmony_ci    queue->type = type;
42769570cc8Sopenharmony_ci}
42869570cc8Sopenharmony_ci
42969570cc8Sopenharmony_cistatic void FreeAppSpawnSandbox(struct TagAppSpawnExtData *data)
43069570cc8Sopenharmony_ci{
43169570cc8Sopenharmony_ci    AppSpawnSandboxCfg *sandbox = ListEntry(data, AppSpawnSandboxCfg, extData);
43269570cc8Sopenharmony_ci    // delete all var
43369570cc8Sopenharmony_ci    DeleteAppSpawnSandbox(sandbox);
43469570cc8Sopenharmony_ci}
43569570cc8Sopenharmony_ci
43669570cc8Sopenharmony_ciAppSpawnSandboxCfg *CreateAppSpawnSandbox(ExtDataType type)
43769570cc8Sopenharmony_ci{
43869570cc8Sopenharmony_ci    // create sandbox
43969570cc8Sopenharmony_ci    AppSpawnSandboxCfg *sandbox = (AppSpawnSandboxCfg *)calloc(1, sizeof(AppSpawnSandboxCfg));
44069570cc8Sopenharmony_ci    APPSPAWN_CHECK(sandbox != NULL, return NULL, "Failed to create sandbox");
44169570cc8Sopenharmony_ci
44269570cc8Sopenharmony_ci    // ext data init
44369570cc8Sopenharmony_ci    OH_ListInit(&sandbox->extData.node);
44469570cc8Sopenharmony_ci    sandbox->extData.dataId = type;
44569570cc8Sopenharmony_ci    sandbox->extData.freeNode = FreeAppSpawnSandbox;
44669570cc8Sopenharmony_ci    sandbox->extData.dumpNode = DumpSandbox;
44769570cc8Sopenharmony_ci
44869570cc8Sopenharmony_ci    // queue
44969570cc8Sopenharmony_ci    InitSandboxQueue(&sandbox->requiredQueue, SANDBOX_TAG_REQUIRED);
45069570cc8Sopenharmony_ci    InitSandboxQueue(&sandbox->permissionQueue, SANDBOX_TAG_PERMISSION);
45169570cc8Sopenharmony_ci    InitSandboxQueue(&sandbox->packageNameQueue, SANDBOX_TAG_PACKAGE_NAME);
45269570cc8Sopenharmony_ci    InitSandboxQueue(&sandbox->spawnFlagsQueue, SANDBOX_TAG_SPAWN_FLAGS);
45369570cc8Sopenharmony_ci    InitSandboxQueue(&sandbox->nameGroupsQueue, SANDBOX_TAG_NAME_GROUP);
45469570cc8Sopenharmony_ci
45569570cc8Sopenharmony_ci    sandbox->topSandboxSwitch = 0;
45669570cc8Sopenharmony_ci    sandbox->appFullMountEnable = 0;
45769570cc8Sopenharmony_ci    sandbox->topSandboxSwitch = 0;
45869570cc8Sopenharmony_ci    sandbox->pidNamespaceSupport = 0;
45969570cc8Sopenharmony_ci    sandbox->sandboxNsFlags = 0;
46069570cc8Sopenharmony_ci    sandbox->maxPermissionIndex = -1;
46169570cc8Sopenharmony_ci    sandbox->depNodeCount = 0;
46269570cc8Sopenharmony_ci    sandbox->depGroupNodes = NULL;
46369570cc8Sopenharmony_ci
46469570cc8Sopenharmony_ci    AddDefaultVariable();
46569570cc8Sopenharmony_ci    AddDefaultExpandAppSandboxConfigHandle();
46669570cc8Sopenharmony_ci    return sandbox;
46769570cc8Sopenharmony_ci}
46869570cc8Sopenharmony_ci
46969570cc8Sopenharmony_civoid DumpAppSpawnSandboxCfg(AppSpawnSandboxCfg *sandbox)
47069570cc8Sopenharmony_ci{
47169570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return);
47269570cc8Sopenharmony_ci    APPSPAPWN_DUMP("Sandbox root path: %{public}s", sandbox->rootPath);
47369570cc8Sopenharmony_ci    APPSPAPWN_DUMP("Sandbox sandboxNsFlags: %{public}x ", sandbox->sandboxNsFlags);
47469570cc8Sopenharmony_ci    APPSPAPWN_DUMP("Sandbox topSandboxSwitch: %{public}s", sandbox->topSandboxSwitch ? "true" : "false");
47569570cc8Sopenharmony_ci    APPSPAPWN_DUMP("Sandbox appFullMountEnable: %{public}s", sandbox->appFullMountEnable ? "true" : "false");
47669570cc8Sopenharmony_ci    APPSPAPWN_DUMP("Sandbox pidNamespaceSupport: %{public}s", sandbox->pidNamespaceSupport ? "true" : "false");
47769570cc8Sopenharmony_ci    APPSPAPWN_DUMP("Sandbox common info: ");
47869570cc8Sopenharmony_ci    DumpSandboxQueue(&sandbox->requiredQueue.front, DumpSandboxSectionNode);
47969570cc8Sopenharmony_ci    DumpSandboxQueue(&sandbox->packageNameQueue.front, DumpSandboxSectionNode);
48069570cc8Sopenharmony_ci    DumpSandboxQueue(&sandbox->permissionQueue.front, DumpSandboxPermission);
48169570cc8Sopenharmony_ci    DumpSandboxQueue(&sandbox->spawnFlagsQueue.front, DumpSandboxSectionNode);
48269570cc8Sopenharmony_ci    DumpSandboxQueue(&sandbox->nameGroupsQueue.front, DumpSandboxNameGroupNode);
48369570cc8Sopenharmony_ci}
48469570cc8Sopenharmony_ci
48569570cc8Sopenharmony_ciAPPSPAWN_STATIC int PreLoadIsoLatedSandboxCfg(AppSpawnMgr *content)
48669570cc8Sopenharmony_ci{
48769570cc8Sopenharmony_ci    if (IsNWebSpawnMode(content)) {
48869570cc8Sopenharmony_ci        return 0;
48969570cc8Sopenharmony_ci    }
49069570cc8Sopenharmony_ci
49169570cc8Sopenharmony_ci    AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_ISOLATED_SANDBOX);
49269570cc8Sopenharmony_ci    APPSPAWN_CHECK(sandbox == NULL, return 0, "Isolated sandbox has been load");
49369570cc8Sopenharmony_ci
49469570cc8Sopenharmony_ci    sandbox = CreateAppSpawnSandbox(EXT_DATA_ISOLATED_SANDBOX);
49569570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return APPSPAWN_SYSTEM_ERROR);
49669570cc8Sopenharmony_ci    OH_ListAddTail(&content->extData, &sandbox->extData.node);
49769570cc8Sopenharmony_ci
49869570cc8Sopenharmony_ci    // load app sandbox config
49969570cc8Sopenharmony_ci    LoadAppSandboxConfig(sandbox, MODE_FOR_NATIVE_SPAWN);
50069570cc8Sopenharmony_ci    sandbox->maxPermissionIndex = PermissionRenumber(&sandbox->permissionQueue);
50169570cc8Sopenharmony_ci
50269570cc8Sopenharmony_ci    content->content.sandboxNsFlags = 0;
50369570cc8Sopenharmony_ci    if (sandbox->pidNamespaceSupport) {
50469570cc8Sopenharmony_ci        content->content.sandboxNsFlags = sandbox->sandboxNsFlags;
50569570cc8Sopenharmony_ci    }
50669570cc8Sopenharmony_ci    return 0;
50769570cc8Sopenharmony_ci}
50869570cc8Sopenharmony_ci
50969570cc8Sopenharmony_ciAPPSPAWN_STATIC int PreLoadSandboxCfg(AppSpawnMgr *content)
51069570cc8Sopenharmony_ci{
51169570cc8Sopenharmony_ci    AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_SANDBOX);
51269570cc8Sopenharmony_ci    APPSPAWN_CHECK(sandbox == NULL, return 0, "Sandbox has been load");
51369570cc8Sopenharmony_ci
51469570cc8Sopenharmony_ci    sandbox = CreateAppSpawnSandbox(EXT_DATA_SANDBOX);
51569570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(sandbox != NULL, return APPSPAWN_SYSTEM_ERROR);
51669570cc8Sopenharmony_ci    OH_ListAddTail(&content->extData, &sandbox->extData.node);
51769570cc8Sopenharmony_ci
51869570cc8Sopenharmony_ci    // load app sandbox config
51969570cc8Sopenharmony_ci    LoadAppSandboxConfig(sandbox, content->content.mode);
52069570cc8Sopenharmony_ci    sandbox->maxPermissionIndex = PermissionRenumber(&sandbox->permissionQueue);
52169570cc8Sopenharmony_ci
52269570cc8Sopenharmony_ci    content->content.sandboxNsFlags = 0;
52369570cc8Sopenharmony_ci    if (IsNWebSpawnMode(content) || sandbox->pidNamespaceSupport) {
52469570cc8Sopenharmony_ci        content->content.sandboxNsFlags = sandbox->sandboxNsFlags;
52569570cc8Sopenharmony_ci    }
52669570cc8Sopenharmony_ci    return 0;
52769570cc8Sopenharmony_ci}
52869570cc8Sopenharmony_ci
52969570cc8Sopenharmony_ciAPPSPAWN_STATIC int IsolatedSandboxHandleServerExit(AppSpawnMgr *content)
53069570cc8Sopenharmony_ci{
53169570cc8Sopenharmony_ci    AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_ISOLATED_SANDBOX);
53269570cc8Sopenharmony_ci    APPSPAWN_CHECK(sandbox != NULL, return 0, "Isolated sandbox not load");
53369570cc8Sopenharmony_ci
53469570cc8Sopenharmony_ci    return 0;
53569570cc8Sopenharmony_ci}
53669570cc8Sopenharmony_ci
53769570cc8Sopenharmony_ciAPPSPAWN_STATIC int SandboxHandleServerExit(AppSpawnMgr *content)
53869570cc8Sopenharmony_ci{
53969570cc8Sopenharmony_ci    AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, EXT_DATA_SANDBOX);
54069570cc8Sopenharmony_ci    APPSPAWN_CHECK(sandbox != NULL, return 0, "Sandbox not load");
54169570cc8Sopenharmony_ci
54269570cc8Sopenharmony_ci    return 0;
54369570cc8Sopenharmony_ci}
54469570cc8Sopenharmony_ci
54569570cc8Sopenharmony_ciint SpawnBuildSandboxEnv(AppSpawnMgr *content, AppSpawningCtx *property)
54669570cc8Sopenharmony_ci{
54769570cc8Sopenharmony_ci    ExtDataType type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? EXT_DATA_ISOLATED_SANDBOX :
54869570cc8Sopenharmony_ci        EXT_DATA_SANDBOX;
54969570cc8Sopenharmony_ci    AppSpawnSandboxCfg *appSandbox = GetAppSpawnSandbox(content, type);
55069570cc8Sopenharmony_ci    APPSPAWN_CHECK(appSandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
55169570cc8Sopenharmony_ci    // no sandbox
55269570cc8Sopenharmony_ci    if (CheckAppMsgFlagsSet(property, APP_FLAGS_NO_SANDBOX)) {
55369570cc8Sopenharmony_ci        return 0;
55469570cc8Sopenharmony_ci    }
55569570cc8Sopenharmony_ci    // CLONE_NEWPID 0x20000000
55669570cc8Sopenharmony_ci    // CLONE_NEWNET 0x40000000
55769570cc8Sopenharmony_ci    if ((content->content.sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID) {
55869570cc8Sopenharmony_ci        int ret = getprocpid();
55969570cc8Sopenharmony_ci        if (ret < 0) {
56069570cc8Sopenharmony_ci            return ret;
56169570cc8Sopenharmony_ci        }
56269570cc8Sopenharmony_ci    }
56369570cc8Sopenharmony_ci    int ret = MountSandboxConfigs(appSandbox, property, IsNWebSpawnMode(content));
56469570cc8Sopenharmony_ci    appSandbox->mounted = 1;
56569570cc8Sopenharmony_ci    // for module test do not create sandbox, use APP_FLAGS_IGNORE_SANDBOX to ignore sandbox result
56669570cc8Sopenharmony_ci    if (CheckAppMsgFlagsSet(property, APP_FLAGS_IGNORE_SANDBOX)) {
56769570cc8Sopenharmony_ci        APPSPAWN_LOGW("Do not care sandbox result %{public}d", ret);
56869570cc8Sopenharmony_ci        return 0;
56969570cc8Sopenharmony_ci    }
57069570cc8Sopenharmony_ci    return ret == 0 ? 0 : APPSPAWN_SANDBOX_MOUNT_FAIL;
57169570cc8Sopenharmony_ci}
57269570cc8Sopenharmony_ci
57369570cc8Sopenharmony_cistatic int AppendPermissionGid(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
57469570cc8Sopenharmony_ci{
57569570cc8Sopenharmony_ci    AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
57669570cc8Sopenharmony_ci    APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
57769570cc8Sopenharmony_ci        "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
57869570cc8Sopenharmony_ci
57969570cc8Sopenharmony_ci    APPSPAWN_LOGV("AppendPermissionGid %{public}s", GetProcessName(property));
58069570cc8Sopenharmony_ci    ListNode *node = sandbox->permissionQueue.front.next;
58169570cc8Sopenharmony_ci    while (node != &sandbox->permissionQueue.front) {
58269570cc8Sopenharmony_ci        SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
58369570cc8Sopenharmony_ci        if (!CheckAppPermissionFlagSet(property, (uint32_t)permissionNode->permissionIndex)) {
58469570cc8Sopenharmony_ci            node = node->next;
58569570cc8Sopenharmony_ci            continue;
58669570cc8Sopenharmony_ci        }
58769570cc8Sopenharmony_ci        if (permissionNode->section.gidCount == 0) {
58869570cc8Sopenharmony_ci            node = node->next;
58969570cc8Sopenharmony_ci            continue;
59069570cc8Sopenharmony_ci        }
59169570cc8Sopenharmony_ci        APPSPAWN_LOGV("Add permission %{public}s gid %{public}d to %{public}s",
59269570cc8Sopenharmony_ci            permissionNode->section.name, permissionNode->section.gidTable[0], GetProcessName(property));
59369570cc8Sopenharmony_ci
59469570cc8Sopenharmony_ci        size_t copyLen = permissionNode->section.gidCount;
59569570cc8Sopenharmony_ci        if ((permissionNode->section.gidCount + dacInfo->gidCount) > APP_MAX_GIDS) {
59669570cc8Sopenharmony_ci            APPSPAWN_LOGW("More gid for %{public}s msg count %{public}u permission %{public}u",
59769570cc8Sopenharmony_ci                GetProcessName(property), dacInfo->gidCount, permissionNode->section.gidCount);
59869570cc8Sopenharmony_ci            copyLen = APP_MAX_GIDS - dacInfo->gidCount;
59969570cc8Sopenharmony_ci        }
60069570cc8Sopenharmony_ci        int ret = memcpy_s(&dacInfo->gidTable[dacInfo->gidCount], sizeof(gid_t) * copyLen,
60169570cc8Sopenharmony_ci            permissionNode->section.gidTable, sizeof(gid_t) * copyLen);
60269570cc8Sopenharmony_ci        if (ret != EOK) {
60369570cc8Sopenharmony_ci            APPSPAWN_LOGW("Failed to append permission %{public}s gid to %{public}s",
60469570cc8Sopenharmony_ci                permissionNode->section.name, GetProcessName(property));
60569570cc8Sopenharmony_ci            node = node->next;
60669570cc8Sopenharmony_ci            continue;
60769570cc8Sopenharmony_ci        }
60869570cc8Sopenharmony_ci        dacInfo->gidCount += copyLen;
60969570cc8Sopenharmony_ci        node = node->next;
61069570cc8Sopenharmony_ci    }
61169570cc8Sopenharmony_ci    return 0;
61269570cc8Sopenharmony_ci}
61369570cc8Sopenharmony_ci
61469570cc8Sopenharmony_cistatic int AppendPackageNameGids(const AppSpawnSandboxCfg *sandbox, AppSpawningCtx *property)
61569570cc8Sopenharmony_ci{
61669570cc8Sopenharmony_ci    AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
61769570cc8Sopenharmony_ci    APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE,
61869570cc8Sopenharmony_ci        "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, GetProcessName(property));
61969570cc8Sopenharmony_ci
62069570cc8Sopenharmony_ci    SandboxPackageNameNode *sandboxNode =
62169570cc8Sopenharmony_ci        (SandboxPackageNameNode *)GetSandboxSection(&sandbox->packageNameQueue, GetProcessName(property));
62269570cc8Sopenharmony_ci    if (sandboxNode == NULL || sandboxNode->section.gidCount == 0) {
62369570cc8Sopenharmony_ci        return 0;
62469570cc8Sopenharmony_ci    }
62569570cc8Sopenharmony_ci
62669570cc8Sopenharmony_ci    size_t copyLen = sandboxNode->section.gidCount;
62769570cc8Sopenharmony_ci    if ((sandboxNode->section.gidCount + dacInfo->gidCount) > APP_MAX_GIDS) {
62869570cc8Sopenharmony_ci        APPSPAWN_LOGW("More gid for %{public}s msg count %{public}u permission %{public}u",
62969570cc8Sopenharmony_ci                      GetProcessName(property),
63069570cc8Sopenharmony_ci                      dacInfo->gidCount,
63169570cc8Sopenharmony_ci                      sandboxNode->section.gidCount);
63269570cc8Sopenharmony_ci        copyLen = APP_MAX_GIDS - dacInfo->gidCount;
63369570cc8Sopenharmony_ci    }
63469570cc8Sopenharmony_ci    int ret = memcpy_s(&dacInfo->gidTable[dacInfo->gidCount], sizeof(gid_t) * copyLen,
63569570cc8Sopenharmony_ci                       sandboxNode->section.gidTable, sizeof(gid_t) * copyLen);
63669570cc8Sopenharmony_ci    if (ret != EOK) {
63769570cc8Sopenharmony_ci        APPSPAWN_LOGW("Failed to append permission %{public}s gid to %{public}s",
63869570cc8Sopenharmony_ci                      sandboxNode->section.name,
63969570cc8Sopenharmony_ci                      GetProcessName(property));
64069570cc8Sopenharmony_ci    }
64169570cc8Sopenharmony_ci    dacInfo->gidCount += copyLen;
64269570cc8Sopenharmony_ci
64369570cc8Sopenharmony_ci    return 0;
64469570cc8Sopenharmony_ci}
64569570cc8Sopenharmony_ci
64669570cc8Sopenharmony_ciint SpawnPrepareSandboxCfg(AppSpawnMgr *content, AppSpawningCtx *property)
64769570cc8Sopenharmony_ci{
64869570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
64969570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1);
65069570cc8Sopenharmony_ci    APPSPAWN_LOGV("Prepare sandbox config %{public}s", GetProcessName(property));
65169570cc8Sopenharmony_ci    ExtDataType type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ? EXT_DATA_ISOLATED_SANDBOX :
65269570cc8Sopenharmony_ci        EXT_DATA_SANDBOX;
65369570cc8Sopenharmony_ci    AppSpawnSandboxCfg *sandbox = GetAppSpawnSandbox(content, type);
65469570cc8Sopenharmony_ci    APPSPAWN_CHECK(sandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
65569570cc8Sopenharmony_ci
65669570cc8Sopenharmony_ci    int32_t index = 0;
65769570cc8Sopenharmony_ci    if (sandbox->appFullMountEnable) {
65869570cc8Sopenharmony_ci        index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_CROSS_APP_MODE);
65969570cc8Sopenharmony_ci    } else {
66069570cc8Sopenharmony_ci        index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_ACCESS_COMMON_DIR_MODE);
66169570cc8Sopenharmony_ci    }
66269570cc8Sopenharmony_ci
66369570cc8Sopenharmony_ci    int32_t fileMgrIndex = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_ACCESS_MANAGER_MODE);
66469570cc8Sopenharmony_ci    if (index > 0 && (CheckAppMsgFlagsSet(property, (uint32_t)fileMgrIndex) == 0)) {
66569570cc8Sopenharmony_ci        if (SetAppPermissionFlags(property, index) != 0) {
66669570cc8Sopenharmony_ci            return -1;
66769570cc8Sopenharmony_ci        }
66869570cc8Sopenharmony_ci    }
66969570cc8Sopenharmony_ci
67069570cc8Sopenharmony_ci    int ret = AppendPermissionGid(sandbox, property);
67169570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
67269570cc8Sopenharmony_ci    ret = AppendPackageNameGids(sandbox, property);
67369570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to add gid for %{public}s", GetProcessName(property));
67469570cc8Sopenharmony_ci    ret = StagedMountSystemConst(sandbox, property, IsNWebSpawnMode(content));
67569570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Failed to mount system-const for %{public}s", GetProcessName(property));
67669570cc8Sopenharmony_ci    return 0;
67769570cc8Sopenharmony_ci}
67869570cc8Sopenharmony_ci
67969570cc8Sopenharmony_ciAPPSPAWN_STATIC int SandboxUnmountPath(const AppSpawnMgr *content, const AppSpawnedProcessInfo *appInfo)
68069570cc8Sopenharmony_ci{
68169570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(content != NULL, return -1);
68269570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(appInfo != NULL, return -1);
68369570cc8Sopenharmony_ci    AppSpawnSandboxCfg *sandbox = NULL;
68469570cc8Sopenharmony_ci    APPSPAWN_LOGV("Sandbox process %{public}s %{public}u exit", appInfo->name, appInfo->uid);
68569570cc8Sopenharmony_ci    if (content->content.mode == MODE_FOR_NATIVE_SPAWN) {
68669570cc8Sopenharmony_ci        sandbox = GetAppSpawnSandbox(content, EXT_DATA_ISOLATED_SANDBOX);
68769570cc8Sopenharmony_ci    } else {
68869570cc8Sopenharmony_ci        sandbox = GetAppSpawnSandbox(content, EXT_DATA_SANDBOX);
68969570cc8Sopenharmony_ci    }
69069570cc8Sopenharmony_ci    return UnmountDepPaths(sandbox, appInfo->uid);
69169570cc8Sopenharmony_ci}
69269570cc8Sopenharmony_ci
69369570cc8Sopenharmony_ci#ifdef APPSPAWN_SANDBOX_NEW
69469570cc8Sopenharmony_ciMODULE_CONSTRUCTOR(void)
69569570cc8Sopenharmony_ci{
69669570cc8Sopenharmony_ci    APPSPAWN_LOGV("Load sandbox module ...");
69769570cc8Sopenharmony_ci    (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadSandboxCfg);
69869570cc8Sopenharmony_ci    (void)AddServerStageHook(STAGE_SERVER_PRELOAD, HOOK_PRIO_SANDBOX, PreLoadIsoLatedSandboxCfg);
69969570cc8Sopenharmony_ci    (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, SandboxHandleServerExit);
70069570cc8Sopenharmony_ci    (void)AddServerStageHook(STAGE_SERVER_EXIT, HOOK_PRIO_SANDBOX, IsolatedSandboxHandleServerExit);
70169570cc8Sopenharmony_ci    (void)AddAppSpawnHook(STAGE_PARENT_PRE_FORK, HOOK_PRIO_SANDBOX, SpawnPrepareSandboxCfg);
70269570cc8Sopenharmony_ci    (void)AddAppSpawnHook(STAGE_CHILD_EXECUTE, HOOK_PRIO_SANDBOX, SpawnBuildSandboxEnv);
70369570cc8Sopenharmony_ci    (void)AddProcessMgrHook(STAGE_SERVER_APP_DIED, 0, SandboxUnmountPath);
70469570cc8Sopenharmony_ci}
70569570cc8Sopenharmony_ci
70669570cc8Sopenharmony_ciMODULE_DESTRUCTOR(void)
70769570cc8Sopenharmony_ci{
70869570cc8Sopenharmony_ci    ClearVariable();
70969570cc8Sopenharmony_ci    ClearExpandAppSandboxConfigHandle();
71069570cc8Sopenharmony_ci}
71169570cc8Sopenharmony_ci#endif
712