1 /*
2 * Copyright (C) 2025 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 "sandbox_shared.h"
17
18 #include <sys/mount.h>
19 #include "securec.h"
20
21 #include "appspawn_sandbox.h"
22 #include "appspawn_permission.h"
23 #include "appspawn_utils.h"
24 #include "parameter.h"
25
26 #define USER_ID_SIZE 16
27 #define DIR_MODE 0711
28 #define LOCK_STATUS_SIZE 16
29
30 #define DATA_GROUP_SOCKET_TYPE "DataGroup"
31 #define GROUPLIST_KEY_DATAGROUPID "dataGroupId"
32 #define GROUPLIST_KEY_GID "gid"
33 #define GROUPLIST_KEY_DIR "dir"
34 #define GROUPLIST_KEY_UUID "uuid"
35
36 static const MountSharedTemplate MOUNT_SHARED_MAP[] = {
37 {"/data/storage/el2", NULL},
38 {"/data/storage/el3", NULL},
39 {"/data/storage/el4", NULL},
40 {"/data/storage/el5", "ohos.permission.PROTECT_SCREEN_LOCK_DATA"},
41 };
42
43 static const DataGroupSandboxPathTemplate DATA_GROUP_SANDBOX_PATH_MAP[] = {
44 {"el2", EL2, "/data/storage/el2/group/", NULL},
45 {"el3", EL3, "/data/storage/el3/group/", NULL},
46 {"el4", EL4, "/data/storage/el4/group/", NULL},
47 {"el5", EL5, "/data/storage/el5/group/", "ohos.permission.PROTECT_SCREEN_LOCK_DATA"},
48 };
49
IsValidDataGroupItem(cJSON * item)50 bool IsValidDataGroupItem(cJSON *item)
51 {
52 // Check if the item contains the specified key and if the value corresponding to the key is a string
53 cJSON *datagroupId = cJSON_GetObjectItem(item, GROUPLIST_KEY_DATAGROUPID);
54 cJSON *gid = cJSON_GetObjectItem(item, GROUPLIST_KEY_GID);
55 cJSON *dir = cJSON_GetObjectItem(item, GROUPLIST_KEY_DIR);
56 cJSON *uuid = cJSON_GetObjectItem(item, GROUPLIST_KEY_UUID);
57
58 if (datagroupId && cJSON_IsString(datagroupId) &&
59 gid && cJSON_IsString(gid) &&
60 dir && cJSON_IsString(dir) &&
61 uuid && cJSON_IsString(uuid)) {
62 return true;
63 }
64 return false;
65 }
66
GetElxInfoFromDir(const char * path)67 int GetElxInfoFromDir(const char *path)
68 {
69 int ret = ELX_MAX;
70 if (path == NULL) {
71 return ret;
72 }
73 uint32_t count = ARRAY_LENGTH(DATA_GROUP_SANDBOX_PATH_MAP);
74 for (uint32_t i = 0; i < count; ++i) {
75 if (strstr(path, DATA_GROUP_SANDBOX_PATH_MAP[i].elxName) != NULL) {
76 return DATA_GROUP_SANDBOX_PATH_MAP[i].category;
77 }
78 }
79 APPSPAWN_LOGE("Get elx info from dir failed, path %{public}s", path);
80 return ret;
81 }
82
GetDataGroupArgTemplate(uint32_t category)83 const DataGroupSandboxPathTemplate *GetDataGroupArgTemplate(uint32_t category)
84 {
85 uint32_t count = ARRAY_LENGTH(DATA_GROUP_SANDBOX_PATH_MAP);
86 if (category > count) {
87 APPSPAWN_LOGE("category %{public}d is out of range", category);
88 return NULL;
89 }
90 for (uint32_t i = 0; i < count; ++i) {
91 if (DATA_GROUP_SANDBOX_PATH_MAP[i].category == category) {
92 return &DATA_GROUP_SANDBOX_PATH_MAP[i];
93 }
94 }
95 return NULL;
96 }
97
IsUnlockStatus(uint32_t uid)98 static bool IsUnlockStatus(uint32_t uid)
99 {
100 const int userIdBase = UID_BASE;
101 uid = uid / userIdBase;
102 if (uid == 0) {
103 return true;
104 }
105 char lockStatusParam[PARAM_BUFFER_SIZE] = {0};
106 int ret = snprintf_s(lockStatusParam, PARAM_BUFFER_SIZE, PARAM_BUFFER_SIZE - 1,
107 "startup.appspawn.lockstatus_%u", uid);
108 APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL,
109 "Format lock status param failed, errno: %{public}d", errno);
110
111 char userLockStatus[LOCK_STATUS_SIZE] = {0};
112 ret = GetParameter(lockStatusParam, "1", userLockStatus, sizeof(userLockStatus));
113 APPSPAWN_LOGI("Get param %{public}s %{public}s", lockStatusParam, userLockStatus);
114 if (ret > 0 && (strcmp(userLockStatus, "0") == 0)) { // 0:unlock status 1:lock status
115 return true;
116 }
117 return false;
118 }
119
SetSandboxPathShared(const char * sandboxPath)120 static bool SetSandboxPathShared(const char *sandboxPath)
121 {
122 int ret = mount(NULL, sandboxPath, NULL, MS_SHARED, NULL);
123 if (ret != 0) {
124 APPSPAWN_LOGW("Need to mount %{public}s to shared, errno %{public}d", sandboxPath, errno);
125 return false;
126 }
127 return true;
128 }
129
MountWithFileMgr(const AppDacInfo * info)130 static int MountWithFileMgr(const AppDacInfo *info)
131 {
132 /* /mnt/user/<currentUserId>/nosharefs/docs */
133 char nosharefsDocsDir[PATH_MAX_LEN] = {0};
134 int ret = snprintf_s(nosharefsDocsDir, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/user/%u/nosharefs/docs",
135 info->uid / UID_BASE);
136 if (ret <= 0) {
137 APPSPAWN_LOGE("snprintf nosharefsDocsDir failed, errno %{public}d", errno);
138 return APPSPAWN_ERROR_UTILS_MEM_FAIL;
139 }
140
141 /* /mnt/sandbox/<currentUser/app-root/storage/Users */
142 char storageUserPath[PATH_MAX_LEN] = {0};
143 ret = snprintf_s(storageUserPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/sandbox/%u/app-root/storage/Users",
144 info->uid / UID_BASE);
145 if (ret <= 0) {
146 APPSPAWN_LOGE("snprintf storageUserPath failed, errno %{public}d", errno);
147 return APPSPAWN_ERROR_UTILS_MEM_FAIL;
148 }
149
150 // Check whether the directory is a shared mount point
151 if (SetSandboxPathShared(storageUserPath)) {
152 APPSPAWN_LOGV("shared mountpoint is exist");
153 return 0;
154 }
155
156 ret = CreateSandboxDir(storageUserPath, DIR_MODE);
157 if (ret != 0) {
158 APPSPAWN_LOGE("mkdir %{public}s failed, errno %{public}d", storageUserPath, errno);
159 return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL;
160 }
161
162 MountArg arg = {
163 .originPath = nosharefsDocsDir,
164 .destinationPath = storageUserPath,
165 .fsType = NULL,
166 .mountFlags = MS_BIND | MS_REC,
167 .options = NULL,
168 .mountSharedFlag = MS_SHARED
169 };
170 ret = SandboxMountPath(&arg);
171 if (ret != 0) {
172 APPSPAWN_LOGE("mount %{public}s shared failed, ret %{public}d", storageUserPath, ret);
173 }
174 return ret;
175 }
176
MountWithOther(const AppDacInfo * info)177 static int MountWithOther(const AppDacInfo *info)
178 {
179 /* /mnt/user/<currentUserId>/sharefs/docs */
180 char sharefsDocsDir[PATH_MAX_LEN] = {0};
181 int ret = snprintf_s(sharefsDocsDir, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/user/%u/sharefs/docs",
182 info->uid / UID_BASE);
183 if (ret <= 0) {
184 APPSPAWN_LOGE("snprintf sharefsDocsDir failed, errno %{public}d", errno);
185 return APPSPAWN_ERROR_UTILS_MEM_FAIL;
186 }
187
188 /* /mnt/sandbox/<currentUser/app-root/storage/Users */
189 char storageUserPath[PATH_MAX_LEN] = {0};
190 ret = snprintf_s(storageUserPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/sandbox/%u/app-root/storage/Users",
191 info->uid / UID_BASE);
192 if (ret <= 0) {
193 APPSPAWN_LOGE("snprintf storageUserPath failed, errno %{public}d", errno);
194 return APPSPAWN_ERROR_UTILS_MEM_FAIL;
195 }
196
197 // Check whether the directory is a shared mount point
198 if (SetSandboxPathShared(storageUserPath)) {
199 APPSPAWN_LOGV("shared mountpoint is exist");
200 return 0;
201 }
202
203 ret = CreateSandboxDir(storageUserPath, DIR_MODE);
204 if (ret != 0) {
205 APPSPAWN_LOGE("mkdir %{public}s failed, errno %{public}d", storageUserPath, errno);
206 return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL;
207 }
208
209 char options[PATH_MAX_LEN] = {0};
210 ret = snprintf_s(options, PATH_MAX_LEN, PATH_MAX_LEN - 1, "override_support_delete,user_id=%u",
211 info->uid / UID_BASE);
212 if (ret <= 0) {
213 APPSPAWN_LOGE("snprintf options failed, errno %{public}d", errno);
214 return APPSPAWN_ERROR_UTILS_MEM_FAIL;
215 }
216
217 MountArg arg = {
218 .originPath = sharefsDocsDir,
219 .destinationPath = storageUserPath,
220 .fsType = "sharefs",
221 .mountFlags = MS_NODEV,
222 .options = options,
223 .mountSharedFlag = MS_SHARED
224 };
225 ret = SandboxMountPath(&arg);
226 if (ret != 0) {
227 APPSPAWN_LOGE("mount %{public}s shared failed, ret %{public}d", storageUserPath, ret);
228 }
229 return ret;
230 }
231
MountStorageUsers(const SandboxContext * context,AppSpawnSandboxCfg * sandbox,const AppDacInfo * info)232 static void MountStorageUsers(const SandboxContext *context, AppSpawnSandboxCfg *sandbox, const AppDacInfo *info)
233 {
234 int ret = 0;
235 int index = GetPermissionIndexInQueue(&sandbox->permissionQueue, FILE_ACCESS_MANAGER_MODE);
236 int checkRes = CheckSandboxCtxPermissionFlagSet(context, (uint32_t)index);
237 if (checkRes == 0) {
238 /* mount /mnt/user/<currentUserId>/sharefs/docs to /mnt/sandbox/<currentUserId>/app-root/storage/Users */
239 ret = MountWithOther(info);
240 } else {
241 /* mount /mnt/user/<currentUserId>/nosharefs/docs to /mnt/sandbox/<currentUserId>/app-root/storage/Users */
242 ret = MountWithFileMgr(info);
243 }
244 if (ret != 0) {
245 APPSPAWN_LOGE("Update %{public}s storage dir failed, ret %{public}d",
246 checkRes == 0 ? "sharefs dir" : "no sharefs dir", ret);
247 } else {
248 APPSPAWN_LOGI("Update %{public}s storage dir success", checkRes == 0 ? "sharefs dir" : "no sharefs dir");
249 }
250 }
251
MountSharedMapItem(const char * bundleNamePath,const char * sandboxPathItem)252 static int MountSharedMapItem(const char *bundleNamePath, const char *sandboxPathItem)
253 {
254 /* /mnt/sandbox/<currentUserId>/<bundleName>/data/storage/el<x> */
255 char sandboxPath[PATH_MAX_LEN] = {0};
256 int ret = snprintf_s(sandboxPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%s",
257 bundleNamePath, sandboxPathItem);
258 if (ret <= 0) {
259 APPSPAWN_LOGE("snprintf sandboxPath failed, errno %{public}d", errno);
260 return APPSPAWN_ERROR_UTILS_MEM_FAIL;
261 }
262
263 // Check whether the directory is a shared mount point
264 if (SetSandboxPathShared(sandboxPath)) {
265 APPSPAWN_LOGV("shared mountpoint is exist");
266 return 0;
267 }
268
269 ret = CreateSandboxDir(sandboxPath, DIR_MODE);
270 if (ret != 0) {
271 APPSPAWN_LOGE("mkdir %{public}s failed, errno %{public}d", sandboxPath, errno);
272 return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL;
273 }
274
275 MountArg arg = {
276 .originPath = sandboxPath,
277 .destinationPath = sandboxPath,
278 .fsType = NULL,
279 .mountFlags = MS_BIND | MS_REC,
280 .options = NULL,
281 .mountSharedFlag = MS_SHARED
282 };
283 ret = SandboxMountPath(&arg);
284 if (ret != 0) {
285 APPSPAWN_LOGE("mount %{public}s shared failed, ret %{public}d", sandboxPath, ret);
286 }
287 return ret;
288 }
289
MountSharedMap(const SandboxContext * context,AppSpawnSandboxCfg * sandbox,const char * bundleNamePath)290 static void MountSharedMap(const SandboxContext *context, AppSpawnSandboxCfg *sandbox, const char *bundleNamePath)
291 {
292 int length = sizeof(MOUNT_SHARED_MAP) / sizeof(MOUNT_SHARED_MAP[0]);
293 for (int i = 0; i < length; i++) {
294 if (MOUNT_SHARED_MAP[i].permission == NULL) {
295 MountSharedMapItem(bundleNamePath, MOUNT_SHARED_MAP[i].sandboxPath);
296 } else {
297 int index = GetPermissionIndexInQueue(&sandbox->permissionQueue, MOUNT_SHARED_MAP[i].permission);
298 APPSPAWN_LOGV("mount dir on lock mountPermissionFlags %{public}d", index);
299 if (CheckSandboxCtxPermissionFlagSet(context, (uint32_t)index)) {
300 MountSharedMapItem(bundleNamePath, MOUNT_SHARED_MAP[i].sandboxPath);
301 }
302 }
303 }
304 APPSPAWN_LOGI("mount shared map success");
305 }
306
DataGroupCtxNodeCompare(ListNode * node,void * data)307 static int DataGroupCtxNodeCompare(ListNode *node, void *data)
308 {
309 DataGroupCtx *existingNode = (DataGroupCtx *)ListEntry(node, DataGroupCtx, node);
310 DataGroupCtx *newNode = (DataGroupCtx *)data;
311 if (existingNode == NULL || newNode == NULL) {
312 APPSPAWN_LOGE("Invalid param");
313 return APPSPAWN_ARG_INVALID;
314 }
315
316 // compare src path and sandbox path
317 bool isSrcPathEqual = (strcmp(existingNode->srcPath.path, newNode->srcPath.path) == 0);
318 bool isDestPathEqual = (strcmp(existingNode->destPath.path, newNode->destPath.path) == 0);
319
320 return (isSrcPathEqual && isDestPathEqual) ? 0 : 1;
321 }
322
AddDataGroupItemToQueue(AppSpawnMgr * content,const char * srcPath,const char * destPath)323 static int AddDataGroupItemToQueue(AppSpawnMgr *content, const char *srcPath, const char *destPath)
324 {
325 DataGroupCtx *dataGroupNode = (DataGroupCtx *)calloc(1, sizeof(DataGroupCtx));
326 APPSPAWN_CHECK(dataGroupNode != NULL, return APPSPAWN_ERROR_UTILS_MEM_FAIL, "Calloc dataGroupNode failed");
327 if (strcpy_s(dataGroupNode->srcPath.path, PATH_MAX_LEN - 1, srcPath) != EOK ||
328 strcpy_s(dataGroupNode->destPath.path, PATH_MAX_LEN - 1, destPath) != EOK) {
329 APPSPAWN_LOGE("strcpy dataGroupNode path failed");
330 free(dataGroupNode);
331 dataGroupNode = NULL;
332 return APPSPAWN_ERROR_UTILS_MEM_FAIL;
333 }
334 dataGroupNode->srcPath.pathLen = strlen(dataGroupNode->srcPath.path);
335 dataGroupNode->destPath.pathLen = strlen(dataGroupNode->destPath.path);
336 ListNode *node = OH_ListFind(&content->dataGroupCtxQueue, (void *)dataGroupNode, DataGroupCtxNodeCompare);
337 if (node != NULL) {
338 APPSPAWN_LOGI("DataGroupCtxNode %{public}s is exist", dataGroupNode->srcPath.path);
339 free(dataGroupNode);
340 dataGroupNode = NULL;
341 return 0;
342 }
343 OH_ListInit(&dataGroupNode->node);
344 OH_ListAddTail(&content->dataGroupCtxQueue, &dataGroupNode->node);
345 return 0;
346 }
347
GetJsonObjFromExtInfo(const SandboxContext * context,const char * name)348 static inline cJSON *GetJsonObjFromExtInfo(const SandboxContext *context, const char *name)
349 {
350 uint32_t size = 0;
351 char *extInfo = (char *)(GetAppSpawnMsgExtInfo(context->message, name, &size));
352 if (size == 0 || extInfo == NULL) {
353 return NULL;
354 }
355 APPSPAWN_LOGV("Get json name %{public}s value %{public}s", name, extInfo);
356 cJSON *extInfoJson = cJSON_Parse(extInfo); // need to free
357 APPSPAWN_CHECK(extInfoJson != NULL, return NULL, "Invalid ext info %{public}s for %{public}s", extInfo, name);
358 return extInfoJson;
359 }
360
DumpDataGroupCtxQueue(const ListNode * front)361 static void DumpDataGroupCtxQueue(const ListNode *front)
362 {
363 if (front == NULL) {
364 return;
365 }
366
367 uint32_t count = 0;
368 ListNode *node = front->next;
369 while (node != front && node != NULL) {
370 DataGroupCtx *dataGroupNode = (DataGroupCtx *)ListEntry(node, DataGroupCtx, node);
371 count++;
372 APPSPAWN_LOGV(" ************************************** %{public}d", count);
373 APPSPAWN_LOGV(" srcPath: %{public}s", dataGroupNode->srcPath.path);
374 APPSPAWN_LOGV(" destPath: %{public}s", dataGroupNode->destPath.path);
375 node = node->next;
376 }
377 }
378
ParseDataGroupList(AppSpawnMgr * content,SandboxContext * context,const AppSpawnSandboxCfg * appSandbox,const char * bundleNamePath)379 static int ParseDataGroupList(AppSpawnMgr *content, SandboxContext *context, const AppSpawnSandboxCfg *appSandbox,
380 const char *bundleNamePath)
381 {
382 int ret = 0;
383 cJSON *dataGroupList = GetJsonObjFromExtInfo(context, DATA_GROUP_SOCKET_TYPE);
384 if (dataGroupList == NULL) {
385 return APPSPAWN_ARG_INVALID;
386 }
387
388 // Iterate through the array (assuming groups is an array)
389 cJSON *item = NULL;
390 cJSON_ArrayForEach(item, dataGroupList) {
391 // Check if the item is valid
392 APPSPAWN_CHECK(IsValidDataGroupItem(item), break, "Element is not a valid data group item");
393
394 cJSON *dirItem = cJSON_GetObjectItemCaseSensitive(item, "dir");
395 cJSON *uuidItem = cJSON_GetObjectItemCaseSensitive(item, "uuid");
396 if (dirItem == NULL || !cJSON_IsString(dirItem) || uuidItem == NULL || !cJSON_IsString(uuidItem)) {
397 APPSPAWN_LOGE("Data group element is invalid");
398 break;
399 }
400
401 const char *srcPath = dirItem->valuestring;
402 APPSPAWN_CHECK(!CheckPath(srcPath), break, "src path %{public}s is invalid", srcPath);
403
404 int elxValue = GetElxInfoFromDir(srcPath);
405 APPSPAWN_CHECK((elxValue >= EL2 && elxValue < ELX_MAX), break, "Get elx value failed");
406
407 const DataGroupSandboxPathTemplate *templateItem = GetDataGroupArgTemplate(elxValue);
408 APPSPAWN_CHECK(templateItem != NULL, break, "Get data group arg template failed");
409
410 // If permission isn't null, need check permission flag
411 if (templateItem->permission != NULL) {
412 int index = GetPermissionIndexInQueue(&appSandbox->permissionQueue, templateItem->permission);
413 APPSPAWN_LOGV("mount dir no lock mount permission flag %{public}d", index);
414 if (!CheckSandboxCtxPermissionFlagSet(context, (uint32_t)index)) {
415 continue;
416 }
417 }
418 // sandboxPath: /mnt/sandbox/<currentUserId>/<bundleName>/data/storage/el<x>/group/<uuid>
419 char targetPath[PATH_MAX_LEN] = {0};
420 int len = snprintf_s(targetPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%s%s",
421 bundleNamePath, templateItem->sandboxPath, uuidItem->valuestring);
422 APPSPAWN_CHECK(len > 0, break, "Failed to format targetPath");
423
424 ret = AddDataGroupItemToQueue(content, srcPath, targetPath);
425 if (ret != 0) {
426 APPSPAWN_LOGE("Add datagroup item to dataGroupCtxQueue failed, el%{public}d", elxValue);
427 OH_ListRemoveAll(&content->dataGroupCtxQueue, NULL);
428 break;
429 }
430 }
431 cJSON_Delete(dataGroupList);
432
433 DumpDataGroupCtxQueue(&content->dataGroupCtxQueue);
434 return ret;
435 }
436
UpdateDataGroupDirs(AppSpawnMgr * content)437 int UpdateDataGroupDirs(AppSpawnMgr *content)
438 {
439 if (content == NULL) {
440 return APPSPAWN_ARG_INVALID;
441 }
442
443 int ret = 0;
444 ListNode *node = content->dataGroupCtxQueue.next;
445 while (node != &content->dataGroupCtxQueue && node != NULL) {
446 DataGroupCtx *dataGroupNode = (DataGroupCtx *)ListEntry(node, DataGroupCtx, node);
447 MountArg args = {
448 .originPath = dataGroupNode->srcPath.path,
449 .destinationPath = dataGroupNode->destPath.path,
450 .fsType = NULL,
451 .mountFlags = MS_BIND | MS_REC,
452 .options = NULL,
453 .mountSharedFlag = MS_SHARED
454 };
455 ret = SandboxMountPath(&args);
456 if (ret != 0) {
457 APPSPAWN_LOGE("Shared mount %{public}s to %{public}s failed, errno %{public}d", args.originPath,
458 args.destinationPath, ret);
459 }
460 node = node->next;
461 }
462 OH_ListRemoveAll(&content->dataGroupCtxQueue, NULL);
463 return 0;
464 }
465
CreateSharedStamp(AppSpawnMsgDacInfo * info,SandboxContext * context)466 static int CreateSharedStamp(AppSpawnMsgDacInfo *info, SandboxContext *context)
467 {
468 char lockSbxPathStamp[PATH_MAX_LEN] = {0};
469 int ret = 0;
470 if (CheckSandboxCtxMsgFlagSet(context, APP_FLAGS_ISOLATED_SANDBOX_TYPE) != 0) {
471 ret = snprintf_s(lockSbxPathStamp, PATH_MAX_LEN, PATH_MAX_LEN - 1,
472 "/mnt/sandbox/%d/isolated/%s_locked", info->uid / UID_BASE, context->bundleName);
473 } else {
474 ret = snprintf_s(lockSbxPathStamp, PATH_MAX_LEN, PATH_MAX_LEN - 1,
475 "/mnt/sandbox/%d/%s_locked", info->uid / UID_BASE, context->bundleName);
476 }
477 if (ret <= 0) {
478 APPSPAWN_LOGE("Failed to format lock sandbox path stamp");
479 return APPSPAWN_ERROR_UTILS_MEM_FAIL;
480 }
481 ret = CreateSandboxDir(lockSbxPathStamp, DIR_MODE);
482 if (ret != 0) {
483 APPSPAWN_LOGE("Mkdir %{public}s failed, errno: %{public}d", lockSbxPathStamp, errno);
484 }
485 return ret;
486 }
487
MountDirsToShared(AppSpawnMgr * content,SandboxContext * context,AppSpawnSandboxCfg * sandbox)488 int MountDirsToShared(AppSpawnMgr *content, SandboxContext *context, AppSpawnSandboxCfg *sandbox)
489 {
490 if (content == NULL || context == NULL || sandbox == NULL) {
491 APPSPAWN_LOGE("Input paramters invalid");
492 return APPSPAWN_SANDBOX_INVALID;
493 }
494
495 AppSpawnMsgDacInfo *info = (AppSpawnMsgDacInfo *)GetSandboxCtxMsgInfo(context, TLV_DAC_INFO);
496 AppSpawnMsgBundleInfo *bundleInfo = (AppSpawnMsgBundleInfo *)GetSandboxCtxMsgInfo(context, TLV_BUNDLE_INFO);
497 if (info == NULL || bundleInfo == NULL) {
498 APPSPAWN_LOGE("Info or bundleInfo invalid");
499 return APPSPAWN_SANDBOX_INVALID;
500 }
501
502 if (IsUnlockStatus(info->uid)) {
503 return 0;
504 }
505
506 /* /mnt/sandbox/<currentUserId>/<bundleName> */
507 char bundleNamePath[PATH_MAX_LEN] = {0};
508 int ret = snprintf_s(bundleNamePath, PATH_MAX_LEN, PATH_MAX_LEN - 1,
509 "/mnt/sandbox/%u/%s", info->uid / UID_BASE, bundleInfo->bundleName);
510 if (ret < 0) {
511 APPSPAWN_LOGE("Failed to format lock sandbox path stamp");
512 return APPSPAWN_ERROR_UTILS_MEM_FAIL;
513 }
514
515 MountSharedMap(context, sandbox, bundleNamePath);
516 MountStorageUsers(context, sandbox, info);
517 ParseDataGroupList(content, context, sandbox, bundleNamePath);
518
519 ret = CreateSharedStamp(info, context);
520 if (ret != 0) {
521 APPSPAWN_LOGE("mkdir lockSbxPathStamp failed, ret: %{public}d", ret);
522 }
523 return ret;
524 }
525
MODULE_CONSTRUCTOR(void)526 MODULE_CONSTRUCTOR(void)
527 {
528 #ifdef APPSPAWN_SANDBOX_NEW
529 (void)AddServerStageHook(STAGE_SERVER_LOCK, HOOK_PRIO_COMMON, UpdateDataGroupDirs);
530 #endif
531 }
532