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#include <sys/mount.h>
1769570cc8Sopenharmony_ci#include <sys/stat.h>
1869570cc8Sopenharmony_ci#include <sys/syscall.h>
1969570cc8Sopenharmony_ci#include <sys/types.h>
2069570cc8Sopenharmony_ci
2169570cc8Sopenharmony_ci#include "appspawn_msg.h"
2269570cc8Sopenharmony_ci#include "appspawn_sandbox.h"
2369570cc8Sopenharmony_ci#include "appspawn_utils.h"
2469570cc8Sopenharmony_ci#include "json_utils.h"
2569570cc8Sopenharmony_ci#include "securec.h"
2669570cc8Sopenharmony_ci
2769570cc8Sopenharmony_ci#define SANDBOX_GROUP_PATH "/data/storage/el2/group/"
2869570cc8Sopenharmony_ci#define SANDBOX_INSTALL_PATH "/data/storage/el1/bundle/"
2969570cc8Sopenharmony_ci#define SANDBOX_OVERLAY_PATH "/data/storage/overlay/"
3069570cc8Sopenharmony_ci
3169570cc8Sopenharmony_cistatic inline bool CheckPath(const char *name)
3269570cc8Sopenharmony_ci{
3369570cc8Sopenharmony_ci    return name != NULL && strcmp(name, ".") != 0 && strcmp(name, "..") != 0 && strstr(name, "/") == NULL;
3469570cc8Sopenharmony_ci}
3569570cc8Sopenharmony_ci
3669570cc8Sopenharmony_ciAPPSPAWN_STATIC int MountAllHsp(const SandboxContext *context, const cJSON *hsps)
3769570cc8Sopenharmony_ci{
3869570cc8Sopenharmony_ci    APPSPAWN_CHECK(context != NULL && hsps != NULL, return -1, "Invalid context or hsps");
3969570cc8Sopenharmony_ci
4069570cc8Sopenharmony_ci    int ret = 0;
4169570cc8Sopenharmony_ci    cJSON *bundles = cJSON_GetObjectItemCaseSensitive(hsps, "bundles");
4269570cc8Sopenharmony_ci    cJSON *modules = cJSON_GetObjectItemCaseSensitive(hsps, "modules");
4369570cc8Sopenharmony_ci    cJSON *versions = cJSON_GetObjectItemCaseSensitive(hsps, "versions");
4469570cc8Sopenharmony_ci    APPSPAWN_CHECK(bundles != NULL && cJSON_IsArray(bundles), return -1, "MountAllHsp: invalid bundles");
4569570cc8Sopenharmony_ci    APPSPAWN_CHECK(modules != NULL && cJSON_IsArray(modules), return -1, "MountAllHsp: invalid modules");
4669570cc8Sopenharmony_ci    APPSPAWN_CHECK(versions != NULL && cJSON_IsArray(versions), return -1, "MountAllHsp: invalid versions");
4769570cc8Sopenharmony_ci    int count = cJSON_GetArraySize(bundles);
4869570cc8Sopenharmony_ci    APPSPAWN_CHECK(count == cJSON_GetArraySize(modules), return -1, "MountAllHsp: sizes are not same");
4969570cc8Sopenharmony_ci    APPSPAWN_CHECK(count == cJSON_GetArraySize(versions), return -1, "MountAllHsp: sizes are not same");
5069570cc8Sopenharmony_ci
5169570cc8Sopenharmony_ci    APPSPAWN_LOGI("MountAllHsp app: %{public}s, count: %{public}d", context->bundleName, count);
5269570cc8Sopenharmony_ci    for (int i = 0; i < count; i++) {
5369570cc8Sopenharmony_ci        char *libBundleName = cJSON_GetStringValue(cJSON_GetArrayItem(bundles, i));
5469570cc8Sopenharmony_ci        char *libModuleName = cJSON_GetStringValue(cJSON_GetArrayItem(modules, i));
5569570cc8Sopenharmony_ci        char *libVersion = cJSON_GetStringValue(cJSON_GetArrayItem(versions, i));
5669570cc8Sopenharmony_ci        APPSPAWN_CHECK(CheckPath(libBundleName) && CheckPath(libModuleName) && CheckPath(libVersion),
5769570cc8Sopenharmony_ci            return -1, "MountAllHsp: path error");
5869570cc8Sopenharmony_ci
5969570cc8Sopenharmony_ci        // src path
6069570cc8Sopenharmony_ci        int len = sprintf_s(context->buffer[0].buffer, context->buffer[0].bufferLen, "%s%s/%s/%s",
6169570cc8Sopenharmony_ci            PHYSICAL_APP_INSTALL_PATH, libBundleName, libVersion, libModuleName);
6269570cc8Sopenharmony_ci        APPSPAWN_CHECK(len > 0, return -1, "Failed to format install path");
6369570cc8Sopenharmony_ci        // sandbox path
6469570cc8Sopenharmony_ci        len = sprintf_s(context->buffer[1].buffer, context->buffer[1].bufferLen, "%s%s%s/%s",
6569570cc8Sopenharmony_ci            context->rootPath, SANDBOX_INSTALL_PATH, libBundleName, libModuleName);
6669570cc8Sopenharmony_ci        APPSPAWN_CHECK(len > 0, return -1, "Failed to format install path");
6769570cc8Sopenharmony_ci
6869570cc8Sopenharmony_ci        CreateSandboxDir(context->buffer[1].buffer, FILE_MODE);
6969570cc8Sopenharmony_ci        MountArg mountArg = {
7069570cc8Sopenharmony_ci            context->buffer[0].buffer, context->buffer[1].buffer, NULL, MS_REC | MS_BIND, NULL, MS_SLAVE
7169570cc8Sopenharmony_ci        };
7269570cc8Sopenharmony_ci        ret = SandboxMountPath(&mountArg);
7369570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return ret, "mount library failed %{public}d", ret);
7469570cc8Sopenharmony_ci    }
7569570cc8Sopenharmony_ci    return ret;
7669570cc8Sopenharmony_ci}
7769570cc8Sopenharmony_ci
7869570cc8Sopenharmony_cistatic inline char *GetLastPath(const char *libPhysicalPath)
7969570cc8Sopenharmony_ci{
8069570cc8Sopenharmony_ci    char *tmp = GetLastStr(libPhysicalPath, "/");
8169570cc8Sopenharmony_ci    return tmp + 1;
8269570cc8Sopenharmony_ci}
8369570cc8Sopenharmony_ci
8469570cc8Sopenharmony_ciAPPSPAWN_STATIC int MountAllGroup(const SandboxContext *context, const cJSON *groups)
8569570cc8Sopenharmony_ci{
8669570cc8Sopenharmony_ci    APPSPAWN_CHECK(context != NULL && groups != NULL, return -1, "Invalid context or group");
8769570cc8Sopenharmony_ci    mode_t mountFlags = MS_REC | MS_BIND;
8869570cc8Sopenharmony_ci    mode_t mountSharedFlag = MS_SLAVE;
8969570cc8Sopenharmony_ci    if (CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, APP_FLAGS_ISOLATED_SANDBOX)) {
9069570cc8Sopenharmony_ci        APPSPAWN_LOGV("MountAllGroup falsg is isolated");
9169570cc8Sopenharmony_ci        mountSharedFlag |= MS_REMOUNT | MS_NODEV | MS_RDONLY | MS_BIND;
9269570cc8Sopenharmony_ci    }
9369570cc8Sopenharmony_ci    int ret = 0;
9469570cc8Sopenharmony_ci    cJSON *dataGroupIds = cJSON_GetObjectItemCaseSensitive(groups, "dataGroupId");
9569570cc8Sopenharmony_ci    cJSON *gids = cJSON_GetObjectItemCaseSensitive(groups, "gid");
9669570cc8Sopenharmony_ci    cJSON *dirs = cJSON_GetObjectItemCaseSensitive(groups, "dir");
9769570cc8Sopenharmony_ci    APPSPAWN_CHECK(dataGroupIds != NULL && cJSON_IsArray(dataGroupIds),
9869570cc8Sopenharmony_ci        return -1, "MountAllGroup: invalid dataGroupIds");
9969570cc8Sopenharmony_ci    APPSPAWN_CHECK(gids != NULL && cJSON_IsArray(gids), return -1, "MountAllGroup: invalid gids");
10069570cc8Sopenharmony_ci    APPSPAWN_CHECK(dirs != NULL && cJSON_IsArray(dirs), return -1, "MountAllGroup: invalid dirs");
10169570cc8Sopenharmony_ci    int count = cJSON_GetArraySize(dataGroupIds);
10269570cc8Sopenharmony_ci    APPSPAWN_CHECK(count == cJSON_GetArraySize(gids), return -1, "MountAllGroup: sizes are not same");
10369570cc8Sopenharmony_ci    APPSPAWN_CHECK(count == cJSON_GetArraySize(dirs), return -1, "MountAllGroup: sizes are not same");
10469570cc8Sopenharmony_ci
10569570cc8Sopenharmony_ci    APPSPAWN_LOGI("MountAllGroup: app: %{public}s, count: %{public}d", context->bundleName, count);
10669570cc8Sopenharmony_ci    for (int i = 0; i < count; i++) {
10769570cc8Sopenharmony_ci        cJSON *dirJson = cJSON_GetArrayItem(dirs, i);
10869570cc8Sopenharmony_ci        APPSPAWN_CHECK(dirJson != NULL && cJSON_IsString(dirJson), return -1, "MountAllGroup: invalid dirJson");
10969570cc8Sopenharmony_ci        const char *libPhysicalPath = cJSON_GetStringValue(dirJson);
11069570cc8Sopenharmony_ci        APPSPAWN_CHECK(!CheckPath(libPhysicalPath), return -1, "MountAllGroup: path error");
11169570cc8Sopenharmony_ci
11269570cc8Sopenharmony_ci        char *dataGroupUuid = GetLastPath(libPhysicalPath);
11369570cc8Sopenharmony_ci        int len = sprintf_s(context->buffer[0].buffer, context->buffer[0].bufferLen, "%s%s%s",
11469570cc8Sopenharmony_ci            context->rootPath, SANDBOX_GROUP_PATH, dataGroupUuid);
11569570cc8Sopenharmony_ci        APPSPAWN_CHECK(len > 0, return -1, "Failed to format install path");
11669570cc8Sopenharmony_ci        APPSPAWN_LOGV("MountAllGroup src: '%{public}s' =>'%{public}s'", libPhysicalPath, context->buffer[0].buffer);
11769570cc8Sopenharmony_ci
11869570cc8Sopenharmony_ci        CreateSandboxDir(context->buffer[0].buffer, FILE_MODE);
11969570cc8Sopenharmony_ci        MountArg mountArg = {libPhysicalPath, context->buffer[0].buffer, NULL, mountFlags, NULL, mountSharedFlag};
12069570cc8Sopenharmony_ci        ret = SandboxMountPath(&mountArg);
12169570cc8Sopenharmony_ci        APPSPAWN_CHECK(ret == 0, return ret, "mount library failed %{public}d", ret);
12269570cc8Sopenharmony_ci    }
12369570cc8Sopenharmony_ci    return ret;
12469570cc8Sopenharmony_ci}
12569570cc8Sopenharmony_ci
12669570cc8Sopenharmony_citypedef struct {
12769570cc8Sopenharmony_ci    const SandboxContext *sandboxContext;
12869570cc8Sopenharmony_ci    uint32_t srcSetLen;
12969570cc8Sopenharmony_ci    char *mountedSrcSet;
13069570cc8Sopenharmony_ci} OverlayContext;
13169570cc8Sopenharmony_ci
13269570cc8Sopenharmony_cistatic int SetOverlayAppPath(const char *hapPath, void *context)
13369570cc8Sopenharmony_ci{
13469570cc8Sopenharmony_ci    APPSPAWN_LOGV("SetOverlayAppPath '%{public}s'", hapPath);
13569570cc8Sopenharmony_ci    OverlayContext *overlayContext = (OverlayContext *)context;
13669570cc8Sopenharmony_ci    const SandboxContext *sandboxContext = overlayContext->sandboxContext;
13769570cc8Sopenharmony_ci
13869570cc8Sopenharmony_ci    // src path
13969570cc8Sopenharmony_ci    char *tmp = GetLastStr(hapPath, "/");
14069570cc8Sopenharmony_ci    if (tmp == NULL) {
14169570cc8Sopenharmony_ci        return 0;
14269570cc8Sopenharmony_ci    }
14369570cc8Sopenharmony_ci    int ret = strncpy_s(sandboxContext->buffer[0].buffer,
14469570cc8Sopenharmony_ci        sandboxContext->buffer[0].bufferLen, hapPath, tmp - (char *)hapPath);
14569570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "mount library failed %{public}d", ret);
14669570cc8Sopenharmony_ci
14769570cc8Sopenharmony_ci    if (strstr(overlayContext->mountedSrcSet, sandboxContext->buffer[0].buffer) != NULL) {
14869570cc8Sopenharmony_ci        APPSPAWN_LOGV("%{public}s have mounted before, no need to mount twice.", sandboxContext->buffer[0].buffer);
14969570cc8Sopenharmony_ci        return 0;
15069570cc8Sopenharmony_ci    }
15169570cc8Sopenharmony_ci    ret = strcat_s(overlayContext->mountedSrcSet, overlayContext->srcSetLen, "|");
15269570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Fail to add src path to set %{public}s", "|");
15369570cc8Sopenharmony_ci    ret = strcat_s(overlayContext->mountedSrcSet, overlayContext->srcSetLen, sandboxContext->buffer[0].buffer);
15469570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "Fail to add src path to set %{public}s", sandboxContext->buffer[0].buffer);
15569570cc8Sopenharmony_ci
15669570cc8Sopenharmony_ci    // sandbox path
15769570cc8Sopenharmony_ci    tmp = GetLastStr(sandboxContext->buffer[0].buffer, "/");
15869570cc8Sopenharmony_ci    if (tmp == NULL) {
15969570cc8Sopenharmony_ci        return 0;
16069570cc8Sopenharmony_ci    }
16169570cc8Sopenharmony_ci    int len = sprintf_s(sandboxContext->buffer[1].buffer, sandboxContext->buffer[1].bufferLen, "%s%s",
16269570cc8Sopenharmony_ci        sandboxContext->rootPath, SANDBOX_OVERLAY_PATH);
16369570cc8Sopenharmony_ci    APPSPAWN_CHECK(len > 0, return -1, "Failed to format install path");
16469570cc8Sopenharmony_ci    ret = strcat_s(sandboxContext->buffer[1].buffer, sandboxContext->buffer[1].bufferLen - len, tmp + 1);
16569570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, return ret, "mount library failed %{public}d", ret);
16669570cc8Sopenharmony_ci    APPSPAWN_LOGV("SetOverlayAppPath path: '%{public}s' => '%{public}s'",
16769570cc8Sopenharmony_ci        sandboxContext->buffer[0].buffer, sandboxContext->buffer[1].buffer);
16869570cc8Sopenharmony_ci
16969570cc8Sopenharmony_ci    (void)MakeDirRec(sandboxContext->buffer[1].buffer, FILE_MODE, 1);
17069570cc8Sopenharmony_ci    MountArg mountArg = {
17169570cc8Sopenharmony_ci        sandboxContext->buffer[0].buffer, sandboxContext->buffer[1].buffer, NULL, MS_REC | MS_BIND, NULL, MS_SHARED
17269570cc8Sopenharmony_ci    };
17369570cc8Sopenharmony_ci    int retMount = SandboxMountPath(&mountArg);
17469570cc8Sopenharmony_ci    if (retMount != 0) {
17569570cc8Sopenharmony_ci        APPSPAWN_LOGE("Fail to mount overlay path, src is %{public}s.", hapPath);
17669570cc8Sopenharmony_ci        ret = retMount;
17769570cc8Sopenharmony_ci    }
17869570cc8Sopenharmony_ci    return ret;
17969570cc8Sopenharmony_ci}
18069570cc8Sopenharmony_ci
18169570cc8Sopenharmony_cistatic int SetOverlayAppSandboxConfig(const SandboxContext *context, const char *overlayInfo)
18269570cc8Sopenharmony_ci{
18369570cc8Sopenharmony_ci    APPSPAWN_CHECK(context != NULL && overlayInfo != NULL, return -1, "Invalid context or overlayInfo");
18469570cc8Sopenharmony_ci    OverlayContext overlayContext;
18569570cc8Sopenharmony_ci    overlayContext.sandboxContext = context;
18669570cc8Sopenharmony_ci    overlayContext.srcSetLen = strlen(overlayInfo);
18769570cc8Sopenharmony_ci    overlayContext.mountedSrcSet = (char *)calloc(1, overlayContext.srcSetLen + 1);
18869570cc8Sopenharmony_ci    APPSPAWN_CHECK(overlayContext.mountedSrcSet != NULL, return -1, "Failed to create mountedSrcSet");
18969570cc8Sopenharmony_ci    *(overlayContext.mountedSrcSet + overlayContext.srcSetLen) = '\0';
19069570cc8Sopenharmony_ci    int ret = StringSplit(overlayInfo, "|", (void *)&overlayContext, SetOverlayAppPath);
19169570cc8Sopenharmony_ci    APPSPAWN_LOGV("overlayContext->mountedSrcSet: '%{public}s'", overlayContext.mountedSrcSet);
19269570cc8Sopenharmony_ci    free(overlayContext.mountedSrcSet);
19369570cc8Sopenharmony_ci    return ret;
19469570cc8Sopenharmony_ci}
19569570cc8Sopenharmony_ci
19669570cc8Sopenharmony_cistatic inline cJSON *GetJsonObjFromProperty(const SandboxContext *context, const char *name)
19769570cc8Sopenharmony_ci{
19869570cc8Sopenharmony_ci    uint32_t size = 0;
19969570cc8Sopenharmony_ci    char *extInfo = (char *)(GetAppSpawnMsgExtInfo(context->message, name, &size));
20069570cc8Sopenharmony_ci    if (size == 0 || extInfo == NULL) {
20169570cc8Sopenharmony_ci        return NULL;
20269570cc8Sopenharmony_ci    }
20369570cc8Sopenharmony_ci    APPSPAWN_LOGV("Get json name %{public}s value %{public}s", name, extInfo);
20469570cc8Sopenharmony_ci    cJSON *root = cJSON_Parse(extInfo);
20569570cc8Sopenharmony_ci    APPSPAWN_CHECK(root != NULL, return NULL, "Invalid ext info %{public}s for %{public}s", extInfo, name);
20669570cc8Sopenharmony_ci    return root;
20769570cc8Sopenharmony_ci}
20869570cc8Sopenharmony_ci
20969570cc8Sopenharmony_cistatic int ProcessHSPListConfig(const SandboxContext *context, const AppSpawnSandboxCfg *appSandBox, const char *name)
21069570cc8Sopenharmony_ci{
21169570cc8Sopenharmony_ci    cJSON *root = GetJsonObjFromProperty(context, name);
21269570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(root != NULL, return 0);
21369570cc8Sopenharmony_ci    int ret = MountAllHsp(context, root);
21469570cc8Sopenharmony_ci    cJSON_Delete(root);
21569570cc8Sopenharmony_ci    return ret;
21669570cc8Sopenharmony_ci}
21769570cc8Sopenharmony_ci
21869570cc8Sopenharmony_cistatic int ProcessDataGroupConfig(const SandboxContext *context, const AppSpawnSandboxCfg *appSandBox, const char *name)
21969570cc8Sopenharmony_ci{
22069570cc8Sopenharmony_ci    cJSON *root = GetJsonObjFromProperty(context, name);
22169570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(root != NULL, return 0);
22269570cc8Sopenharmony_ci    int ret = MountAllGroup(context, root);
22369570cc8Sopenharmony_ci    cJSON_Delete(root);
22469570cc8Sopenharmony_ci    return ret;
22569570cc8Sopenharmony_ci}
22669570cc8Sopenharmony_ci
22769570cc8Sopenharmony_cistatic int ProcessOverlayAppConfig(const SandboxContext *context,
22869570cc8Sopenharmony_ci    const AppSpawnSandboxCfg *appSandBox, const char *name)
22969570cc8Sopenharmony_ci{
23069570cc8Sopenharmony_ci    uint32_t size = 0;
23169570cc8Sopenharmony_ci    char *extInfo = (char *)GetAppSpawnMsgExtInfo(context->message, name, &size);
23269570cc8Sopenharmony_ci    if (size == 0 || extInfo == NULL) {
23369570cc8Sopenharmony_ci        return 0;
23469570cc8Sopenharmony_ci    }
23569570cc8Sopenharmony_ci    APPSPAWN_LOGV("ProcessOverlayAppConfig name %{public}s value %{public}s", name, extInfo);
23669570cc8Sopenharmony_ci    return SetOverlayAppSandboxConfig(context, extInfo);
23769570cc8Sopenharmony_ci}
23869570cc8Sopenharmony_ci
23969570cc8Sopenharmony_cistruct ListNode g_sandboxExpandCfgList = {&g_sandboxExpandCfgList, &g_sandboxExpandCfgList};
24069570cc8Sopenharmony_cistatic int AppSandboxExpandAppCfgCompareName(ListNode *node, void *data)
24169570cc8Sopenharmony_ci{
24269570cc8Sopenharmony_ci    AppSandboxExpandAppCfgNode *varNode = ListEntry(node, AppSandboxExpandAppCfgNode, node);
24369570cc8Sopenharmony_ci    return strncmp((char *)data, varNode->name, strlen(varNode->name));
24469570cc8Sopenharmony_ci}
24569570cc8Sopenharmony_ci
24669570cc8Sopenharmony_cistatic int AppSandboxExpandAppCfgComparePrio(ListNode *node1, ListNode *node2)
24769570cc8Sopenharmony_ci{
24869570cc8Sopenharmony_ci    AppSandboxExpandAppCfgNode *varNode1 = ListEntry(node1, AppSandboxExpandAppCfgNode, node);
24969570cc8Sopenharmony_ci    AppSandboxExpandAppCfgNode *varNode2 = ListEntry(node2, AppSandboxExpandAppCfgNode, node);
25069570cc8Sopenharmony_ci    return varNode1->prio - varNode2->prio;
25169570cc8Sopenharmony_ci}
25269570cc8Sopenharmony_ci
25369570cc8Sopenharmony_cistatic const AppSandboxExpandAppCfgNode *GetAppSandboxExpandAppCfg(const char *name)
25469570cc8Sopenharmony_ci{
25569570cc8Sopenharmony_ci    ListNode *node = OH_ListFind(&g_sandboxExpandCfgList, (void *)name, AppSandboxExpandAppCfgCompareName);
25669570cc8Sopenharmony_ci    if (node == NULL) {
25769570cc8Sopenharmony_ci        return NULL;
25869570cc8Sopenharmony_ci    }
25969570cc8Sopenharmony_ci    return ListEntry(node, AppSandboxExpandAppCfgNode, node);
26069570cc8Sopenharmony_ci}
26169570cc8Sopenharmony_ci
26269570cc8Sopenharmony_ciint RegisterExpandSandboxCfgHandler(const char *name, int prio, ProcessExpandSandboxCfg handleExpandCfg)
26369570cc8Sopenharmony_ci{
26469570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(name != NULL && handleExpandCfg != NULL, return APPSPAWN_ARG_INVALID);
26569570cc8Sopenharmony_ci    if (GetAppSandboxExpandAppCfg(name) != NULL) {
26669570cc8Sopenharmony_ci        return APPSPAWN_NODE_EXIST;
26769570cc8Sopenharmony_ci    }
26869570cc8Sopenharmony_ci
26969570cc8Sopenharmony_ci    size_t len = APPSPAWN_ALIGN(strlen(name) + 1);
27069570cc8Sopenharmony_ci    AppSandboxExpandAppCfgNode *node = (AppSandboxExpandAppCfgNode *)(malloc(sizeof(AppSandboxExpandAppCfgNode) + len));
27169570cc8Sopenharmony_ci    APPSPAWN_CHECK(node != NULL, return APPSPAWN_SYSTEM_ERROR, "Failed to create sandbox");
27269570cc8Sopenharmony_ci    // ext data init
27369570cc8Sopenharmony_ci    OH_ListInit(&node->node);
27469570cc8Sopenharmony_ci    node->cfgHandle = handleExpandCfg;
27569570cc8Sopenharmony_ci    node->prio = prio;
27669570cc8Sopenharmony_ci    int ret = strcpy_s(node->name, len, name);
27769570cc8Sopenharmony_ci    APPSPAWN_CHECK(ret == 0, free(node);
27869570cc8Sopenharmony_ci        return -1, "Failed to copy name %{public}s", name);
27969570cc8Sopenharmony_ci    OH_ListAddWithOrder(&g_sandboxExpandCfgList, &node->node, AppSandboxExpandAppCfgComparePrio);
28069570cc8Sopenharmony_ci    return 0;
28169570cc8Sopenharmony_ci}
28269570cc8Sopenharmony_ci
28369570cc8Sopenharmony_ciint ProcessExpandAppSandboxConfig(const SandboxContext *context, const AppSpawnSandboxCfg *appSandBox, const char *name)
28469570cc8Sopenharmony_ci{
28569570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(context != NULL && appSandBox != NULL, return APPSPAWN_ARG_INVALID);
28669570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(name != NULL, return APPSPAWN_ARG_INVALID);
28769570cc8Sopenharmony_ci    APPSPAWN_LOGV("ProcessExpandAppSandboxConfig %{public}s.", name);
28869570cc8Sopenharmony_ci    const AppSandboxExpandAppCfgNode *node = GetAppSandboxExpandAppCfg(name);
28969570cc8Sopenharmony_ci    if (node != NULL && node->cfgHandle != NULL) {
29069570cc8Sopenharmony_ci        return node->cfgHandle(context, appSandBox, name);
29169570cc8Sopenharmony_ci    }
29269570cc8Sopenharmony_ci    return 0;
29369570cc8Sopenharmony_ci}
29469570cc8Sopenharmony_ci
29569570cc8Sopenharmony_civoid AddDefaultExpandAppSandboxConfigHandle(void)
29669570cc8Sopenharmony_ci{
29769570cc8Sopenharmony_ci    RegisterExpandSandboxCfgHandler("HspList", 0, ProcessHSPListConfig);
29869570cc8Sopenharmony_ci    RegisterExpandSandboxCfgHandler("DataGroup", 1, ProcessDataGroupConfig);
29969570cc8Sopenharmony_ci    RegisterExpandSandboxCfgHandler("Overlay", 2, ProcessOverlayAppConfig);  // 2 priority
30069570cc8Sopenharmony_ci}
30169570cc8Sopenharmony_ci
30269570cc8Sopenharmony_civoid ClearExpandAppSandboxConfigHandle(void)
30369570cc8Sopenharmony_ci{
30469570cc8Sopenharmony_ci    OH_ListRemoveAll(&g_sandboxExpandCfgList, NULL);
30569570cc8Sopenharmony_ci}
306