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