• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 != &section->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 != &section->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