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 "appspawn_sandbox.h"
17
18 #include <errno.h>
19 #include <fcntl.h>
20 #include <sched.h>
21 #include <stdbool.h>
22 #include <stdio.h>
23 #include <stdlib.h>
24 #include <unistd.h>
25
26 #include <sys/mount.h>
27 #include <sys/stat.h>
28 #include <sys/syscall.h>
29 #include <sys/types.h>
30
31 #include "appspawn_msg.h"
32 #include "appspawn_utils.h"
33 #ifdef WITH_DLP
34 #include "dlp_fuse_fd.h"
35 #endif
36 #include "init_utils.h"
37 #include "parameter.h"
38 #include "securec.h"
39 #define LOCK_STATUS_PARAM_SIZE 64
40 #define LOCK_STATUS_SIZE 16
41
SetMountPathOperation(uint32_t * operation,uint32_t index)42 static inline void SetMountPathOperation(uint32_t *operation, uint32_t index)
43 {
44 *operation |= (1 << index);
45 }
46
CheckSpawningMsgFlagSet(const SandboxContext * context,uint32_t index)47 static inline bool CheckSpawningMsgFlagSet(const SandboxContext *context, uint32_t index)
48 {
49 APPSPAWN_CHECK(context->message != NULL, return false, "Invalid property for type %{public}u", TLV_MSG_FLAGS);
50 return CheckAppSpawnMsgFlag(context->message, TLV_MSG_FLAGS, index);
51 }
52
CheckSpawningPermissionFlagSet(const SandboxContext * context,uint32_t index)53 APPSPAWN_STATIC inline bool CheckSpawningPermissionFlagSet(const SandboxContext *context, uint32_t index)
54 {
55 APPSPAWN_CHECK(context != NULL && context->message != NULL,
56 return NULL, "Invalid property for type %{public}u", TLV_PERMISSION);
57 return CheckAppSpawnMsgFlag(context->message, TLV_PERMISSION, index);
58 }
59
CheckDirRecursive(const char * path)60 APPSPAWN_STATIC bool CheckDirRecursive(const char *path)
61 {
62 char buffer[PATH_MAX] = {0};
63 const char slash = '/';
64 const char *p = path;
65 char *curPos = strchr(path, slash);
66 while (curPos != NULL) {
67 int len = curPos - p;
68 p = curPos + 1;
69 if (len == 0) {
70 curPos = strchr(p, slash);
71 continue;
72 }
73 int ret = memcpy_s(buffer, PATH_MAX, path, p - path - 1);
74 APPSPAWN_CHECK(ret == 0, return false, "Failed to copy path");
75 ret = access(buffer, F_OK);
76 APPSPAWN_CHECK(ret == 0, return false, "Dir not exit %{public}s errno: %{public}d", buffer, errno);
77 curPos = strchr(p, slash);
78 }
79 int ret = access(path, F_OK);
80 APPSPAWN_CHECK(ret == 0, return false, "Dir not exit %{public}s errno: %{public}d", buffer, errno);
81 return true;
82 }
83
SandboxMountPath(const MountArg * arg)84 int SandboxMountPath(const MountArg *arg)
85 {
86 APPSPAWN_CHECK(arg != NULL && arg->originPath != NULL && arg->destinationPath != NULL,
87 return APPSPAWN_ARG_INVALID, "Invalid arg ");
88
89 APPSPAWN_LOGV("Bind mount arg: '%{public}s' '%{public}s' %{public}x '%{public}s' %{public}s => %{public}s",
90 arg->fsType, arg->mountSharedFlag == MS_SHARED ? "MS_SHARED" : "MS_SLAVE",
91 (uint32_t)arg->mountFlags, arg->options, arg->originPath, arg->destinationPath);
92
93 int ret = mount(arg->originPath, arg->destinationPath, arg->fsType, arg->mountFlags, arg->options);
94 if (ret != 0) {
95 if (arg->originPath != NULL && strstr(arg->originPath, "/data/app/el2/") != NULL) {
96 CheckDirRecursive(arg->originPath);
97 }
98 APPSPAWN_LOGW("errno is: %{public}d, bind mount %{public}s => %{public}s",
99 errno, arg->originPath, arg->destinationPath);
100 return errno;
101 }
102 ret = mount(NULL, arg->destinationPath, NULL, arg->mountSharedFlag, NULL);
103 if (ret != 0) {
104 APPSPAWN_LOGW("errno is: %{public}d, bind mount %{public}s => %{public}s",
105 errno, arg->originPath, arg->destinationPath);
106 return errno;
107 }
108 return 0;
109 }
110
BuildRootPath(char * buffer,uint32_t bufferLen,const AppSpawnSandboxCfg * sandbox,uid_t uid)111 static int BuildRootPath(char *buffer, uint32_t bufferLen, const AppSpawnSandboxCfg *sandbox, uid_t uid)
112 {
113 int ret = 0;
114 int len = 0;
115 uint32_t currLen = 0;
116 uint32_t userIdLen = sizeof(PARAMETER_USER_ID) - 1;
117 uint32_t rootLen = strlen(sandbox->rootPath);
118 char *rootPath = strstr(sandbox->rootPath, PARAMETER_USER_ID);
119 if (rootPath == NULL) {
120 len = sprintf_s(buffer, bufferLen, "%s/%d", sandbox->rootPath, uid);
121 } else {
122 ret = memcpy_s(buffer, bufferLen, sandbox->rootPath, rootPath - sandbox->rootPath);
123 APPSPAWN_CHECK(ret == 0, return ret, "Failed to copy root path %{public}s", sandbox->rootPath);
124 currLen = rootPath - sandbox->rootPath;
125
126 if (rootLen > (currLen + userIdLen)) {
127 len = sprintf_s(buffer + currLen, bufferLen - currLen, "%d%s",
128 uid, sandbox->rootPath + currLen + userIdLen);
129 } else {
130 len = sprintf_s(buffer + currLen, bufferLen - currLen, "%d", uid);
131 }
132 APPSPAWN_CHECK(len > 0 && (uint32_t)(len < (bufferLen - currLen)), return ret,
133 "Failed to format root path %{public}s", sandbox->rootPath);
134 currLen += (uint32_t)len;
135 }
136 buffer[currLen] = '\0';
137 return 0;
138 }
139
140 static SandboxContext *g_sandboxContext = NULL;
141
GetSandboxContext(void)142 SandboxContext *GetSandboxContext(void)
143 {
144 if (g_sandboxContext == NULL) {
145 SandboxContext *context = calloc(1, MAX_SANDBOX_BUFFER * MAX_BUFFER + sizeof(SandboxContext));
146 APPSPAWN_CHECK(context != NULL, return NULL, "Failed to get mem");
147 char *buffer = (char *)(context + 1);
148 for (int i = 0; i < MAX_BUFFER; i++) {
149 context->buffer[i].bufferLen = MAX_SANDBOX_BUFFER;
150 context->buffer[i].current = 0;
151 context->buffer[i].buffer = buffer + MAX_SANDBOX_BUFFER * i;
152 }
153 context->bundleName = NULL;
154 context->bundleHasWps = 0;
155 context->dlpBundle = 0;
156 context->appFullMountEnable = 0;
157 context->sandboxSwitch = 1;
158 context->sandboxShared = false;
159 context->message = NULL;
160 context->rootPath = NULL;
161 g_sandboxContext = context;
162 }
163 return g_sandboxContext;
164 }
165
DeleteSandboxContext(SandboxContext * context)166 void DeleteSandboxContext(SandboxContext *context)
167 {
168 APPSPAWN_CHECK_ONLY_EXPER(context != NULL, return);
169 if (context->rootPath) {
170 free(context->rootPath);
171 context->rootPath = NULL;
172 }
173 if (context == g_sandboxContext) {
174 g_sandboxContext = NULL;
175 }
176 free(context);
177 }
178
InitSandboxContext(SandboxContext * context,const AppSpawnSandboxCfg * sandbox,const AppSpawningCtx * property,int nwebspawn)179 static int InitSandboxContext(SandboxContext *context,
180 const AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn)
181 {
182 AppSpawnMsgFlags *msgFlags = (AppSpawnMsgFlags *)GetAppProperty(property, TLV_MSG_FLAGS);
183 APPSPAWN_CHECK(msgFlags != NULL, return APPSPAWN_TLV_NONE,
184 "No msg flags in msg %{public}s", GetProcessName(property));
185 context->nwebspawn = nwebspawn;
186 context->bundleName = GetBundleName(property);
187 context->bundleHasWps = strstr(context->bundleName, "wps") != NULL;
188 context->dlpBundle = strcmp(GetProcessName(property), "com.ohos.dlpmanager") == 0;
189 context->appFullMountEnable = sandbox->appFullMountEnable;
190
191 context->sandboxSwitch = 1;
192 context->sandboxShared = false;
193 SandboxPackageNameNode *packageNode = (SandboxPackageNameNode *)GetSandboxSection(
194 &sandbox->packageNameQueue, context->bundleName);
195 if (packageNode) {
196 context->sandboxShared = packageNode->section.sandboxShared;
197 }
198 context->message = property->message;
199 context->sandboxNsFlags = CLONE_NEWNS;
200 if ((CheckSpawningMsgFlagSet(context, APP_FLAGS_ISOLATED_SANDBOX) && !IsDeveloperModeOpen()) ||
201 CheckSpawningMsgFlagSet(context, APP_FLAGS_ISOLATED_NETWORK)) {
202 context->sandboxNsFlags |= sandbox->sandboxNsFlags & CLONE_NEWNET ? CLONE_NEWNET : 0;
203 }
204
205 // root path
206 const char *rootPath = GetSandboxRealVar(context, BUFFER_FOR_SOURCE, sandbox->rootPath, NULL, NULL);
207 if (rootPath) {
208 context->rootPath = strdup(rootPath);
209 }
210 if (context->rootPath == NULL) {
211 DeleteSandboxContext(context);
212 return -1;
213 }
214 return 0;
215 }
216
GetVarExtraData(const SandboxContext * context,const SandboxSection * section)217 static VarExtraData *GetVarExtraData(const SandboxContext *context, const SandboxSection *section)
218 {
219 static VarExtraData extraData;
220 (void)memset_s(&extraData, sizeof(extraData), 0, sizeof(extraData));
221 extraData.sandboxTag = GetSectionType(section);
222 if (GetSectionType(section) == SANDBOX_TAG_NAME_GROUP) {
223 SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)section;
224 extraData.data.depNode = groupNode->depNode;
225 }
226 return &extraData;
227 }
228
GetMountArgs(const SandboxContext * context,const PathMountNode * sandboxNode,uint32_t operation,MountArg * args)229 static uint32_t GetMountArgs(const SandboxContext *context,
230 const PathMountNode *sandboxNode, uint32_t operation, MountArg *args)
231 {
232 uint32_t category = sandboxNode->category;
233 const MountArgTemplate *tmp = GetMountArgTemplate(category);
234 if (tmp == 0) {
235 return MOUNT_TMP_DEFAULT;
236 }
237 args->fsType = tmp->fsType;
238 args->options = tmp->options;
239 args->mountFlags = tmp->mountFlags;
240 if (CHECK_FLAGS_BY_INDEX(operation, SANDBOX_TAG_PERMISSION)) {
241 if (!((category == MOUNT_TMP_DAC_OVERRIDE) && context->appFullMountEnable)) {
242 args->fsType = "";
243 args->options = "";
244 }
245 }
246 args->mountSharedFlag = (sandboxNode->mountSharedFlag) ? MS_SHARED : tmp->mountSharedFlag;
247 return category;
248 }
249
CheckSandboxMountNode(const SandboxContext * context,const SandboxSection * section,const PathMountNode * sandboxNode,uint32_t operation)250 APPSPAWN_STATIC int CheckSandboxMountNode(const SandboxContext *context,
251 const SandboxSection *section, const PathMountNode *sandboxNode, uint32_t operation)
252 {
253 if (sandboxNode->source == NULL || sandboxNode->target == NULL) {
254 APPSPAWN_LOGW("Invalid mount config section %{public}s", section->name);
255 return 0;
256 }
257 // special handle wps and don't use /data/app/xxx/<Package> config
258 if (CHECK_FLAGS_BY_INDEX(operation, SANDBOX_TAG_SPAWN_FLAGS)) { // flags-point
259 if (context->bundleHasWps &&
260 (strstr(sandboxNode->source, "/data/app") != NULL) &&
261 (strstr(sandboxNode->source, "/base") != NULL || strstr(sandboxNode->source, "/database") != NULL) &&
262 (strstr(sandboxNode->source, PARAMETER_PACKAGE_NAME) != NULL)) {
263 APPSPAWN_LOGW("Invalid mount source %{public}s section %{public}s",
264 sandboxNode->source, section->name);
265 return 0;
266 }
267 }
268 // check apl
269 AppSpawnMsgDomainInfo *msgDomainInfo = (AppSpawnMsgDomainInfo *)GetSpawningMsgInfo(context, TLV_DOMAIN_INFO);
270 if (msgDomainInfo != NULL && sandboxNode->appAplName != NULL) {
271 if (!strcmp(sandboxNode->appAplName, msgDomainInfo->apl)) {
272 APPSPAWN_LOGW("Invalid mount app apl %{public}s %{public}s section %{public}s",
273 sandboxNode->appAplName, msgDomainInfo->apl, section->name);
274 return 0;
275 }
276 }
277 return 1;
278 }
279
SandboxMountFusePath(const SandboxContext * context,const MountArg * args)280 static int32_t SandboxMountFusePath(const SandboxContext *context, const MountArg *args)
281 {
282 AppSpawnMsgDacInfo *info = (AppSpawnMsgDacInfo *)GetSpawningMsgInfo(context, TLV_DAC_INFO);
283 APPSPAWN_CHECK(info != NULL, return APPSPAWN_TLV_NONE,
284 "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, context->bundleName);
285
286 // umount fuse path, make sure that sandbox path is not a mount point
287 umount2(args->destinationPath, MNT_DETACH);
288
289 int fd = open("/dev/fuse", O_RDWR);
290 APPSPAWN_CHECK(fd != -1, return -EINVAL,
291 "open /dev/fuse failed, errno: %{public}d sandbox path %{public}s", errno, args->destinationPath);
292
293 char options[FUSE_OPTIONS_MAX_LEN];
294 (void)sprintf_s(options, sizeof(options), "fd=%d,"
295 "rootmode=40000,user_id=%d,group_id=%d,allow_other,"
296 "context=\"u:object_r:dlp_fuse_file:s0\","
297 "fscontext=u:object_r:dlp_fuse_file:s0", fd, info->uid, info->gid);
298
299 APPSPAWN_LOGV("Bind mount dlp fuse \n "
300 "mount arg: '%{public}s' '%{public}s' %{public}x '%{public}s' %{public}s => %{public}s",
301 args->fsType, args->mountSharedFlag == MS_SHARED ? "MS_SHARED" : "MS_SLAVE",
302 (uint32_t)args->mountFlags, options, args->originPath, args->destinationPath);
303
304 // To make sure destinationPath exist
305 CreateSandboxDir(args->destinationPath, FILE_MODE);
306 MountArg mountArg = {args->originPath, args->destinationPath, args->fsType, args->mountFlags, options, MS_SHARED};
307 int ret = SandboxMountPath(&mountArg);
308 if (ret != 0) {
309 close(fd);
310 return -1;
311 }
312 /* set DLP_FUSE_FD */
313 #ifdef WITH_DLP
314 SetDlpFuseFd(fd);
315 #endif
316 return 0;
317 }
318
CheckAndCreateSandboxFile(const char * file)319 APPSPAWN_STATIC void CheckAndCreateSandboxFile(const char *file)
320 {
321 if (access(file, F_OK) == 0) {
322 APPSPAWN_LOGI("file %{public}s already exist", file);
323 return;
324 }
325 MakeDirRec(file, FILE_MODE, 0);
326 int fd = open(file, O_CREAT, FILE_MODE);
327 if (fd < 0) {
328 APPSPAWN_LOGW("failed create %{public}s, err=%{public}d", file, errno);
329 } else {
330 close(fd);
331 }
332 return;
333 }
334
CreateDemandSrc(const SandboxContext * context,const PathMountNode * sandboxNode,const MountArg * args)335 APPSPAWN_STATIC void CreateDemandSrc(const SandboxContext *context, const PathMountNode *sandboxNode,
336 const MountArg *args)
337 {
338 if (!sandboxNode->createDemand) {
339 return;
340 }
341 CheckAndCreateSandboxFile(args->originPath);
342 AppSpawnMsgDacInfo *info = (AppSpawnMsgDacInfo *)GetSpawningMsgInfo(context, TLV_DAC_INFO);
343 APPSPAWN_CHECK(info != NULL, return,
344 "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, context->bundleName);
345
346 // chmod
347 uid_t uid = sandboxNode->demandInfo->uid != INVALID_UID ? sandboxNode->demandInfo->uid : info->uid;
348 gid_t gid = sandboxNode->demandInfo->gid != INVALID_UID ? sandboxNode->demandInfo->gid : info->gid;
349 int ret = chown(args->originPath, uid, gid);
350 if (ret != 0) {
351 APPSPAWN_LOGE("Failed to chown %{public}s errno: %{public}d", args->originPath, errno);
352 }
353 if (sandboxNode->demandInfo->mode != INVALID_UID) {
354 ret = chmod(args->originPath, sandboxNode->demandInfo->mode);
355 if (ret != 0) {
356 APPSPAWN_LOGE("Failed to chmod %{public}s errno: %{public}d", args->originPath, errno);
357 }
358 }
359 }
360
GetRealSrcPath(const SandboxContext * context,const char * source,VarExtraData * extraData)361 APPSPAWN_STATIC const char *GetRealSrcPath(const SandboxContext *context, const char *source, VarExtraData *extraData)
362 {
363 bool hasPackageName = strstr(source, "<variablePackageName>") != NULL;
364 extraData->variablePackageName = (char *)context->bundleName;
365 const char *originPath = GetSandboxRealVar(context, BUFFER_FOR_SOURCE, source, NULL, extraData);
366 if (originPath == NULL) {
367 return NULL;
368 }
369 if (!hasPackageName) {
370 return originPath;
371 }
372 if (!CheckSpawningMsgFlagSet(context, APP_FLAGS_ATOMIC_SERVICE) ||
373 !CheckDirRecursive(originPath)) {
374 return originPath;
375 }
376
377 AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetSpawningMsgInfo(context, TLV_DAC_INFO);
378 char *accountId = GetAppSpawnMsgExtInfo(context->message, MSG_EXT_NAME_ACCOUNT_ID, NULL);
379 if (accountId == NULL || dacInfo == NULL) {
380 return originPath;
381 }
382
383 // user target to format path
384 int len = sprintf_s(context->buffer[BUFFER_FOR_TARGET].buffer,
385 context->buffer[BUFFER_FOR_TARGET].bufferLen, "%s/%s", context->bundleName, accountId);
386 APPSPAWN_CHECK(len > 0, return NULL, "format variablePackageName fail %{public}s", context->bundleName);
387 extraData->variablePackageName = context->buffer[BUFFER_FOR_TARGET].buffer;
388 originPath = GetSandboxRealVar(context, BUFFER_FOR_SOURCE, source, NULL, extraData);
389 if (originPath == NULL) {
390 return NULL;
391 }
392 MakeDirRec(originPath, FILE_MODE, 0);
393 int ret = chown(originPath, dacInfo->uid, dacInfo->gid);
394 APPSPAWN_CHECK_ONLY_LOG(ret == 0, "chown failed, path %{public}s, errno %{public}d", originPath, errno);
395 return originPath;
396 }
397
DoSandboxPathNodeMount(const SandboxContext * context,const SandboxSection * section,const PathMountNode * sandboxNode,uint32_t operation)398 static int DoSandboxPathNodeMount(const SandboxContext *context,
399 const SandboxSection *section, const PathMountNode *sandboxNode, uint32_t operation)
400 {
401 if (CheckSandboxMountNode(context, section, sandboxNode, operation) == 0) {
402 return 0;
403 }
404
405 MountArg args = {};
406 uint32_t category = GetMountArgs(context, sandboxNode, operation, &args);
407 VarExtraData *extraData = GetVarExtraData(context, section);
408 args.originPath = GetRealSrcPath(context, sandboxNode->source, extraData);
409 // dest
410 extraData->operation = operation; // only destinationPath
411 // 对name group的节点,需要对目的沙盒进行特殊处理,不能带root-dir
412 if (CHECK_FLAGS_BY_INDEX(operation, SANDBOX_TAG_NAME_GROUP) &&
413 CHECK_FLAGS_BY_INDEX(operation, MOUNT_PATH_OP_ONLY_SANDBOX)) {
414 args.destinationPath = GetSandboxRealVar(context, BUFFER_FOR_TARGET, sandboxNode->target, NULL, extraData);
415 } else {
416 args.destinationPath = GetSandboxRealVar(context,
417 BUFFER_FOR_TARGET, sandboxNode->target, context->rootPath, extraData);
418 }
419 APPSPAWN_CHECK(args.originPath != NULL && args.destinationPath != NULL,
420 return APPSPAWN_ARG_INVALID, "Invalid path %{public}s %{public}s", args.originPath, args.destinationPath);
421
422 if (sandboxNode->sandboxNode.type == SANDBOX_TAG_MOUNT_FILE) {
423 CheckAndCreateSandboxFile(args.destinationPath);
424 } else {
425 CreateSandboxDir(args.destinationPath, FILE_MODE);
426 }
427 CreateDemandSrc(context, sandboxNode, &args);
428
429 if (CHECK_FLAGS_BY_INDEX(operation, MOUNT_PATH_OP_UNMOUNT)) { // unmount this deps
430 APPSPAWN_LOGV("umount2 %{public}s", args.destinationPath);
431 umount2(args.destinationPath, MNT_DETACH);
432 }
433 int ret = 0;
434 if ((category == MOUNT_TMP_DLP_FUSE || category == MOUNT_TMP_FUSE) && context->dlpBundle == 1) {
435 ret = SandboxMountFusePath(context, &args);
436 } else {
437 ret = SandboxMountPath(&args);
438 }
439
440 if (ret != 0 && sandboxNode->checkErrorFlag) {
441 APPSPAWN_LOGE("Failed to mount config, section: %{public}s result: %{public}d category: %{public}d",
442 section->name, ret, category);
443 return ret;
444 }
445 return 0;
446 }
447
DoSandboxPathSymLink(const SandboxContext * context,const SandboxSection * section,const SymbolLinkNode * sandboxNode)448 static int DoSandboxPathSymLink(const SandboxContext *context,
449 const SandboxSection *section, const SymbolLinkNode *sandboxNode)
450 {
451 // Check the validity of the symlink configuration
452 if (sandboxNode->linkName == NULL || sandboxNode->target == NULL) {
453 APPSPAWN_LOGW("Invalid symlink config, section %{public}s", section->name);
454 return 0;
455 }
456
457 const char *target = GetSandboxRealVar(context, BUFFER_FOR_SOURCE, sandboxNode->target, NULL, NULL);
458 const char *linkName = GetSandboxRealVar(context, BUFFER_FOR_TARGET,
459 sandboxNode->linkName, context->rootPath, NULL);
460 APPSPAWN_LOGV("symlink, from %{public}s to %{public}s", target, linkName);
461 int ret = symlink(target, linkName);
462 if (ret && errno != EEXIST) {
463 if (sandboxNode->checkErrorFlag) {
464 APPSPAWN_LOGE("symlink failed, errno: %{public}d link info %{public}s %{public}s",
465 errno, sandboxNode->target, sandboxNode->linkName);
466 return errno;
467 }
468 APPSPAWN_LOGV("symlink failed, errno: %{public}d link info %{public}s %{public}s",
469 errno, sandboxNode->target, sandboxNode->linkName);
470 }
471 return 0;
472 }
473
DoSandboxNodeMount(const SandboxContext * context,const SandboxSection * section,uint32_t operation)474 static int DoSandboxNodeMount(const SandboxContext *context, const SandboxSection *section, uint32_t operation)
475 {
476 ListNode *node = section->front.next;
477 while (node != §ion->front) {
478 int ret = 0;
479 SandboxMountNode *sandboxNode = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node);
480 switch (sandboxNode->type) {
481 case SANDBOX_TAG_MOUNT_PATH:
482 case SANDBOX_TAG_MOUNT_FILE:
483 ret = DoSandboxPathNodeMount(context, section, (PathMountNode *)sandboxNode, operation);
484 break;
485 case SANDBOX_TAG_SYMLINK:
486 if (!CHECK_FLAGS_BY_INDEX(operation, MOUNT_PATH_OP_SYMLINK)) {
487 break;
488 }
489 ret = DoSandboxPathSymLink(context, section, (SymbolLinkNode *)sandboxNode);
490 break;
491 default:
492 break;
493 }
494 if (ret != 0) {
495 return ret;
496 }
497 node = node->next;
498 }
499 return 0;
500 }
501
UpdateMountPathDepsPath(const SandboxContext * context,SandboxNameGroupNode * groupNode)502 static int UpdateMountPathDepsPath(const SandboxContext *context, SandboxNameGroupNode *groupNode)
503 {
504 PathMountNode *depNode = groupNode->depNode;
505 const char *srcPath = GetSandboxRealVar(context, BUFFER_FOR_SOURCE, depNode->source, NULL, NULL);
506 const char *sandboxPath = GetSandboxRealVar(context, BUFFER_FOR_TARGET, depNode->target, NULL, NULL);
507 if (srcPath == NULL || sandboxPath == NULL) {
508 APPSPAWN_LOGE("Failed to get real path %{public}s ", groupNode->section.name);
509 return APPSPAWN_SANDBOX_MOUNT_FAIL;
510 }
511 free(depNode->source);
512 depNode->source = strdup(srcPath);
513 free(depNode->target);
514 depNode->target = strdup(sandboxPath);
515 if (depNode->source == NULL || depNode->target == NULL) {
516 APPSPAWN_LOGE("Failed to get real path %{public}s ", groupNode->section.name);
517 if (depNode->source) {
518 free(depNode->source);
519 depNode->source = NULL;
520 }
521 if (depNode->target) {
522 free(depNode->target);
523 depNode->target = NULL;
524 }
525 return APPSPAWN_SANDBOX_MOUNT_FAIL;
526 }
527 return 0;
528 }
529
CheckAndCreateDepPath(const SandboxContext * context,const SandboxNameGroupNode * groupNode)530 static bool CheckAndCreateDepPath(const SandboxContext *context, const SandboxNameGroupNode *groupNode)
531 {
532 PathMountNode *mountNode = (PathMountNode *)GetFirstSandboxMountNode(&groupNode->section);
533 if (mountNode == NULL) {
534 return false;
535 }
536
537 // 这里可能需要替换deps的数据
538 VarExtraData *extraData = GetVarExtraData(context, &groupNode->section);
539 const char *srcPath = GetSandboxRealVar(context, BUFFER_FOR_SOURCE, mountNode->source, NULL, extraData);
540 if (srcPath == NULL) {
541 return false;
542 }
543 if (access(srcPath, F_OK) == 0) {
544 APPSPAWN_LOGV("Src path %{public}s exist, do not mount", srcPath);
545 return true;
546 }
547 // 不存在,则创建并挂载
548 APPSPAWN_LOGV("Mount depended source: %{public}s", groupNode->depNode->source);
549 CreateSandboxDir(groupNode->depNode->source, FILE_MODE);
550 return false;
551 }
552
MountSandboxConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox,const SandboxSection * section,uint32_t op)553 static int MountSandboxConfig(const SandboxContext *context,
554 const AppSpawnSandboxCfg *sandbox, const SandboxSection *section, uint32_t op)
555 {
556 uint32_t operation = (op != MOUNT_PATH_OP_NONE) ? op : 0;
557 SetMountPathOperation(&operation, section->sandboxNode.type);
558 // if sandbox switch is off, don't do symlink work again
559 if (context->sandboxSwitch && sandbox->topSandboxSwitch) {
560 SetMountPathOperation(&operation, MOUNT_PATH_OP_SYMLINK);
561 }
562
563 int ret = DoSandboxNodeMount(context, section, operation);
564 APPSPAWN_CHECK(ret == 0, return ret,
565 "Mount sandbox config fail result: %{public}d, app: %{public}s", ret, context->bundleName);
566
567 if (section->nameGroups == NULL) {
568 return 0;
569 }
570
571 for (uint32_t i = 0; i < section->number; i++) {
572 if (section->nameGroups[i] == NULL) {
573 continue;
574 }
575 SandboxNameGroupNode *groupNode = (SandboxNameGroupNode *)section->nameGroups[i];
576 SetMountPathOperation(&operation, SANDBOX_TAG_NAME_GROUP);
577 ret = DoSandboxNodeMount(context, &groupNode->section, operation);
578 APPSPAWN_CHECK(ret == 0, return ret,
579 "Mount name group %{public}s fail result: %{public}d", groupNode->section.name, ret);
580 }
581 return 0;
582 }
583
SetExpandSandboxConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)584 static int SetExpandSandboxConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
585 {
586 int ret = ProcessExpandAppSandboxConfig(context, sandbox, "HspList");
587 APPSPAWN_CHECK(ret == 0, return ret,
588 "Set HspList config fail result: %{public}d, app: %{public}s", ret, context->bundleName);
589 ret = ProcessExpandAppSandboxConfig(context, sandbox, "DataGroup");
590 APPSPAWN_CHECK(ret == 0, return ret,
591 "Set DataGroup config fail result: %{public}d, app: %{public}s", ret, context->bundleName);
592
593 bool mountDestBundlePath = false;
594 AppSpawnMsgDomainInfo *msgDomainInfo = (AppSpawnMsgDomainInfo *)GetSpawningMsgInfo(context, TLV_DOMAIN_INFO);
595 if (msgDomainInfo != NULL) {
596 mountDestBundlePath = (strcmp(msgDomainInfo->apl, APL_SYSTEM_BASIC) == 0) ||
597 (strcmp(msgDomainInfo->apl, APL_SYSTEM_CORE) == 0);
598 }
599 if (mountDestBundlePath || (CheckSpawningMsgFlagSet(context, APP_FLAGS_ACCESS_BUNDLE_DIR) != 0)) {
600 // need permission check for system app here
601 const char *destBundlesPath = GetSandboxRealVar(context,
602 BUFFER_FOR_TARGET, "/data/bundles/", context->rootPath, NULL);
603 CreateSandboxDir(destBundlesPath, FILE_MODE);
604 MountArg mountArg = {PHYSICAL_APP_INSTALL_PATH, destBundlesPath, NULL, MS_REC | MS_BIND, NULL, MS_SLAVE};
605 ret = SandboxMountPath(&mountArg);
606 APPSPAWN_CHECK(ret == 0, return ret, "mount library failed %{public}d", ret);
607 }
608 return 0;
609 }
610
SetSandboxPackageNameConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)611 static int SetSandboxPackageNameConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
612 {
613 SandboxPackageNameNode *sandboxNode =
614 (SandboxPackageNameNode *)GetSandboxSection(&sandbox->packageNameQueue, context->bundleName);
615 if (sandboxNode != NULL) {
616 int ret = MountSandboxConfig(context, sandbox, &sandboxNode->section, MOUNT_PATH_OP_NONE);
617 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
618 }
619 return 0;
620 }
621
SetSandboxSpawnFlagsConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)622 static int SetSandboxSpawnFlagsConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
623 {
624 ListNode *node = sandbox->spawnFlagsQueue.front.next;
625 while (node != &sandbox->spawnFlagsQueue.front) {
626 SandboxFlagsNode *sandboxNode = (SandboxFlagsNode *)ListEntry(node, SandboxMountNode, node);
627 // match flags point
628 if (sandboxNode->flagIndex == 0 || !CheckSpawningMsgFlagSet(context, sandboxNode->flagIndex)) {
629 node = node->next;
630 continue;
631 }
632
633 int ret = MountSandboxConfig(context, sandbox, &sandboxNode->section, MOUNT_PATH_OP_NONE);
634 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
635 node = node->next;
636 }
637 return 0;
638 }
639
SetSandboxPermissionConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)640 static int SetSandboxPermissionConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
641 {
642 APPSPAWN_LOGV("Set permission config");
643 ListNode *node = sandbox->permissionQueue.front.next;
644 while (node != &sandbox->permissionQueue.front) {
645 SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
646 if (!CheckSpawningPermissionFlagSet(context, permissionNode->permissionIndex)) {
647 node = node->next;
648 continue;
649 }
650
651 APPSPAWN_LOGV("SetSandboxPermissionConfig permission %{public}d %{public}s",
652 permissionNode->permissionIndex, permissionNode->section.name);
653 int ret = MountSandboxConfig(context, sandbox, &permissionNode->section, MOUNT_PATH_OP_NONE);
654 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
655 node = node->next;
656 }
657 return 0;
658 }
659
SetOverlayAppSandboxConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)660 static int SetOverlayAppSandboxConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
661 {
662 if (!CheckSpawningMsgFlagSet(context, APP_FLAGS_OVERLAY)) {
663 return 0;
664 }
665 int ret = ProcessExpandAppSandboxConfig(context, sandbox, "Overlay");
666 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
667 return 0;
668 }
669
SetBundleResourceSandboxConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)670 static int SetBundleResourceSandboxConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
671 {
672 if (!CheckSpawningMsgFlagSet(context, APP_FLAGS_BUNDLE_RESOURCES)) {
673 return 0;
674 }
675 const char *destPath = GetSandboxRealVar(context,
676 BUFFER_FOR_TARGET, "/data/storage/bundle_resources/", context->rootPath, NULL);
677 CreateSandboxDir(destPath, FILE_MODE);
678 MountArg mountArg = {
679 "/data/service/el1/public/bms/bundle_resources/", destPath, NULL, MS_REC | MS_BIND, NULL, MS_SLAVE
680 };
681 int ret = SandboxMountPath(&mountArg);
682 return ret;
683 }
684
ChangeCurrentDir(const SandboxContext * context)685 static int32_t ChangeCurrentDir(const SandboxContext *context)
686 {
687 int32_t ret = 0;
688 ret = chdir(context->rootPath);
689 APPSPAWN_CHECK(ret == 0, return ret,
690 "chdir failed, app: %{public}s, path: %{public}s errno: %{public}d",
691 context->bundleName, context->rootPath, errno);
692
693 if (context->sandboxShared) {
694 ret = chroot(context->rootPath);
695 APPSPAWN_CHECK(ret == 0, return ret,
696 "chroot failed, path: %{public}s errno: %{public}d", context->rootPath, errno);
697 return ret;
698 }
699 ret = syscall(SYS_pivot_root, context->rootPath, context->rootPath);
700 APPSPAWN_CHECK(ret == 0, return ret,
701 "pivot root failed, path: %{public}s errno: %{public}d", context->rootPath, errno);
702 ret = umount2(".", MNT_DETACH);
703 APPSPAWN_CHECK(ret == 0, return ret,
704 "MNT_DETACH failed, path: %{public}s errno: %{public}d", context->rootPath, errno);
705 APPSPAWN_LOGV("ChangeCurrentDir %{public}s ", context->rootPath);
706 return ret;
707 }
708
SandboxRootFolderCreateNoShare(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox,bool remountProc)709 static int SandboxRootFolderCreateNoShare(
710 const SandboxContext *context, const AppSpawnSandboxCfg *sandbox, bool remountProc)
711 {
712 APPSPAWN_LOGV("SandboxRootFolderCreateNoShare %{public}s ", context->rootPath);
713 int ret = mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL);
714 APPSPAWN_CHECK(ret == 0, return ret,
715 "set propagation slave failed, app: %{public}s errno: %{public}d", context->rootPath, errno);
716
717 MountArg arg = {context->rootPath, context->rootPath, NULL, BASIC_MOUNT_FLAGS, NULL, MS_SLAVE};
718 ret = SandboxMountPath(&arg);
719 APPSPAWN_CHECK(ret == 0, return ret,
720 "mount path failed, app: %{public}s errno: %{public}d", context->rootPath, ret);
721 return ret;
722 }
723
SandboxRootFolderCreate(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)724 static int SandboxRootFolderCreate(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
725 {
726 APPSPAWN_LOGV("topSandboxSwitch %{public}d sandboxSwitch: %{public}d sandboxShared: %{public}d \n",
727 sandbox->topSandboxSwitch, context->sandboxSwitch, context->sandboxShared);
728
729 int ret = 0;
730 if (sandbox->topSandboxSwitch == 0 || context->sandboxSwitch == 0) {
731 ret = mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL);
732 APPSPAWN_CHECK(ret == 0, return ret,
733 "set propagation slave failed, app: %{public}s errno: %{public}d", context->rootPath, errno);
734 // bind mount "/" to /mnt/sandbox/<packageName> path
735 // rootfs: to do more resources bind mount here to get more strict resources constraints
736 ret = mount("/", context->rootPath, NULL, BASIC_MOUNT_FLAGS, NULL);
737 APPSPAWN_CHECK(ret == 0, return ret,
738 "mount bind / failed, app: %{public}s errno: %{public}d", context->rootPath, errno);
739 } else if (!context->sandboxShared) {
740 bool remountProc = !context->nwebspawn && ((sandbox->sandboxNsFlags & CLONE_NEWPID) == CLONE_NEWPID);
741 ret = SandboxRootFolderCreateNoShare(context, sandbox, remountProc);
742 }
743 return ret;
744 }
745
IsSandboxMounted(const AppSpawnSandboxCfg * sandbox,const char * name,const char * rootPath)746 static bool IsSandboxMounted(const AppSpawnSandboxCfg *sandbox, const char *name, const char *rootPath)
747 {
748 char path[PATH_MAX] = {};
749 int len = sprintf_s(path, sizeof(path), "%s%s", rootPath, SANDBOX_STAMP_FILE_SUFFIX);
750 APPSPAWN_CHECK(len > 0, return false, "Failed to format path");
751
752 FILE *f = fopen(path, "rb");
753 if (f != NULL) {
754 fclose(f);
755 #ifndef APPSPAWN_TEST
756 return true;
757 #endif
758 }
759 return false;
760 }
761
SetSandboxMounted(const AppSpawnSandboxCfg * sandbox,const char * name,char * rootPath)762 static int SetSandboxMounted(const AppSpawnSandboxCfg *sandbox, const char *name, char *rootPath)
763 {
764 APPSPAWN_LOGW("SetSystemConstMounted %{public}s ", rootPath);
765 char path[PATH_MAX] = {};
766 int len = sprintf_s(path, sizeof(path), "%s%s", rootPath, SANDBOX_STAMP_FILE_SUFFIX);
767 APPSPAWN_CHECK(len > 0, return 0, "Failed to format path");
768
769 FILE *f = fopen(path, "wb");
770 if (f != NULL) {
771 fclose(f);
772 }
773 return 0;
774 }
775
UnmountPath(char * rootPath,uint32_t len,const SandboxMountNode * sandboxNode)776 static void UnmountPath(char *rootPath, uint32_t len, const SandboxMountNode *sandboxNode)
777 {
778 if (sandboxNode->type == SANDBOX_TAG_MOUNT_PATH) {
779 PathMountNode *pathNode = (PathMountNode *)sandboxNode;
780 int ret = strcat_s(rootPath, len, pathNode->target);
781 APPSPAWN_CHECK(ret == 0, return, "Failed to format");
782 APPSPAWN_LOGV("Unmount sandbox config sandbox path %{public}s ", rootPath);
783 ret = umount2(rootPath, MNT_DETACH);
784 APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Failed to umount2 %{public}s errno: %{public}d", rootPath, errno);
785 }
786 }
787
UnmountDepPaths(const AppSpawnSandboxCfg * sandbox,uid_t uid)788 int UnmountDepPaths(const AppSpawnSandboxCfg *sandbox, uid_t uid)
789 {
790 APPSPAWN_CHECK(sandbox != NULL, return -1, "Invalid sandbox or context");
791 APPSPAWN_LOGI("Unmount sandbox mount-paths-deps %{public}u ", sandbox->depNodeCount);
792 char path[PATH_MAX] = {};
793 int ret = BuildRootPath(path, sizeof(path), sandbox, uid / UID_BASE);
794 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return -1);
795 uint32_t rootLen = strlen(path);
796 for (uint32_t i = 0; i < sandbox->depNodeCount; i++) {
797 SandboxNameGroupNode *groupNode = sandbox->depGroupNodes[i];
798 if (groupNode == NULL || groupNode->depNode == NULL) {
799 continue;
800 }
801 // unmount this deps
802 UnmountPath(path, sizeof(path), &groupNode->depNode->sandboxNode);
803 path[rootLen] = '\0';
804 }
805 return 0;
806 }
807
UnmountSandboxConfigs(const AppSpawnSandboxCfg * sandbox,uid_t uid,const char * name)808 int UnmountSandboxConfigs(const AppSpawnSandboxCfg *sandbox, uid_t uid, const char *name)
809 {
810 APPSPAWN_CHECK(sandbox != NULL, return -1, "Invalid sandbox or context");
811 APPSPAWN_CHECK(name != NULL, return -1, "Invalid name");
812 char path[PATH_MAX] = {};
813 int ret = BuildRootPath(path, sizeof(path), sandbox, uid / UID_BASE);
814 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return -1);
815 uint32_t rootLen = strlen(path);
816 APPSPAWN_LOGI("Unmount sandbox %{public}s root: %{public}s", name, path);
817
818 if (!IsSandboxMounted(sandbox, name, path)) {
819 return 0;
820 }
821
822 SandboxSection *section = GetSandboxSection(&sandbox->requiredQueue, name);
823 if (section == NULL) {
824 return 0;
825 }
826 ListNode *node = section->front.next;
827 while (node != §ion->front) {
828 SandboxMountNode *sandboxNode = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node);
829 UnmountPath(path, sizeof(path), sandboxNode);
830 path[rootLen] = '\0';
831 // get next
832 node = node->next;
833 }
834
835 // delete stamp file
836 ret = strcat_s(path, sizeof(path), SANDBOX_STAMP_FILE_SUFFIX);
837 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return 0);
838 APPSPAWN_LOGI("Unmount sandbox %{public}s ", path);
839 unlink(path);
840 return 0;
841 }
842
StagedMountSystemConst(const AppSpawnSandboxCfg * sandbox,const AppSpawningCtx * property,int nwebspawn)843 int StagedMountSystemConst(const AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn)
844 {
845 APPSPAWN_CHECK(sandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
846 /**
847 * system-const 处理逻辑
848 * root-dir "/mnt/sandbox/app-root/<currentUserId>"
849 * 遍历system-const, 处理mount path -- 可以清除配置
850 * src = mount-path.src-path
851 * dst = root-dir + mount-path.sandbox-path
852 *
853 * 遍历name-groups,处理mount path
854 * 检查type,必须是 system-const
855 * 如果存在 mount-paths-deps
856 * src = mount-path.src-path
857 * dst = mount-path.sandbox-path --> 存在依赖时,配置<deps-path>、<deps-sandbox-path>、<deps-src-path>
858 * 否则:
859 * src = mount-path.src-path
860 * dst = root-dir + mount-path.sandbox-path
861 */
862 SandboxContext *context = GetSandboxContext();
863 APPSPAWN_CHECK_ONLY_EXPER(context != NULL, return APPSPAWN_SYSTEM_ERROR);
864 int ret = InitSandboxContext(context, sandbox, property, nwebspawn);
865 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
866
867 if (IsSandboxMounted(sandbox, "system-const", context->rootPath)) {
868 APPSPAWN_LOGV("Sandbox system-const %{public}s has been mount", context->rootPath);
869 DeleteSandboxContext(context);
870 return 0;
871 }
872
873 APPSPAWN_LOGV("Set sandbox system-const %{public}s", context->rootPath);
874 uint32_t operation = 0;
875 SetMountPathOperation(&operation, MOUNT_PATH_OP_REPLACE_BY_SANDBOX); // 首次挂载,使用sandbox替换
876 SandboxSection *section = GetSandboxSection(&sandbox->requiredQueue, "system-const");
877 if (section != NULL) {
878 ret = MountSandboxConfig(context, sandbox, section, operation);
879 }
880 SetSandboxMounted(sandbox, "system-const", context->rootPath);
881 DeleteSandboxContext(context);
882 return ret;
883 }
884
StagedMountPreUnShare(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)885 int StagedMountPreUnShare(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
886 {
887 APPSPAWN_CHECK(sandbox != NULL && context != NULL, return -1, "Invalid sandbox or context");
888 APPSPAWN_LOGV("Set sandbox config before unshare group count %{public}d", sandbox->depNodeCount);
889
890 /**
891 * 在unshare前处理mount-paths-deps 处理逻辑
892 * root-dir global.sandbox-root
893 * src-dir "/mnt/sandbox/app-common/<currentUserId>"
894 * 遍历mount-paths-deps,处理mount-paths-deps
895 * src = mount-paths-deps.src-path
896 * dst = root-dir + mount-paths-deps.sandbox-path
897 * 如果设置no-exist,检查mount-paths 的src(实际路径) 是否不存在,
898 则安mount-paths-deps.src-path 创建。 按shared方式挂载mount-paths-deps
899 * 如果是 always,按shared方式挂载mount-paths-deps
900 * 不配置 按always 处理
901 *
902 */
903 int ret = 0;
904 for (uint32_t i = 0; i < sandbox->depNodeCount; i++) {
905 SandboxNameGroupNode *groupNode = sandbox->depGroupNodes[i];
906 if (groupNode == NULL || groupNode->depNode == NULL) {
907 continue;
908 }
909 APPSPAWN_LOGV("Set sandbox deps config %{public}s ", groupNode->section.name);
910 // change source and target to real path
911 ret = UpdateMountPathDepsPath(context, groupNode);
912 APPSPAWN_CHECK(ret == 0, return ret,
913 "Failed to update deps path name group %{public}s", groupNode->section.name);
914
915 if (groupNode->depMode == MOUNT_MODE_NOT_EXIST && CheckAndCreateDepPath(context, groupNode)) {
916 continue;
917 }
918
919 uint32_t operation = 0;
920 SetMountPathOperation(&operation, MOUNT_PATH_OP_UNMOUNT);
921 groupNode->depMounted = 1;
922 ret = DoSandboxPathNodeMount(context, &groupNode->section, groupNode->depNode, operation);
923 if (ret != 0) {
924 APPSPAWN_LOGE("Mount deps root fail %{public}s", groupNode->section.name);
925 return ret;
926 }
927 }
928 return 0;
929 }
930
SetAppVariableConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)931 static int SetAppVariableConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
932 {
933 /**
934 * app-variable 处理逻辑
935 * root-dir global.sandbox-root
936 * app-variabl, 处理mount path
937 * src = mount-path.src-path
938 * dst = root-dir + mount-path.src-path
939 * 遍历name-groups,处理mount path
940 * 如果存在 mount-paths-deps
941 * dst = mount-path.sandbox-path --> 存在依赖时,配置<deps-path>、<deps-sandbox-path>、<deps-src-path>
942 * 否则:
943 * src = mount-path.src-path
944 * dst = root-dir + mount-path.sandbox-path
945 */
946 int ret = 0;
947 // 首次挂载,使用sandbox替换
948 uint32_t operation = 0;
949 SetMountPathOperation(&operation, MOUNT_PATH_OP_REPLACE_BY_SANDBOX);
950 SandboxSection *section = GetSandboxSection(&sandbox->requiredQueue, "app-variable");
951 if (section == NULL) {
952 return 0;
953 }
954 ret = MountSandboxConfig(context, sandbox, section, operation);
955 APPSPAWN_CHECK(ret == 0, return ret,
956 "Set app-variable config fail result: %{public}d, app: %{public}s", ret, context->bundleName);
957 return 0;
958 }
959
StagedMountPostUnshare(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)960 int StagedMountPostUnshare(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
961 {
962 APPSPAWN_CHECK(sandbox != NULL && context != NULL, return -1, "Invalid sandbox or context");
963 APPSPAWN_LOGV("Set sandbox config after unshare ");
964
965 int ret = SetAppVariableConfig(context, sandbox);
966 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
967 if (!context->nwebspawn) {
968 ret = SetExpandSandboxConfig(context, sandbox);
969 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
970 }
971
972 ret = SetSandboxSpawnFlagsConfig(context, sandbox);
973 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
974
975 ret = SetSandboxPackageNameConfig(context, sandbox);
976 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
977
978 ret = SetSandboxPermissionConfig(context, sandbox);
979 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
980 return ret;
981 }
982
MountSandboxConfigs(const AppSpawnSandboxCfg * sandbox,const AppSpawningCtx * property,int nwebspawn)983 int MountSandboxConfigs(const AppSpawnSandboxCfg *sandbox, const AppSpawningCtx *property, int nwebspawn)
984 {
985 APPSPAWN_CHECK_ONLY_EXPER(property != NULL, return -1);
986 APPSPAWN_CHECK(sandbox != NULL, return -1, "Failed to get sandbox for %{public}s", GetProcessName(property));
987
988 SandboxContext *context = GetSandboxContext();
989 APPSPAWN_CHECK_ONLY_EXPER(context != NULL, return APPSPAWN_SYSTEM_ERROR);
990 int ret = InitSandboxContext(context, sandbox, property, nwebspawn);
991 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
992
993 APPSPAWN_LOGV("Set sandbox config %{public}s sandboxNsFlags 0x%{public}x",
994 context->rootPath, context->sandboxNsFlags);
995 do {
996 ret = StagedMountPreUnShare(context, sandbox);
997 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
998
999 CreateSandboxDir(context->rootPath, FILE_MODE);
1000 // add pid to a new mnt namespace
1001 ret = unshare(context->sandboxNsFlags);
1002 APPSPAWN_CHECK(ret == 0, break,
1003 "unshare failed, app: %{public}s errno: %{public}d", context->bundleName, errno);
1004 if ((context->sandboxNsFlags & CLONE_NEWNET) == CLONE_NEWNET) {
1005 ret = EnableNewNetNamespace();
1006 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
1007 }
1008
1009 ret = SandboxRootFolderCreate(context, sandbox);
1010 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
1011
1012 ret = StagedMountPostUnshare(context, sandbox);
1013 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
1014
1015 ret = SetOverlayAppSandboxConfig(context, sandbox);
1016 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
1017 ret = SetBundleResourceSandboxConfig(context, sandbox);
1018 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
1019
1020 ret = ChangeCurrentDir(context);
1021 APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
1022 APPSPAWN_LOGV("Change root dir success %{public}s ", context->rootPath);
1023 } while (0);
1024 DeleteSandboxContext(context);
1025 return ret;
1026 }
1027