1/* 2 * Copyright (c) 2024 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include <errno.h> 17#include <fcntl.h> 18#include <sched.h> 19#include <stdbool.h> 20#include <stdio.h> 21#include <stdlib.h> 22#include <unistd.h> 23 24#include <sys/mount.h> 25#include <sys/stat.h> 26#include <sys/syscall.h> 27#include <sys/types.h> 28 29#include "appspawn_sandbox.h" 30#include "appspawn_utils.h" 31#include "securec.h" 32 33/* 34名称 fs-type flags options 说明 35default MS_BIND MS_REC 默认可读写 36rdonly MS_NODEV MS_RDONLY 只读挂载 37epfs epfs MS_NODEV 待讨论 38dac_override MS_NODEV MS_RDONLY "support_overwrite=1" 39开启const.filemanager.full_mount.enable 40fuse fuse MS_NOSUID MS_NODEV MS_NOEXEC MS_NOATIME MS_LAZYTIME 41dlp_fuse fuse MS_NOSUID MS_NODEV MS_NOEXEC MS_NOATIME MS_LAZYTIME 为dlpmanager管理应用专用的挂载参数 42shared MS_BIND MS_REC root 43namespace上是MS_SHARED方式挂载 44 45*/ 46/** 47 "dac-override-sensitive": "true", 默认值:false。使能后直接使用默认值 48 "sandbox-flags-customized": [ "MS_NODEV", "MS_RDONLY" ], 49 "fs-type": "sharefs", 50 "options": "support_overwrite=1" 51*/ 52#define FUSE_MOUNT_FLAGS (MS_NOSUID | MS_NODEV | MS_NOEXEC | MS_NOATIME | MS_LAZYTIME) 53#define FUSE_MOUNT_OPTIONS \ 54 "fd=%d, rootmode=40000,user_id=%d,group_id=%d,allow_other," \ 55 "context=\"u:object_r:dlp_fuse_file:s0\", fscontext=u:object_r:dlp_fuse_file:s0" 56 57static const MountArgTemplate DEF_MOUNT_ARG_TMP[MOUNT_TMP_MAX] = { 58 {"default", MOUNT_TMP_DEFAULT, NULL, MS_BIND | MS_REC, NULL, MS_SLAVE}, 59 {"rdonly", MOUNT_TMP_RDONLY, NULL, MS_NODEV | MS_RDONLY, NULL, MS_SLAVE}, 60 {"epfs", MOUNT_TMP_EPFS, "epfs", MS_NODEV, NULL, MS_SLAVE}, 61 {"dac_override_delete", MOUNT_TMP_DAC_OVERRIDE_DELETE, "sharefs", MS_NODEV, "override_support_delete", MS_SLAVE}, 62 {"dac_override", MOUNT_TMP_DAC_OVERRIDE, "sharefs", MS_NODEV, "support_overwrite=1", MS_SLAVE}, 63 {"fuse", MOUNT_TMP_FUSE, "fuse", FUSE_MOUNT_FLAGS, FUSE_MOUNT_OPTIONS, MS_SHARED}, 64 {"dlp_fuse", MOUNT_TMP_DLP_FUSE, "fuse", FUSE_MOUNT_FLAGS, FUSE_MOUNT_OPTIONS, MS_SHARED}, 65 {"shared", MOUNT_TMP_SHRED, NULL, MS_BIND | MS_REC, NULL, MS_SHARED}, 66}; 67 68static const SandboxFlagInfo MOUNT_FLAGS_MAP[] = { 69 {"rec", MS_REC}, {"MS_REC", MS_REC}, 70 {"bind", MS_BIND}, {"MS_BIND", MS_BIND}, {"move", MS_MOVE}, {"MS_MOVE", MS_MOVE}, 71 {"slave", MS_SLAVE}, {"MS_SLAVE", MS_SLAVE}, {"rdonly", MS_RDONLY}, {"MS_RDONLY", MS_RDONLY}, 72 {"shared", MS_SHARED}, {"MS_SHARED", MS_SHARED}, {"unbindable", MS_UNBINDABLE}, 73 {"MS_UNBINDABLE", MS_UNBINDABLE}, {"remount", MS_REMOUNT}, {"MS_REMOUNT", MS_REMOUNT}, 74 {"nosuid", MS_NOSUID}, {"MS_NOSUID", MS_NOSUID}, {"nodev", MS_NODEV}, {"MS_NODEV", MS_NODEV}, 75 {"noexec", MS_NOEXEC}, {"MS_NOEXEC", MS_NOEXEC}, {"noatime", MS_NOATIME}, {"MS_NOATIME", MS_NOATIME}, 76 {"lazytime", MS_LAZYTIME}, {"MS_LAZYTIME", MS_LAZYTIME} 77}; 78 79static const SandboxFlagInfo PATH_MODE_MAP[] = { 80 {"S_IRUSR", S_IRUSR}, {"S_IWUSR", S_IWUSR}, {"S_IXUSR", S_IXUSR}, 81 {"S_IRGRP", S_IRGRP}, {"S_IWGRP", S_IWGRP}, {"S_IXGRP", S_IXGRP}, 82 {"S_IROTH", S_IROTH}, {"S_IWOTH", S_IWOTH}, {"S_IXOTH", S_IXOTH}, 83 {"S_IRWXU", S_IRWXU}, {"S_IRWXG", S_IRWXG}, {"S_IRWXO", S_IRWXO} 84}; 85 86uint32_t GetMountCategory(const char *name) 87{ 88 APPSPAWN_CHECK_ONLY_EXPER(name != NULL, return MOUNT_TMP_DEFAULT); 89 uint32_t count = ARRAY_LENGTH(DEF_MOUNT_ARG_TMP); 90 for (uint32_t i = 0; i < count; i++) { 91 if (strcmp(DEF_MOUNT_ARG_TMP[i].name, name) == 0) { 92 return DEF_MOUNT_ARG_TMP[i].category; 93 } 94 } 95 return MOUNT_TMP_DEFAULT; 96} 97 98const MountArgTemplate *GetMountArgTemplate(uint32_t category) 99{ 100 uint32_t count = ARRAY_LENGTH(DEF_MOUNT_ARG_TMP); 101 if (category > count) { 102 return NULL; 103 } 104 for (uint32_t i = 0; i < count; i++) { 105 if (DEF_MOUNT_ARG_TMP[i].category == category) { 106 return &DEF_MOUNT_ARG_TMP[i]; 107 } 108 } 109 return NULL; 110} 111 112const SandboxFlagInfo *GetSandboxFlagInfo(const char *key, const SandboxFlagInfo *flagsInfos, uint32_t count) 113{ 114 APPSPAWN_CHECK_ONLY_EXPER(key != NULL, return NULL); 115 APPSPAWN_CHECK_ONLY_EXPER(flagsInfos != NULL, return NULL); 116 for (uint32_t i = 0; i < count; i++) { 117 if (strcmp(flagsInfos[i].name, key) == 0) { 118 return &flagsInfos[i]; 119 } 120 } 121 return NULL; 122} 123 124int GetPathMode(const char *name) 125{ 126 APPSPAWN_CHECK_ONLY_EXPER(name != NULL, return 0); 127 const SandboxFlagInfo *info = GetSandboxFlagInfo(name, PATH_MODE_MAP, ARRAY_LENGTH(PATH_MODE_MAP)); 128 if (info != NULL) { 129 return info->flags; 130 } 131 return 0; 132} 133 134static void DumpSandboxFlags(char *buffer, uint32_t bufferSize, unsigned long flags, 135 const SandboxFlagInfo *flagsInfos, uint32_t count) 136{ 137 bool first = true; 138 size_t currLen = 0; 139 int len = 0; 140 unsigned long tmp = flags; 141 for (uint32_t i = 0; i < count; i++) { 142 if ((flagsInfos[i].flags & tmp) == 0) { 143 continue; 144 } 145 tmp &= ~(flagsInfos[i].flags); 146 if (!first) { 147 len = sprintf_s(buffer + currLen, bufferSize - currLen - 1, " %s ", "|"); 148 APPSPAWN_CHECK_ONLY_EXPER(len > 0, return); 149 currLen += len; 150 } 151 first = false; 152 len = sprintf_s(buffer + currLen, bufferSize - currLen, "%s", flagsInfos[i].name); 153 APPSPAWN_CHECK_ONLY_EXPER(len > 0, return); 154 currLen += len; 155 } 156} 157 158static void DumpMode(const char *info, mode_t mode) 159{ 160 APPSPAWN_CHECK_ONLY_EXPER(info != NULL, return); 161 char buffer[64] = {0}; // 64 to show flags 162 DumpSandboxFlags(buffer, sizeof(buffer), mode, PATH_MODE_MAP, ARRAY_LENGTH(PATH_MODE_MAP)); 163 APPSPAPWN_DUMP("%{public}s[0x%{public}x] %{public}s", info, (uint32_t)(mode), buffer); 164} 165 166static void DumpMountFlags(const char *info, unsigned long mountFlags) 167{ 168 APPSPAWN_CHECK_ONLY_EXPER(info != NULL, return); 169 char buffer[128] = {0}; // 64 to show flags 170 DumpSandboxFlags(buffer, sizeof(buffer), mountFlags, MOUNT_FLAGS_MAP, ARRAY_LENGTH(MOUNT_FLAGS_MAP)); 171 APPSPAPWN_DUMP("%{public}s[0x%{public}x] %{public}s", info, (uint32_t)(mountFlags), buffer); 172} 173 174void DumpMountPathMountNode(const PathMountNode *pathNode) 175{ 176 const MountArgTemplate *tmp = GetMountArgTemplate(pathNode->category); 177 if (tmp == NULL) { 178 return; 179 } 180 APPSPAPWN_DUMP(" sandbox node category: %{public}u(%{public}s)", tmp->category, tmp->name); 181 DumpMountFlags(" sandbox node mountFlags: ", tmp->mountFlags); 182 APPSPAPWN_DUMP(" sandbox node mountSharedFlag: %{public}s", 183 tmp->mountSharedFlag == MS_SLAVE ? "MS_SLAVE" : "MS_SHARED"); 184 APPSPAPWN_DUMP(" sandbox node options: %{public}s", tmp->options ? tmp->options : "null"); 185 APPSPAPWN_DUMP(" sandbox node fsType: %{public}s", tmp->fsType ? tmp->fsType : "null"); 186 DumpMode(" sandbox node destMode: ", pathNode->destMode); 187 APPSPAPWN_DUMP(" sandbox node config mountSharedFlag: %{public}s", 188 pathNode->mountSharedFlag ? "MS_SHARED" : "MS_SLAVE"); 189}