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