• 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 #undef _GNU_SOURCE
17 #define _GNU_SOURCE
18 
19 #include "appspawn_sandbox.h"
20 
21 #include <sys/mount.h>
22 #include <dirent.h>
23 #include "securec.h"
24 #include "appspawn_manager.h"
25 #include "appspawn_utils.h"
26 #include "modulemgr.h"
27 
28 #define DEBUG_MNT_TMP_ROOT     "/mnt/debugtmp/"
29 #define DEBUG_MNT_SHAREFS_ROOT "/mnt/debug/"
30 #define DEBUG_HAP_DIR          "debug_hap"
31 
32 typedef struct TagRemoveDebugDirInfo {
33     char *debugTmpPath;
34     char *debugPath;
35     AppSpawnSandboxCfg *sandboxCfg;
36     SandboxContext *context;
37 } RemoveDebugDirInfo;
38 
39 static int InitDebugSandboxContext(SandboxContext *context, const AppSpawnSandboxCfg *sandbox,
40                                    const AppSpawningCtx *property, int nwebspawn);
41 
UmountAndRmdirDir(const char * targetPath)42 static void UmountAndRmdirDir(const char *targetPath)
43 {
44     if (access(targetPath, F_OK) != 0) {
45         APPSPAWN_LOGE("targetPath %{public}s is not exist", targetPath);
46         return;
47     }
48 
49     int ret = umount2(targetPath, MNT_DETACH);
50     APPSPAWN_CHECK_ONLY_LOG(ret == 0, "umount failed %{public}s errno: %{public}d", targetPath, errno);
51     ret = rmdir(targetPath);
52     APPSPAWN_CHECK_ONLY_LOG(ret == 0, "rmdir failed %{public}s errno: %{public}d", targetPath, errno);
53     APPSPAWN_LOGI("rmdir targetPath: %{public}s", targetPath);
54 }
55 
RemoveDebugBaseConfig(SandboxSection * section,const char * debugRootPath)56 static int RemoveDebugBaseConfig(SandboxSection *section, const char *debugRootPath)
57 {
58     ListNode *node = section->front.next;
59     int ret = 0;
60     while (node != &section->front && node != NULL) {
61         SandboxMountNode *sandboxNode = (SandboxMountNode *)ListEntry(node, SandboxMountNode, node);
62         APPSPAWN_CHECK(sandboxNode != NULL, return APPSPAWN_SANDBOX_INVALID, "Get sandbox mount node failed");
63         char targetPath[PATH_MAX_LEN] = {0};
64         ret = snprintf_s(targetPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%s", debugRootPath,
65                          ((PathMountNode *)sandboxNode)->target);
66         APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL,
67                        "snprintf_s targetPath failed, errno: %{public}d", errno);
68         UmountAndRmdirDir(targetPath);
69         node = node->next;
70     }
71     return 0;
72 }
73 
RemoveDebugAppVarConfig(const AppSpawnSandboxCfg * sandboxCfg,const char * debugRootPath)74 static int RemoveDebugAppVarConfig(const AppSpawnSandboxCfg *sandboxCfg, const char *debugRootPath)
75 {
76     SandboxSection *section = GetSandboxSection(&sandboxCfg->requiredQueue, "app-variable");
77     if (section == NULL) {
78         return 0;
79     }
80 
81     return RemoveDebugBaseConfig(section, debugRootPath);
82 }
83 
RemoveDebugPermissionConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandboxCfg,const char * debugRootPath)84 static int RemoveDebugPermissionConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandboxCfg,
85                                        const char *debugRootPath)
86 {
87     ListNode *node = sandboxCfg->permissionQueue.front.next;
88     int ret = 0;
89     while (node != &sandboxCfg->permissionQueue.front && node != NULL) {
90         SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
91         APPSPAWN_CHECK(permissionNode != NULL, return APPSPAWN_SANDBOX_INVALID, "Get sandbox permission node failed");
92         APPSPAWN_LOGV("CheckSandboxCtxPermissionFlagSet permission %{public}d %{public}s",
93                       permissionNode->permissionIndex, permissionNode->section.name);
94         ret = RemoveDebugBaseConfig(&permissionNode->section, debugRootPath);
95         APPSPAWN_CHECK(ret == 0, return ret, "Failed to remove debug permission config");
96         node = node->next;
97     }
98     return ret;
99 }
100 
101 // 获取userId信息,若消息请求中携带userId拓展字段则使用userId否则使用info信息中的uid
ConvertUserIdPath(const AppSpawningCtx * property,char * debugRootPath,char * debugTmpRootPath)102 static int ConvertUserIdPath(const AppSpawningCtx *property, char *debugRootPath, char *debugTmpRootPath)
103 {
104     int ret = 0;
105     char *userId = (char *)GetAppSpawnMsgExtInfo(property->message, MSG_EXT_NAME_USERID, NULL);
106     if (userId == NULL) {
107         AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
108         APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE, "No tlv %{public}d in msg", TLV_DAC_INFO);
109         ret = snprintf_s(debugRootPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%d/", DEBUG_MNT_SHAREFS_ROOT,
110                          dacInfo->uid / UID_BASE);
111         APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL,
112                        "snprintf_s debugRootPath failed, errno: %{public}d", errno);
113         ret = snprintf_s(debugTmpRootPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%d/", DEBUG_MNT_TMP_ROOT,
114                          dacInfo->uid / UID_BASE);
115         APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL,
116                        "snprintf_s debugTmpRootPath failed, errno: %{public}d", errno);
117     } else {
118         ret = snprintf_s(debugRootPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%s/", DEBUG_MNT_SHAREFS_ROOT, userId);
119         APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL,
120                        "snprintf_s debugRootPath failed, errno: %{public}d", errno);
121         ret = snprintf_s(debugTmpRootPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%s/", DEBUG_MNT_TMP_ROOT, userId);
122         APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL,
123                        "snprintf_s debugTmpRootPath failed, errno: %{public}d", errno);
124     }
125     return 0;
126 }
127 
UninstallPrivateDirs(const AppSpawnMgr * content,const AppSpawningCtx * property,RemoveDebugDirInfo * removeDebugDirInfo)128 static int UninstallPrivateDirs(const AppSpawnMgr *content, const AppSpawningCtx *property,
129                                 RemoveDebugDirInfo *removeDebugDirInfo)
130 {
131     AppSpawnMsgDacInfo *dacInfo = (AppSpawnMsgDacInfo *)GetAppProperty(property, TLV_DAC_INFO);
132     APPSPAWN_CHECK(dacInfo != NULL, return APPSPAWN_TLV_NONE, "No tlv %{public}d in msg", TLV_DAC_INFO);
133 
134     char uidPath[PATH_MAX_LEN] = {0};
135     /* snprintf_s /mnt/debugtmp/<uid> */
136     int ret = snprintf_s(uidPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%d/", DEBUG_MNT_TMP_ROOT, dacInfo->uid / UID_BASE);
137     APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL,
138                    "snprintf_s /mnt/debugtmp/<uid> failed, errno: %{public}d", errno);
139 
140     /* snprintf_s /mnt/debugtmp/<userId>/debug_hap/<variablePackageName> */
141     ret = snprintf_s(removeDebugDirInfo->debugTmpPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%s",
142                      removeDebugDirInfo->debugTmpPath, removeDebugDirInfo->context->rootPath + strlen(uidPath));
143     APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL,
144         "snprintf_s /mnt/debugtmp/<userId>/debug_hap/<variablePackageName> failed, errno: %{public}d", errno);
145 
146     ret = RemoveDebugAppVarConfig(removeDebugDirInfo->sandboxCfg, removeDebugDirInfo->debugTmpPath);
147     APPSPAWN_CHECK(ret == 0, return ret, "Failed to remove debug app variable config");
148 
149     ret = RemoveDebugPermissionConfig(removeDebugDirInfo->context, removeDebugDirInfo->sandboxCfg,
150                                       removeDebugDirInfo->debugTmpPath);
151     APPSPAWN_CHECK(ret == 0, return ret, "Failed to remove debug permission config");
152 
153     /* umount and remove dir /mnt/debug/<userId>/debug_hap/<variablePackageName> */
154     ret = snprintf_s(removeDebugDirInfo->debugPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%s/",
155         removeDebugDirInfo->debugPath, removeDebugDirInfo->context->rootPath + strlen(uidPath));
156     APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL,
157         "snprintf_s /mnt/debug/<userId>/debug_hap/<variablePackageName> failed, errno: %{public}d", errno);
158     UmountAndRmdirDir(removeDebugDirInfo->debugPath);
159 
160     return 0;
161 }
162 
UninstallAllDirs(const AppSpawnMgr * content,const AppSpawningCtx * property,RemoveDebugDirInfo * removeDebugDirInfo)163 static int UninstallAllDirs(const AppSpawnMgr *content, const AppSpawningCtx *property,
164                             RemoveDebugDirInfo *removeDebugDirInfo)
165 {
166     /* snprintf_s /mnt/debugtmp/<uid>/debug_hap */
167     int ret = snprintf_s(removeDebugDirInfo->debugTmpPath + strlen(removeDebugDirInfo->debugTmpPath), PATH_MAX_LEN,
168                          PATH_MAX_LEN - 1, "%s/", "debug_hap");
169     APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL,
170                    "snprintf_s /mnt/debugtmp/<uid>/debug_hap failed, errno: %{public}d", errno);
171 
172     char debugTmpPackagePath[PATH_MAX_LEN] = {0};
173     char debugPackagePath[PATH_MAX_LEN] = {0};
174     DIR *dir = opendir(removeDebugDirInfo->debugTmpPath);
175     APPSPAWN_CHECK(dir != NULL, return APPSPAWN_SYSTEM_ERROR,
176         "Failed to open %{public}s, errno: %{public}d", removeDebugDirInfo->debugTmpPath, errno);
177     struct dirent *entry;
178     while ((entry = readdir(dir)) != NULL) {
179         if (entry->d_name[0] == '.') {
180             continue;
181         }
182         (void)memset_s(debugPackagePath, PATH_MAX_LEN, 0, PATH_MAX_LEN);
183         (void)memset_s(debugTmpPackagePath, PATH_MAX_LEN, 0, PATH_MAX_LEN);
184 
185         /* snprintf_s /mnt/debugtmp/<uid>/debug_hap/<variablePackageName> */
186         ret = snprintf_s(debugTmpPackagePath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%s",
187                          removeDebugDirInfo->debugTmpPath, entry->d_name);
188         APPSPAWN_CHECK(ret > 0, closedir(dir); return APPSPAWN_ERROR_UTILS_MEM_FAIL,
189             "snprintf_s /mnt/debugtmp/<uid>/debug_hap/<variablePackageName> failed, errno: %{public}d", errno);
190 
191         ret = RemoveDebugAppVarConfig(removeDebugDirInfo->sandboxCfg, debugTmpPackagePath);
192         APPSPAWN_CHECK(ret == 0, closedir(dir);
193                                  return ret, "Failed to remove app variable config");
194 
195         ret = RemoveDebugPermissionConfig(removeDebugDirInfo->context, removeDebugDirInfo->sandboxCfg,
196                                           debugTmpPackagePath);
197         APPSPAWN_CHECK(ret == 0, closedir(dir);
198                                  return ret, "Failed to remove debug permission config");
199 
200         /**
201          * umount and remove dir /mnt/debug/<uid>/debug_hap/<variablePackageName>
202          * /mnt/debug + <uid>/debug_hap/<variablePackageName>(debugTmpPackagePath)
203          */
204         ret = snprintf_s(debugPackagePath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%s", DEBUG_MNT_SHAREFS_ROOT,
205                          debugTmpPackagePath + strlen(DEBUG_MNT_TMP_ROOT));
206         APPSPAWN_CHECK(ret > 0, closedir(dir); return APPSPAWN_ERROR_UTILS_MEM_FAIL,
207             "snprintf_s /mnt/debug/<uid>/debug_hap/<variablePackageName> failed, errno: %{public}d", errno);
208         UmountAndRmdirDir(debugPackagePath);
209     }
210     closedir(dir);
211     return 0;
212 }
213 
UninstallDebugSandbox(AppSpawnMgr * content,AppSpawningCtx * property)214 static int UninstallDebugSandbox(AppSpawnMgr *content, AppSpawningCtx *property)
215 {
216     APPSPAWN_CHECK(content != NULL && property != NULL, return APPSPAWN_ARG_INVALID,
217         "Invalid appspawn client or property");
218     char debugRootPath[PATH_MAX_LEN] = {0};
219     char debugTmpRootPath[PATH_MAX_LEN] = {0};
220 
221     int ret = ConvertUserIdPath(property, debugRootPath, debugTmpRootPath);
222     APPSPAWN_CHECK(ret == 0, return ret, "Failed to convert userid path");
223 
224     AppSpawnSandboxCfg *sandboxCfg = GetAppSpawnSandbox(content, EXT_DATA_DEBUG_HAP_SANDBOX);
225     APPSPAWN_CHECK(sandboxCfg != NULL, return APPSPAWN_SANDBOX_INVALID,
226                               "Failed to get sandbox for %{public}s", GetProcessName(property));
227 
228     SandboxContext *context = GetSandboxContext();   // Need free after mounting each time
229     APPSPAWN_CHECK_ONLY_EXPER(context != NULL, return APPSPAWN_ERROR_UTILS_MEM_FAIL);
230     ret = InitDebugSandboxContext(context, sandboxCfg, property, IsNWebSpawnMode(content));
231     APPSPAWN_CHECK_ONLY_EXPER(ret == 0, DeleteSandboxContext(&context);
232                                         return ret);
233 
234     RemoveDebugDirInfo removeDebugDirInfo = {
235         .debugPath = debugRootPath,
236         .debugTmpPath = debugTmpRootPath,
237         .context = context,
238         .sandboxCfg = sandboxCfg
239     };
240     // If the message request carries package name information, it is necessary to obtain the actual package name
241     if (GetBundleName(property) != NULL) {
242         ret = UninstallPrivateDirs(content, property, &removeDebugDirInfo);
243     } else {  // Traverse directories from debugTmpRootPath directory
244         ret = UninstallAllDirs(content, property, &removeDebugDirInfo);
245     }
246     APPSPAWN_CHECK_ONLY_LOG(ret == 0, "Failed to uninstall debug hap dir, ret: %{public}d", ret);
247 
248     DeleteSandboxContext(&context);
249     return 0;
250 }
251 
252 // Mount the point of the app-variable attribute in the debug attribute.
SetDebugAppVarConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)253 static int SetDebugAppVarConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
254 {
255     SandboxSection *section = GetSandboxSection(&sandbox->requiredQueue, "app-variable");
256     if (section == NULL) {
257         return 0;
258     }
259 
260     uint32_t operation = 0;
261     if (CheckSandboxCtxMsgFlagSet(context, APP_FLAGS_ATOMIC_SERVICE)) {
262         SetMountPathOperation(&operation, MOUNT_PATH_OP_UNMOUNT);
263     }
264     int ret = MountSandboxConfig(context, sandbox, section, operation);
265     APPSPAWN_CHECK(ret == 0, return ret, "Set debug app-variable config fail result: %{public}d, app: %{public}s",
266                    ret, context->bundleName);
267     return 0;
268 }
269 
SetDebugPermissionConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)270 static int SetDebugPermissionConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
271 {
272     ListNode *node = sandbox->permissionQueue.front.next;
273     while (node != &sandbox->permissionQueue.front && node != NULL) {
274         SandboxPermissionNode *permissionNode = (SandboxPermissionNode *)ListEntry(node, SandboxMountNode, node);
275         if (!CheckSandboxCtxPermissionFlagSet(context, permissionNode->permissionIndex)) {
276             node = node->next;
277             continue;
278         }
279 
280         APPSPAWN_LOGV("SetSandboxPermissionConfig permission %{public}d %{public}s",
281                       permissionNode->permissionIndex, permissionNode->section.name);
282         uint32_t operation = MOUNT_PATH_OP_NONE;
283         if (CheckSandboxCtxMsgFlagSet(context, APP_FLAGS_ATOMIC_SERVICE)) {
284             SetMountPathOperation(&operation, MOUNT_PATH_OP_UNMOUNT);
285         }
286         int ret = MountSandboxConfig(context, sandbox, &permissionNode->section, operation);
287         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
288         node = node->next;
289     }
290     return 0;
291 }
292 
SetDebugAutomicTmpRootPath(SandboxContext * context,const AppSpawningCtx * property)293 static int SetDebugAutomicTmpRootPath(SandboxContext *context, const AppSpawningCtx *property)
294 {
295     context->bundleName = GetBundleName(property);
296     context->message = property->message;
297     AppSpawnMsgDacInfo *info = (AppSpawnMsgDacInfo *)GetSandboxCtxMsgInfo(context, TLV_DAC_INFO);
298     APPSPAWN_CHECK(info != NULL, return APPSPAWN_TLV_NONE,
299         "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, context->bundleName);
300 
301     char debugAutomicRootPath[PATH_MAX_LEN] = {0};
302     int ret = snprintf_s(debugAutomicRootPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "/mnt/debugtmp/%d/debug_hap/%s",
303                          info->uid / UID_BASE, context->bundleName);
304     APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL, "snprintf_s debugAutomicRootPath failed");
305     context->rootPath = strdup(debugAutomicRootPath);
306     if (context->rootPath == NULL) {
307         DeleteSandboxContext(&context);
308         return APPSPAWN_SYSTEM_ERROR;
309     }
310     APPSPAWN_LOGI("Set automic sandbox root: %{public}s", context->rootPath);
311     return 0;
312 }
313 
InitDebugSandboxContext(SandboxContext * context,const AppSpawnSandboxCfg * sandbox,const AppSpawningCtx * property,int nwebspawn)314 static int InitDebugSandboxContext(SandboxContext *context, const AppSpawnSandboxCfg *sandbox,
315                                    const AppSpawningCtx *property, int nwebspawn)
316 {
317     if (GetBundleName(property) == NULL) {
318         APPSPAWN_LOGI("No need init sandbox context");
319         return 0;
320     }
321     if (!CheckAppMsgFlagsSet(property, APP_FLAGS_ATOMIC_SERVICE)) {
322         return InitSandboxContext(context, sandbox, property, nwebspawn);
323     }
324 
325     return SetDebugAutomicTmpRootPath(context, property);
326 }
327 
MountDebugTmpConfig(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)328 static int MountDebugTmpConfig(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
329 {
330     int ret = SetDebugAppVarConfig(context, sandbox);
331     APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
332 
333     ret = SetDebugPermissionConfig(context, sandbox);
334     APPSPAWN_CHECK_ONLY_EXPER(ret == 0, return ret);
335     return ret;
336 }
337 
MountDebugDirBySharefs(const SandboxContext * context,const AppSpawnSandboxCfg * sandbox)338 static int MountDebugDirBySharefs(const SandboxContext *context, const AppSpawnSandboxCfg *sandbox)
339 {
340     if (context->rootPath == NULL) {
341         APPSPAWN_LOGE("sandbox root is null");
342         return APPSPAWN_SANDBOX_INVALID;
343     }
344 
345     const char *srcPath = context->rootPath;
346     char dstPath[PATH_MAX_LEN] = {0};
347     size_t mntTmpRootLen = strlen(DEBUG_MNT_TMP_ROOT);
348     int ret = snprintf_s(dstPath, PATH_MAX_LEN, PATH_MAX_LEN - 1, "%s%s",
349                          DEBUG_MNT_SHAREFS_ROOT, context->rootPath + mntTmpRootLen);
350     APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL, "Failed to snprintf_s dstPath");
351 
352     // If mount dstPath to MS_SHARED, the mount point already exists.
353     ret = mount(NULL, dstPath, NULL, MS_SHARED, NULL);
354     if (ret == 0) {
355         return 0;
356     }
357 
358     ret = MakeDirRec(dstPath, FILE_MODE, 1);
359     APPSPAWN_CHECK(ret == 0, return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL, "Failed to mkdir dstPath: %{public}s", dstPath);
360 
361     AppSpawnMsgDacInfo *info = (AppSpawnMsgDacInfo *)GetSandboxCtxMsgInfo(context, TLV_DAC_INFO);
362     APPSPAWN_CHECK(info != NULL, return APPSPAWN_TLV_NONE,
363                    "No tlv %{public}d in msg %{public}s", TLV_DAC_INFO, context->bundleName);
364 
365     char options[OPTIONS_MAX_LEN] = {0};
366     ret = snprintf_s(options, OPTIONS_MAX_LEN, OPTIONS_MAX_LEN - 1, "override_support_delete,user_id=%u",
367                      info->uid / UID_BASE);
368     APPSPAWN_CHECK(ret > 0, return APPSPAWN_ERROR_UTILS_MEM_FAIL, "Failed to snprintf_s options");
369 
370     const MountArgTemplate *tmp = GetMountArgTemplate(MOUNT_TMP_DAC_OVERRIDE_DELETE);
371     APPSPAWN_CHECK(tmp != NULL, return APPSPAWN_SANDBOX_INVALID, "Failed to get mount args");
372 
373     MountArg args = {
374         .originPath = srcPath,
375         .destinationPath = dstPath,
376         .fsType = tmp->fsType,
377         .options = options,
378         .mountFlags = tmp->mountFlags,
379         .mountSharedFlag = MS_SLAVE
380     };
381     ret = SandboxMountPath(&args);
382     APPSPAWN_CHECK(ret == 0, return APPSPAWN_SYSTEM_ERROR, "Failed to mount points");
383 
384     return 0;
385 }
386 
InstallDebugSandbox(AppSpawnMgr * content,AppSpawningCtx * property)387 APPSPAWN_STATIC int InstallDebugSandbox(AppSpawnMgr *content, AppSpawningCtx *property)
388 {
389     APPSPAWN_CHECK(property != NULL && content != NULL, return APPSPAWN_ARG_INVALID,
390                    "Invalid appspawn client or property");
391 
392     if (!IsDeveloperModeOn(property)) {
393         return 0;
394     }
395 
396     uint32_t size = 0;
397     char *provisionType = GetAppSpawnMsgExtInfo(property->message, MSG_EXT_NAME_PROVISION_TYPE, &size);
398     if (provisionType == NULL || size == 0 || strcmp(provisionType, "debug") != 0) {
399         return 0;
400     }
401 
402     APPSPAWN_LOGI("Install %{public}s debug sandbox", GetProcessName(property));
403     AppSpawnSandboxCfg *sandboxCfg = GetAppSpawnSandbox(content, EXT_DATA_DEBUG_HAP_SANDBOX);
404     APPSPAWN_CHECK(sandboxCfg != NULL, return APPSPAWN_SANDBOX_INVALID,
405                    "Failed to get sandbox for %{public}s", GetProcessName(property));
406 
407     SandboxContext *context = GetSandboxContext();   // Need free after mounting each time
408     APPSPAWN_CHECK_ONLY_EXPER(context != NULL, return APPSPAWN_SYSTEM_ERROR);
409     int ret = InitDebugSandboxContext(context, sandboxCfg, property, IsNWebSpawnMode(content));
410     APPSPAWN_CHECK_ONLY_EXPER(ret == 0, DeleteSandboxContext(&context);
411                                         return ret);
412 
413     APPSPAWN_LOGI("Set sandbox config %{public}s sandboxNsFlags 0x%{public}x",
414                   context->rootPath, context->sandboxNsFlags);
415     do {
416         ret = MountDebugTmpConfig(context, sandboxCfg);
417         APPSPAWN_CHECK_ONLY_EXPER(ret == 0, break);
418         /**
419          * /mnt/debugtmp/<currentUserId>/debug_hap/<variablePackageName>/ =>
420          * /mnt/debug/<currentUserId>/debug_hap/<variablePackageName>/
421          */
422         ret = MountDebugDirBySharefs(context, sandboxCfg);
423     } while (0);
424 
425     DeleteSandboxContext(&context);
426     return 0;
427 }
428 
429 #ifdef APPSPAWN_SANDBOX_NEW
MODULE_CONSTRUCTOR(void)430 MODULE_CONSTRUCTOR(void)
431 {
432     APPSPAWN_LOGV("Load debug hap module ...");
433     (void)AddAppSpawnHook(STAGE_PARENT_UNINSTALL, HOOK_PRIO_SANDBOX, UninstallDebugSandbox);
434     (void)AddAppSpawnHook(STAGE_PARENT_POST_RELY, HOOK_PRIO_SANDBOX, InstallDebugSandbox);
435 }
436 #endif