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 <errno.h>
1769570cc8Sopenharmony_ci#include <fcntl.h>
1869570cc8Sopenharmony_ci#include <sched.h>
1969570cc8Sopenharmony_ci#include <stdbool.h>
2069570cc8Sopenharmony_ci#include <stdio.h>
2169570cc8Sopenharmony_ci#include <stdlib.h>
2269570cc8Sopenharmony_ci#include <unistd.h>
2369570cc8Sopenharmony_ci
2469570cc8Sopenharmony_ci#include <sys/mount.h>
2569570cc8Sopenharmony_ci#include <sys/stat.h>
2669570cc8Sopenharmony_ci#include <sys/syscall.h>
2769570cc8Sopenharmony_ci#include <sys/types.h>
2869570cc8Sopenharmony_ci
2969570cc8Sopenharmony_ci#include "appspawn_sandbox.h"
3069570cc8Sopenharmony_ci#include "appspawn_utils.h"
3169570cc8Sopenharmony_ci#include "securec.h"
3269570cc8Sopenharmony_ci
3369570cc8Sopenharmony_ci/*
3469570cc8Sopenharmony_ci名称            fs-type      flags                          options                 说明
3569570cc8Sopenharmony_cidefault                      MS_BIND MS_REC                                         默认可读写
3669570cc8Sopenharmony_cirdonly                       MS_NODEV MS_RDONLY                                     只读挂载
3769570cc8Sopenharmony_ciepfs            epfs         MS_NODEV                                                待讨论
3869570cc8Sopenharmony_cidac_override                 MS_NODEV MS_RDONLY             "support_overwrite=1"
3969570cc8Sopenharmony_ci开启const.filemanager.full_mount.enable
4069570cc8Sopenharmony_cifuse            fuse         MS_NOSUID MS_NODEV MS_NOEXEC MS_NOATIME MS_LAZYTIME
4169570cc8Sopenharmony_cidlp_fuse        fuse         MS_NOSUID MS_NODEV MS_NOEXEC MS_NOATIME MS_LAZYTIME     为dlpmanager管理应用专用的挂载参数
4269570cc8Sopenharmony_cishared                       MS_BIND MS_REC                                           root
4369570cc8Sopenharmony_cinamespace上是MS_SHARED方式挂载
4469570cc8Sopenharmony_ci
4569570cc8Sopenharmony_ci*/
4669570cc8Sopenharmony_ci/**
4769570cc8Sopenharmony_ci    "dac-override-sensitive": "true",  默认值:false。使能后直接使用默认值
4869570cc8Sopenharmony_ci    "sandbox-flags-customized": [ "MS_NODEV", "MS_RDONLY" ],
4969570cc8Sopenharmony_ci    "fs-type": "sharefs",
5069570cc8Sopenharmony_ci    "options": "support_overwrite=1"
5169570cc8Sopenharmony_ci*/
5269570cc8Sopenharmony_ci#define FUSE_MOUNT_FLAGS (MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME | MS_LAZYTIME)
5369570cc8Sopenharmony_ci#define FUSE_MOUNT_OPTIONS  \
5469570cc8Sopenharmony_ci    "fd=%d, rootmode=40000,user_id=%d,group_id=%d,allow_other," \
5569570cc8Sopenharmony_ci    "context=\"u:object_r:dlp_fuse_file:s0\", fscontext=u:object_r:dlp_fuse_file:s0"
5669570cc8Sopenharmony_ci
5769570cc8Sopenharmony_cistatic const MountArgTemplate DEF_MOUNT_ARG_TMP[MOUNT_TMP_MAX] = {
5869570cc8Sopenharmony_ci    {"default", MOUNT_TMP_DEFAULT, NULL, MS_BIND | MS_REC, NULL, MS_SLAVE},
5969570cc8Sopenharmony_ci    {"rdonly", MOUNT_TMP_RDONLY, NULL, MS_NODEV | MS_RDONLY, NULL, MS_SLAVE},
6069570cc8Sopenharmony_ci    {"epfs", MOUNT_TMP_EPFS, "epfs", MS_NODEV, NULL, MS_SLAVE},
6169570cc8Sopenharmony_ci    {"dac_override_delete", MOUNT_TMP_DAC_OVERRIDE_DELETE, "sharefs", MS_NODEV, "override_support_delete", MS_SLAVE},
6269570cc8Sopenharmony_ci    {"dac_override", MOUNT_TMP_DAC_OVERRIDE, "sharefs", MS_NODEV, "support_overwrite=1", MS_SLAVE},
6369570cc8Sopenharmony_ci    {"fuse", MOUNT_TMP_FUSE, "fuse", FUSE_MOUNT_FLAGS, FUSE_MOUNT_OPTIONS, MS_SHARED},
6469570cc8Sopenharmony_ci    {"dlp_fuse", MOUNT_TMP_DLP_FUSE, "fuse", FUSE_MOUNT_FLAGS, FUSE_MOUNT_OPTIONS, MS_SHARED},
6569570cc8Sopenharmony_ci    {"shared", MOUNT_TMP_SHRED, NULL, MS_BIND | MS_REC, NULL, MS_SHARED},
6669570cc8Sopenharmony_ci};
6769570cc8Sopenharmony_ci
6869570cc8Sopenharmony_cistatic const SandboxFlagInfo MOUNT_FLAGS_MAP[] = {
6969570cc8Sopenharmony_ci    {"rec", MS_REC}, {"MS_REC", MS_REC},
7069570cc8Sopenharmony_ci    {"bind", MS_BIND}, {"MS_BIND", MS_BIND}, {"move", MS_MOVE}, {"MS_MOVE", MS_MOVE},
7169570cc8Sopenharmony_ci    {"slave", MS_SLAVE}, {"MS_SLAVE", MS_SLAVE}, {"rdonly", MS_RDONLY}, {"MS_RDONLY", MS_RDONLY},
7269570cc8Sopenharmony_ci    {"shared", MS_SHARED}, {"MS_SHARED", MS_SHARED}, {"unbindable", MS_UNBINDABLE},
7369570cc8Sopenharmony_ci    {"MS_UNBINDABLE", MS_UNBINDABLE}, {"remount", MS_REMOUNT}, {"MS_REMOUNT", MS_REMOUNT},
7469570cc8Sopenharmony_ci    {"nosuid", MS_NOSUID}, {"MS_NOSUID", MS_NOSUID}, {"nodev", MS_NODEV}, {"MS_NODEV", MS_NODEV},
7569570cc8Sopenharmony_ci    {"noexec", MS_NOEXEC}, {"MS_NOEXEC", MS_NOEXEC}, {"noatime", MS_NOATIME}, {"MS_NOATIME", MS_NOATIME},
7669570cc8Sopenharmony_ci    {"lazytime", MS_LAZYTIME}, {"MS_LAZYTIME", MS_LAZYTIME}
7769570cc8Sopenharmony_ci};
7869570cc8Sopenharmony_ci
7969570cc8Sopenharmony_cistatic const SandboxFlagInfo PATH_MODE_MAP[] = {
8069570cc8Sopenharmony_ci    {"S_IRUSR", S_IRUSR}, {"S_IWUSR", S_IWUSR}, {"S_IXUSR", S_IXUSR},
8169570cc8Sopenharmony_ci    {"S_IRGRP", S_IRGRP}, {"S_IWGRP", S_IWGRP}, {"S_IXGRP", S_IXGRP},
8269570cc8Sopenharmony_ci    {"S_IROTH", S_IROTH}, {"S_IWOTH", S_IWOTH}, {"S_IXOTH", S_IXOTH},
8369570cc8Sopenharmony_ci    {"S_IRWXU", S_IRWXU}, {"S_IRWXG", S_IRWXG}, {"S_IRWXO", S_IRWXO}
8469570cc8Sopenharmony_ci};
8569570cc8Sopenharmony_ci
8669570cc8Sopenharmony_ciuint32_t GetMountCategory(const char *name)
8769570cc8Sopenharmony_ci{
8869570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(name != NULL, return MOUNT_TMP_DEFAULT);
8969570cc8Sopenharmony_ci    uint32_t count = ARRAY_LENGTH(DEF_MOUNT_ARG_TMP);
9069570cc8Sopenharmony_ci    for (uint32_t i = 0; i < count; i++) {
9169570cc8Sopenharmony_ci        if (strcmp(DEF_MOUNT_ARG_TMP[i].name, name) == 0) {
9269570cc8Sopenharmony_ci            return DEF_MOUNT_ARG_TMP[i].category;
9369570cc8Sopenharmony_ci        }
9469570cc8Sopenharmony_ci    }
9569570cc8Sopenharmony_ci    return MOUNT_TMP_DEFAULT;
9669570cc8Sopenharmony_ci}
9769570cc8Sopenharmony_ci
9869570cc8Sopenharmony_ciconst MountArgTemplate *GetMountArgTemplate(uint32_t category)
9969570cc8Sopenharmony_ci{
10069570cc8Sopenharmony_ci    uint32_t count = ARRAY_LENGTH(DEF_MOUNT_ARG_TMP);
10169570cc8Sopenharmony_ci    if (category > count) {
10269570cc8Sopenharmony_ci        return NULL;
10369570cc8Sopenharmony_ci    }
10469570cc8Sopenharmony_ci    for (uint32_t i = 0; i < count; i++) {
10569570cc8Sopenharmony_ci        if (DEF_MOUNT_ARG_TMP[i].category == category) {
10669570cc8Sopenharmony_ci            return &DEF_MOUNT_ARG_TMP[i];
10769570cc8Sopenharmony_ci        }
10869570cc8Sopenharmony_ci    }
10969570cc8Sopenharmony_ci    return NULL;
11069570cc8Sopenharmony_ci}
11169570cc8Sopenharmony_ci
11269570cc8Sopenharmony_ciconst SandboxFlagInfo *GetSandboxFlagInfo(const char *key, const SandboxFlagInfo *flagsInfos, uint32_t count)
11369570cc8Sopenharmony_ci{
11469570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(key != NULL, return NULL);
11569570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(flagsInfos != NULL, return NULL);
11669570cc8Sopenharmony_ci    for (uint32_t i = 0; i < count; i++) {
11769570cc8Sopenharmony_ci        if (strcmp(flagsInfos[i].name, key) == 0) {
11869570cc8Sopenharmony_ci            return &flagsInfos[i];
11969570cc8Sopenharmony_ci        }
12069570cc8Sopenharmony_ci    }
12169570cc8Sopenharmony_ci    return NULL;
12269570cc8Sopenharmony_ci}
12369570cc8Sopenharmony_ci
12469570cc8Sopenharmony_ciint GetPathMode(const char *name)
12569570cc8Sopenharmony_ci{
12669570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(name != NULL, return 0);
12769570cc8Sopenharmony_ci    const SandboxFlagInfo *info = GetSandboxFlagInfo(name, PATH_MODE_MAP, ARRAY_LENGTH(PATH_MODE_MAP));
12869570cc8Sopenharmony_ci    if (info != NULL) {
12969570cc8Sopenharmony_ci        return info->flags;
13069570cc8Sopenharmony_ci    }
13169570cc8Sopenharmony_ci    return 0;
13269570cc8Sopenharmony_ci}
13369570cc8Sopenharmony_ci
13469570cc8Sopenharmony_cistatic void DumpSandboxFlags(char *buffer, uint32_t bufferSize, unsigned long flags,
13569570cc8Sopenharmony_ci    const SandboxFlagInfo *flagsInfos, uint32_t count)
13669570cc8Sopenharmony_ci{
13769570cc8Sopenharmony_ci    bool first = true;
13869570cc8Sopenharmony_ci    size_t currLen = 0;
13969570cc8Sopenharmony_ci    int len = 0;
14069570cc8Sopenharmony_ci    unsigned long tmp = flags;
14169570cc8Sopenharmony_ci    for (uint32_t i = 0; i < count; i++) {
14269570cc8Sopenharmony_ci        if ((flagsInfos[i].flags & tmp) == 0) {
14369570cc8Sopenharmony_ci            continue;
14469570cc8Sopenharmony_ci        }
14569570cc8Sopenharmony_ci        tmp &= ~(flagsInfos[i].flags);
14669570cc8Sopenharmony_ci        if (!first) {
14769570cc8Sopenharmony_ci            len = sprintf_s(buffer + currLen, bufferSize - currLen - 1, " %s ", "|");
14869570cc8Sopenharmony_ci            APPSPAWN_CHECK_ONLY_EXPER(len > 0, return);
14969570cc8Sopenharmony_ci            currLen += len;
15069570cc8Sopenharmony_ci        }
15169570cc8Sopenharmony_ci        first = false;
15269570cc8Sopenharmony_ci        len = sprintf_s(buffer + currLen, bufferSize - currLen, "%s", flagsInfos[i].name);
15369570cc8Sopenharmony_ci        APPSPAWN_CHECK_ONLY_EXPER(len > 0, return);
15469570cc8Sopenharmony_ci        currLen += len;
15569570cc8Sopenharmony_ci    }
15669570cc8Sopenharmony_ci}
15769570cc8Sopenharmony_ci
15869570cc8Sopenharmony_cistatic void DumpMode(const char *info, mode_t mode)
15969570cc8Sopenharmony_ci{
16069570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(info != NULL, return);
16169570cc8Sopenharmony_ci    char buffer[64] = {0};  // 64 to show flags
16269570cc8Sopenharmony_ci    DumpSandboxFlags(buffer, sizeof(buffer), mode, PATH_MODE_MAP, ARRAY_LENGTH(PATH_MODE_MAP));
16369570cc8Sopenharmony_ci    APPSPAPWN_DUMP("%{public}s[0x%{public}x] %{public}s", info, (uint32_t)(mode), buffer);
16469570cc8Sopenharmony_ci}
16569570cc8Sopenharmony_ci
16669570cc8Sopenharmony_cistatic void DumpMountFlags(const char *info, unsigned long mountFlags)
16769570cc8Sopenharmony_ci{
16869570cc8Sopenharmony_ci    APPSPAWN_CHECK_ONLY_EXPER(info != NULL, return);
16969570cc8Sopenharmony_ci    char buffer[128] = {0};  // 64 to show flags
17069570cc8Sopenharmony_ci    DumpSandboxFlags(buffer, sizeof(buffer), mountFlags, MOUNT_FLAGS_MAP, ARRAY_LENGTH(MOUNT_FLAGS_MAP));
17169570cc8Sopenharmony_ci    APPSPAPWN_DUMP("%{public}s[0x%{public}x] %{public}s", info, (uint32_t)(mountFlags), buffer);
17269570cc8Sopenharmony_ci}
17369570cc8Sopenharmony_ci
17469570cc8Sopenharmony_civoid DumpMountPathMountNode(const PathMountNode *pathNode)
17569570cc8Sopenharmony_ci{
17669570cc8Sopenharmony_ci    const MountArgTemplate *tmp = GetMountArgTemplate(pathNode->category);
17769570cc8Sopenharmony_ci    if (tmp == NULL) {
17869570cc8Sopenharmony_ci        return;
17969570cc8Sopenharmony_ci    }
18069570cc8Sopenharmony_ci    APPSPAPWN_DUMP("        sandbox node category: %{public}u(%{public}s)", tmp->category, tmp->name);
18169570cc8Sopenharmony_ci    DumpMountFlags("        sandbox node mountFlags: ", tmp->mountFlags);
18269570cc8Sopenharmony_ci    APPSPAPWN_DUMP("        sandbox node mountSharedFlag: %{public}s",
18369570cc8Sopenharmony_ci        tmp->mountSharedFlag == MS_SLAVE ? "MS_SLAVE" : "MS_SHARED");
18469570cc8Sopenharmony_ci    APPSPAPWN_DUMP("        sandbox node options: %{public}s", tmp->options ? tmp->options : "null");
18569570cc8Sopenharmony_ci    APPSPAPWN_DUMP("        sandbox node fsType: %{public}s", tmp->fsType ? tmp->fsType : "null");
18669570cc8Sopenharmony_ci    DumpMode("        sandbox node destMode: ", pathNode->destMode);
18769570cc8Sopenharmony_ci    APPSPAPWN_DUMP("        sandbox node config mountSharedFlag: %{public}s",
18869570cc8Sopenharmony_ci        pathNode->mountSharedFlag ? "MS_SHARED" : "MS_SLAVE");
18969570cc8Sopenharmony_ci}