• 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_core.h"
17 
18 #include <dirent.h>
19 #include <fcntl.h>
20 #include <sys/stat.h>
21 #include <fstream>
22 #include <sstream>
23 #include <set>
24 #include "securec.h"
25 #include "appspawn_manager.h"
26 #include "appspawn_trace.h"
27 #include "appspawn_utils.h"
28 #include "sandbox_dec.h"
29 #include "sandbox_def.h"
30 #ifdef APPSPAWN_HISYSEVENT
31 #include "hisysevent_adapter.h"
32 #endif
33 
34 #ifdef WITH_DLP
35 #include "dlp_fuse_fd.h"
36 #endif
37 
38 namespace OHOS {
39 namespace AppSpawn {
40 
NeedNetworkIsolated(AppSpawningCtx * property)41 bool SandboxCore::NeedNetworkIsolated(AppSpawningCtx *property)
42 {
43     int developerMode = IsDeveloperModeOpen();
44     if (CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX) && !developerMode) {
45         return true;
46     }
47 
48     if (CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_NETWORK)) {
49         std::string extensionType = SandboxCommon::GetExtraInfoByType(property, MSG_EXT_NAME_EXTENSION_TYPE);
50         if (extensionType.length() == 0 || !developerMode) {
51             return true;
52         }
53     }
54 
55     return false;
56 }
57 
EnableSandboxNamespace(AppSpawningCtx * appProperty,uint32_t sandboxNsFlags)58 int SandboxCore::EnableSandboxNamespace(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags)
59 {
60 #ifdef APPSPAWN_HISYSEVENT
61     struct timespec startClock = {0};
62     clock_gettime(CLOCK_MONOTONIC, &startClock);
63 #endif
64     int rc = unshare(sandboxNsFlags);
65 #ifdef APPSPAWN_HISYSEVENT
66     struct timespec endClock = {0};
67     clock_gettime(CLOCK_MONOTONIC, &endClock);
68     uint64_t diff = DiffTime(&startClock, &endClock);
69     APPSPAWN_CHECK_ONLY_EXPER(diff < FUNC_REPORT_DURATION, ReportAbnormalDuration("unshare", diff));
70 #endif
71     APPSPAWN_CHECK(rc == 0, return rc, "unshare %{public}s failed, err %{public}d", GetBundleName(appProperty), errno);
72 
73     if ((sandboxNsFlags & CLONE_NEWNET) == CLONE_NEWNET) {
74         rc = EnableNewNetNamespace();
75         APPSPAWN_CHECK(rc == 0, return rc, "Set %{public}s new netnamespace failed", GetBundleName(appProperty));
76     }
77     return 0;
78 }
79 
GetAppMsgFlags(const AppSpawningCtx * property)80 uint32_t SandboxCore::GetAppMsgFlags(const AppSpawningCtx *property)
81 {
82     APPSPAWN_CHECK(property != nullptr && property->message != nullptr,
83         return 0, "Invalid property for name %{public}u", TLV_MSG_FLAGS);
84     AppSpawnMsgFlags *msgFlags = (AppSpawnMsgFlags *)GetAppSpawnMsgInfo(property->message, TLV_MSG_FLAGS);
85     APPSPAWN_CHECK(msgFlags != nullptr,
86         return 0, "No TLV_MSG_FLAGS in msg %{public}s", property->message->msgHeader.processName);
87     return msgFlags->flags[0];
88 }
89 
CheckMountFlag(const AppSpawningCtx * appProperty,const std::string bundleName,cJSON * appConfig)90 bool SandboxCore::CheckMountFlag(const AppSpawningCtx *appProperty, const std::string bundleName,
91                                  cJSON *appConfig)
92 {
93     const char *flagChr = GetStringFromJsonObj(appConfig, SandboxCommonDef::g_flags);
94     if (flagChr == nullptr) {
95         return false;
96     }
97     std::string flagStr(flagChr);
98     uint32_t flag = SandboxCommon::ConvertFlagStr(flagStr);
99     if ((CheckAppMsgFlagsSet(appProperty, flag) != 0) &&
100         bundleName.find("wps") != std::string::npos) {
101         return true;
102     }
103     return false;
104 }
105 
UpdateMsgFlagsWithPermission(AppSpawningCtx * appProperty,const std::string & permissionMode,uint32_t flag)106 void SandboxCore::UpdateMsgFlagsWithPermission(AppSpawningCtx *appProperty, const std::string &permissionMode,
107                                                uint32_t flag)
108 {
109     int32_t processIndex = GetPermissionIndex(nullptr, permissionMode.c_str());
110     if ((CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(processIndex)) == 0)) {
111         APPSPAWN_LOGV("Don't need set %{public}s flag", permissionMode.c_str());
112         return;
113     }
114 
115     int ret = SetAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, flag);
116     if (ret != 0) {
117         APPSPAWN_LOGV("Set %{public}s flag failed", permissionMode.c_str());
118     }
119 }
120 
UpdatePointFlags(AppSpawningCtx * appProperty)121 int32_t SandboxCore::UpdatePointFlags(AppSpawningCtx *appProperty)
122 {
123     uint32_t index = 0;
124 #ifdef APPSPAWN_SUPPORT_NOSHAREFS
125     index = APP_FLAGS_FILE_CROSS_APP;
126 #else
127     index = APP_FLAGS_FILE_ACCESS_COMMON_DIR;
128 #endif
129     int32_t fileMgrIndex = GetPermissionIndex(nullptr, SandboxCommonDef::FILE_ACCESS_MANAGER_MODE.c_str());
130     if ((CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(fileMgrIndex)) == 0)) {
131         return SetAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, index);
132     }
133     return 0;
134 }
135 
GetSandboxPath(const AppSpawningCtx * appProperty,cJSON * mntPoint,const std::string & section,std::string sandboxRoot)136 std::string SandboxCore::GetSandboxPath(const AppSpawningCtx *appProperty, cJSON *mntPoint,
137     const std::string &section, std::string sandboxRoot)
138 {
139     std::string sandboxPath = "";
140     const char *tmpSandboxPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_sandBoxPath);
141     if (tmpSandboxPathChr == nullptr) {
142         return "";
143     }
144     std::string tmpSandboxPath(tmpSandboxPathChr);
145     if (section.compare(SandboxCommonDef::g_permissionPrefix) == 0) {
146         sandboxPath = sandboxRoot + SandboxCommon::ConvertToRealPathWithPermission(appProperty, tmpSandboxPath);
147     } else {
148         sandboxPath = sandboxRoot + SandboxCommon::ConvertToRealPath(appProperty, tmpSandboxPath);
149     }
150     return sandboxPath;
151 }
152 
DoDlpAppMountStrategy(const AppSpawningCtx * appProperty,const std::string & srcPath,const std::string & sandboxPath,const std::string & fsType,unsigned long mountFlags)153 int32_t SandboxCore::DoDlpAppMountStrategy(const AppSpawningCtx *appProperty, const std::string &srcPath,
154         const std::string &sandboxPath, const std::string &fsType, unsigned long mountFlags)
155 {
156     AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
157     if (dacInfo == nullptr) {
158         return -1;
159     }
160 
161     // umount fuse path, make sure that sandbox path is not a mount point
162     umount2(sandboxPath.c_str(), MNT_DETACH);
163 
164     int fd = open("/dev/fuse", O_RDWR);
165     APPSPAWN_CHECK(fd != -1, return -EINVAL, "open /dev/fuse failed, errno is %{public}d", errno);
166 
167     char options[SandboxCommonDef::OPTIONS_MAX_LEN];
168     (void)sprintf_s(options, sizeof(options), "fd=%d,"
169         "rootmode=40000,user_id=%u,group_id=%u,allow_other,"
170         "context=\"u:object_r:dlp_fuse_file:s0\","
171         "fscontext=u:object_r:dlp_fuse_file:s0",
172         fd, dacInfo->uid, dacInfo->gid);
173 
174     // To make sure destinationPath exist
175     (void)SandboxCommon::CreateDirRecursive(sandboxPath, SandboxCommonDef::FILE_MODE);
176 
177 #ifndef APPSPAWN_TEST
178     APPSPAWN_LOGV("Bind mount %{public}s to %{public}s '%{public}s' '%{public}lu' '%{public}s'",
179         srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options);
180     int ret = mount(srcPath.c_str(), sandboxPath.c_str(), fsType.c_str(), mountFlags, options);
181     APPSPAWN_CHECK(ret == 0, close(fd);
182         return ret, "DoDlpAppMountStrategy failed, bind mount %{public}s to %{public}s failed %{public}d",
183         srcPath.c_str(), sandboxPath.c_str(), errno);
184 
185     ret = mount(nullptr, sandboxPath.c_str(), nullptr, MS_SHARED, nullptr);
186     APPSPAWN_CHECK(ret == 0, close(fd);
187         return ret, "errno is: %{public}d, private mount to %{public}s failed", errno, sandboxPath.c_str());
188 #endif
189     /* set DLP_FUSE_FD  */
190 #ifdef WITH_DLP
191     SetDlpFuseFd(fd);
192 #endif
193     return fd;
194 }
195 
HandleSpecialAppMount(const AppSpawningCtx * appProperty,const std::string & srcPath,const std::string & sandboxPath,const std::string & fsType,unsigned long mountFlags)196 int32_t SandboxCore::HandleSpecialAppMount(const AppSpawningCtx *appProperty, const std::string &srcPath,
197         const std::string &sandboxPath, const std::string &fsType, unsigned long mountFlags)
198 {
199     std::string bundleName = GetBundleName(appProperty);
200     std::string processName = GetProcessName(appProperty);
201     /* dlp application mount strategy */
202     /* dlp is an example, we should change to real bundle name later */
203     if (bundleName.find(SandboxCommonDef::g_dlpBundleName) != std::string::npos &&
204         processName.compare(SandboxCommonDef::g_dlpBundleName) == 0) {
205         if (!fsType.empty()) {
206             return DoDlpAppMountStrategy(appProperty, srcPath, sandboxPath, fsType, mountFlags);
207         }
208     }
209     return -1;
210 }
211 
GetPrivateJsonInfo(const AppSpawningCtx * appProperty,cJSON * wholeConfig)212 cJSON *SandboxCore::GetPrivateJsonInfo(const AppSpawningCtx *appProperty, cJSON *wholeConfig)
213 {
214     cJSON *firstPrivate = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_privatePrefix);
215     if (!firstPrivate) {
216         return nullptr;
217     }
218 
219     const char *bundleName = GetBundleName(appProperty);
220     return GetFirstSubConfig(firstPrivate, bundleName);
221 }
222 
DoSandboxFilePrivateBind(const AppSpawningCtx * appProperty,cJSON * wholeConfig)223 int32_t SandboxCore::DoSandboxFilePrivateBind(const AppSpawningCtx *appProperty, cJSON *wholeConfig)
224 {
225     cJSON *bundleNameInfo = GetPrivateJsonInfo(appProperty, wholeConfig);
226     if (bundleNameInfo == nullptr) {
227         return 0;
228     }
229     (void)DoAddGid((AppSpawningCtx *)appProperty, bundleNameInfo, "", SandboxCommonDef::g_privatePrefix);
230     return DoAllMntPointsMount(appProperty, bundleNameInfo, nullptr, SandboxCommonDef::g_privatePrefix);
231 }
232 
DoSandboxFilePrivateSymlink(const AppSpawningCtx * appProperty,cJSON * wholeConfig)233 int32_t SandboxCore::DoSandboxFilePrivateSymlink(const AppSpawningCtx *appProperty, cJSON *wholeConfig)
234 {
235     cJSON *bundleNameInfo = GetPrivateJsonInfo(appProperty, wholeConfig);
236     if (bundleNameInfo == nullptr) {
237         return 0;
238     }
239     return DoAllSymlinkPointslink(appProperty, bundleNameInfo);
240 }
241 
DoSandboxFilePrivateFlagsPointHandle(const AppSpawningCtx * appProperty,cJSON * wholeConfig)242 int32_t SandboxCore::DoSandboxFilePrivateFlagsPointHandle(const AppSpawningCtx *appProperty, cJSON *wholeConfig)
243 {
244     cJSON *bundleNameInfo = GetPrivateJsonInfo(appProperty, wholeConfig);
245     if (bundleNameInfo == nullptr) {
246         return 0;
247     }
248     return HandleFlagsPoint(appProperty, bundleNameInfo);
249 }
250 
SetPrivateAppSandboxProperty_(const AppSpawningCtx * appProperty,cJSON * config)251 int32_t SandboxCore::SetPrivateAppSandboxProperty_(const AppSpawningCtx *appProperty, cJSON *config)
252 {
253     int ret = DoSandboxFilePrivateBind(appProperty, config);
254     APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePrivateBind failed");
255 
256     ret = DoSandboxFilePrivateSymlink(appProperty, config);
257     APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateSymlink failed");
258 
259     ret = DoSandboxFilePrivateFlagsPointHandle(appProperty, config);
260     APPSPAWN_CHECK_ONLY_LOG(ret == 0, "DoSandboxFilePrivateFlagsPointHandle failed");
261 
262     return ret;
263 }
264 
DoSandboxFilePermissionBind(AppSpawningCtx * appProperty,cJSON * wholeConfig)265 int32_t SandboxCore::DoSandboxFilePermissionBind(AppSpawningCtx *appProperty, cJSON *wholeConfig)
266 {
267     cJSON *permission = cJSON_GetObjectItemCaseSensitive(wholeConfig, SandboxCommonDef::g_permissionPrefix);
268     if (!permission || !cJSON_IsArray(permission)) {
269         return 0;
270     }
271 
272     auto processor = [&appProperty](cJSON *item) {
273         cJSON *permissionChild = item->child;
274         while (permissionChild != nullptr) {
275             int index = GetPermissionIndex(nullptr, permissionChild->string);
276             if (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(index)) == 0) {
277                 permissionChild = permissionChild->next;
278                 continue;
279             }
280             cJSON *permissionMountPaths = cJSON_GetArrayItem(permissionChild, 0);
281             if (!permissionMountPaths) {
282                 permissionChild = permissionChild->next;
283                 continue;
284             }
285             APPSPAWN_LOGV("DoSandboxFilePermissionBind %{public}s index %{public}d", permissionChild->string, index);
286             DoAddGid(appProperty, permissionMountPaths, permissionChild->string, SandboxCommonDef::g_permissionPrefix);
287             DoAllMntPointsMount(appProperty, permissionMountPaths, permissionChild->string,
288                                 SandboxCommonDef::g_permissionPrefix);
289 
290             permissionChild = permissionChild->next;
291         }
292         return 0;
293     };
294 
295     return SandboxCommon::HandleArrayForeach(permission, processor);
296 }
297 
SetPermissionAppSandboxProperty_(AppSpawningCtx * appProperty,cJSON * config)298 int32_t SandboxCore::SetPermissionAppSandboxProperty_(AppSpawningCtx *appProperty, cJSON *config)
299 {
300     int ret = DoSandboxFilePermissionBind(appProperty, config);
301     APPSPAWN_CHECK(ret == 0, return ret, "DoSandboxFilePermissionBind failed");
302     return ret;
303 }
304 
GetFirstCommonConfig(cJSON * wholeConfig,const char * prefix)305 cJSON *SandboxCore::GetFirstCommonConfig(cJSON *wholeConfig, const char *prefix)
306 {
307     cJSON *commonConfig = cJSON_GetObjectItemCaseSensitive(wholeConfig, prefix);
308     if (!commonConfig || !cJSON_IsArray(commonConfig)) {
309         return nullptr;
310     }
311 
312     return cJSON_GetArrayItem(commonConfig, 0);
313 }
314 
GetFirstSubConfig(cJSON * parent,const char * key)315 cJSON *SandboxCore::GetFirstSubConfig(cJSON *parent, const char *key)
316 {
317     cJSON *config = cJSON_GetObjectItemCaseSensitive(parent, key);
318     if (!config || !cJSON_IsArray(config)) {
319         return nullptr;
320     }
321 
322     return cJSON_GetArrayItem(config, 0);
323 }
324 
DoSandboxFileCommonBind(const AppSpawningCtx * appProperty,cJSON * wholeConfig)325 int32_t SandboxCore::DoSandboxFileCommonBind(const AppSpawningCtx *appProperty, cJSON *wholeConfig)
326 {
327     cJSON *firstCommon = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_commonPrefix);
328     if (!firstCommon) {
329         return 0;
330     }
331 
332     cJSON *appBaseConfig = GetFirstSubConfig(firstCommon, SandboxCommonDef::g_appBase);
333     if (!appBaseConfig) {
334         return 0;
335     }
336 
337     int ret = DoAllMntPointsMount(appProperty, appBaseConfig, nullptr, SandboxCommonDef::g_appBase);
338     if (ret) {
339         return ret;
340     }
341 
342     cJSON *appResourcesConfig = GetFirstSubConfig(firstCommon, SandboxCommonDef::g_appResources);
343     if (!appResourcesConfig) {
344         return 0;
345     }
346     ret = DoAllMntPointsMount(appProperty, appResourcesConfig, nullptr, SandboxCommonDef::g_appResources);
347     return ret;
348 }
349 
DoSandboxFileCommonSymlink(const AppSpawningCtx * appProperty,cJSON * wholeConfig)350 int32_t SandboxCore::DoSandboxFileCommonSymlink(const AppSpawningCtx *appProperty, cJSON *wholeConfig)
351 {
352     cJSON *firstCommon = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_commonPrefix);
353     if (!firstCommon) {
354         return 0;
355     }
356 
357     cJSON *appBaseConfig = GetFirstSubConfig(firstCommon, SandboxCommonDef::g_appBase);
358     if (!appBaseConfig) {
359         return 0;
360     }
361 
362     int ret = DoAllSymlinkPointslink(appProperty, appBaseConfig);
363     if (ret) {
364         return ret;
365     }
366 
367     cJSON *appResourcesConfig = GetFirstSubConfig(firstCommon, SandboxCommonDef::g_appResources);
368     if (!appResourcesConfig) {
369         return 0;
370     }
371     ret = DoAllSymlinkPointslink(appProperty, appResourcesConfig);
372     return ret;
373 }
374 
DoSandboxFileCommonFlagsPointHandle(const AppSpawningCtx * appProperty,cJSON * wholeConfig)375 int32_t SandboxCore::DoSandboxFileCommonFlagsPointHandle(const AppSpawningCtx *appProperty, cJSON *wholeConfig)
376 {
377     cJSON *firstCommon = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_commonPrefix);
378     if (!firstCommon) {
379         return 0;
380     }
381 
382     cJSON *appResourcesConfig = GetFirstSubConfig(firstCommon, SandboxCommonDef::g_appResources);
383     if (!appResourcesConfig) {
384         return 0;
385     }
386     return HandleFlagsPoint(appProperty, appResourcesConfig);
387 }
388 
SetCommonAppSandboxProperty_(const AppSpawningCtx * appProperty,cJSON * config)389 int32_t SandboxCore::SetCommonAppSandboxProperty_(const AppSpawningCtx *appProperty, cJSON *config)
390 {
391     int rc = 0;
392     rc = DoSandboxFileCommonBind(appProperty, config);
393     APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonBind failed, %{public}s", GetBundleName(appProperty));
394 
395     // if sandbox switch is off, don't do symlink work again
396     if (SandboxCommon::IsAppSandboxEnabled(appProperty) == true &&
397         (SandboxCommon::IsTotalSandboxEnabled(appProperty) == true)) {
398         rc = DoSandboxFileCommonSymlink(appProperty, config);
399         APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxFileCommonSymlink failed, %{public}s", GetBundleName(appProperty));
400     }
401 
402     rc = DoSandboxFileCommonFlagsPointHandle(appProperty, config);
403     APPSPAWN_CHECK_ONLY_LOG(rc == 0, "DoSandboxFilePrivateFlagsPointHandle failed");
404 
405     return rc;
406 }
407 
CheckPath(const std::string & name)408 static inline bool CheckPath(const std::string& name)
409 {
410     return !name.empty() && name != "." && name != ".." && name.find("/") == std::string::npos;
411 }
412 
GetJsonObjFromProperty(const AppSpawningCtx * appProperty,const char * name)413 static inline cJSON *GetJsonObjFromProperty(const AppSpawningCtx *appProperty, const char *name)
414 {
415     uint32_t size = 0;
416     const char *extInfo = (char *)(GetAppSpawnMsgExtInfo(appProperty->message, name, &size));
417     if (size == 0 || extInfo == nullptr) {
418         return nullptr;
419     }
420     APPSPAWN_LOGV("Get json name %{public}s value %{public}s", name, extInfo);
421     cJSON *root = cJSON_Parse(extInfo);
422     APPSPAWN_CHECK(root != nullptr, return nullptr, "Invalid ext info %{public}s for %{public}s", extInfo, name);
423     return root;
424 }
425 
MountAllHsp(const AppSpawningCtx * appProperty,std::string & sandboxPackagePath,cJSON * hspRoot)426 int32_t SandboxCore::MountAllHsp(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath, cJSON *hspRoot)
427 {
428     if (appProperty == nullptr || sandboxPackagePath == "") {
429         return 0;
430     }
431     int ret = 0;
432     APPSPAWN_CHECK_ONLY_EXPER(hspRoot != nullptr && cJSON_IsObject(hspRoot), return 0);
433 
434     cJSON *bundles = cJSON_GetObjectItemCaseSensitive(hspRoot, "bundles");
435     cJSON *modules = cJSON_GetObjectItemCaseSensitive(hspRoot, "modules");
436     cJSON *versions = cJSON_GetObjectItemCaseSensitive(hspRoot, "versions");
437     APPSPAWN_CHECK(bundles != nullptr && cJSON_IsArray(bundles), return -1, "MountAllHsp: invalid bundles");
438     APPSPAWN_CHECK(modules != nullptr && cJSON_IsArray(modules), return -1, "MountAllHsp: invalid modules");
439     APPSPAWN_CHECK(versions != nullptr && cJSON_IsArray(versions), return -1, "MountAllHsp: invalid versions");
440     int count = cJSON_GetArraySize(bundles);
441     APPSPAWN_CHECK(count == cJSON_GetArraySize(modules), return -1, "MountAllHsp: sizes are not same");
442     APPSPAWN_CHECK(count == cJSON_GetArraySize(versions), return -1, "MountAllHsp: sizes are not same");
443 
444     APPSPAWN_LOGI("MountAllHsp app: %{public}s, count: %{public}d", GetBundleName(appProperty), count);
445     for (int i = 0; i < count; i++) {
446         if (!(cJSON_IsString(cJSON_GetArrayItem(bundles, i)) && cJSON_IsString(cJSON_GetArrayItem(modules, i)) &&
447             cJSON_IsString(cJSON_GetArrayItem(versions, i)))) {
448             return -1;
449         }
450         const char *libBundleName = cJSON_GetStringValue(cJSON_GetArrayItem(bundles, i));
451         const char *libModuleName = cJSON_GetStringValue(cJSON_GetArrayItem(modules, i));
452         const char *libVersion = cJSON_GetStringValue(cJSON_GetArrayItem(versions, i));
453         APPSPAWN_CHECK(libBundleName != nullptr && libModuleName != nullptr && libVersion != nullptr,
454             return -1, "MountAllHsp: config error");
455         APPSPAWN_CHECK(CheckPath(libBundleName) && CheckPath(libModuleName) && CheckPath(libVersion),
456             return -1, "MountAllHsp: path error");
457 
458         std::string libPhysicalPath = SandboxCommonDef::g_physicalAppInstallPath + libBundleName + "/" +
459                                       libVersion + "/" + libModuleName;
460         std::string mntPath =
461             sandboxPackagePath + SandboxCommonDef::g_sandboxHspInstallPath + libBundleName + "/" + libModuleName;
462         SharedMountArgs arg = {
463             .srcPath = libPhysicalPath.c_str(),
464             .destPath = mntPath.c_str()
465         };
466         ret = SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg);
467         APPSPAWN_CHECK(ret == 0, return 0, "mount library failed %{public}d", ret);
468     }
469     return 0;
470 }
471 
MountAllGroup(const AppSpawningCtx * appProperty,std::string & sandboxPackagePath)472 int32_t SandboxCore::MountAllGroup(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath)
473 {
474     if (appProperty == nullptr || sandboxPackagePath == "") {
475         return 0;
476     }
477     cJSON *dataGroupRoot = GetJsonObjFromProperty(appProperty, SandboxCommonDef::DATA_GROUP_SOCKET_TYPE.c_str());
478     APPSPAWN_CHECK_ONLY_EXPER(dataGroupRoot != nullptr, return 0);
479 
480     mode_t mountSharedFlag = MS_SLAVE;
481     if (CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX)) {
482         mountSharedFlag |= MS_REMOUNT | MS_NODEV | MS_RDONLY | MS_BIND;
483     }
484 
485     auto processor = [&appProperty, &sandboxPackagePath, &mountSharedFlag](cJSON *item) {
486         APPSPAWN_CHECK(IsValidDataGroupItem(item), return -1, "MountAllGroup: data group item error");
487         const char *srcPathChr = GetStringFromJsonObj(item, SandboxCommonDef::g_groupList_key_dir.c_str());
488         if (srcPathChr == nullptr) {
489             return 0;
490         }
491         std::string srcPath(srcPathChr);
492         APPSPAWN_CHECK(!CheckPath(srcPath), return -1, "MountAllGroup: path error");
493         const char *uuidChr = GetStringFromJsonObj(item, SandboxCommonDef::g_groupList_key_uuid.c_str());
494         if (uuidChr == nullptr) {
495             return 0;
496         }
497         std::string uuidStr(uuidChr);
498 
499         int elxValue = GetElxInfoFromDir(srcPath.c_str());
500         APPSPAWN_CHECK((elxValue >= EL2 && elxValue < ELX_MAX), return -1, "Get elx value failed");
501 
502         const DataGroupSandboxPathTemplate *templateItem = GetDataGroupArgTemplate(elxValue);
503         APPSPAWN_CHECK(templateItem != nullptr, return -1, "Get data group arg template failed");
504 
505         // If permission isn't null, need check permission flag
506         if (templateItem->permission != nullptr) {
507             int index = GetPermissionIndex(nullptr, templateItem->permission);
508             APPSPAWN_LOGV("mount dir no lock mount permission flag %{public}d", index);
509             if (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(index)) == 0) {
510                 return 0;
511             }
512         }
513 
514         std::string mntPath = sandboxPackagePath + templateItem->sandboxPath + uuidStr;
515         SharedMountArgs arg = {
516             .srcPath = srcPath.c_str(),
517             .destPath = mntPath.c_str(),
518             .mountSharedFlag = mountSharedFlag
519         };
520         int result = SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg);
521         if (result != 0) {
522             APPSPAWN_LOGE("mount el%{public}d datagroup failed", elxValue);
523         }
524         return 0;
525     };
526     int ret = SandboxCommon::HandleArrayForeach(dataGroupRoot, processor);
527     cJSON_Delete(dataGroupRoot);
528     return ret;
529 }
530 
ProcessMountPoint(cJSON * mntPoint,MountPointProcessParams & params)531 int32_t SandboxCore::ProcessMountPoint(cJSON *mntPoint, MountPointProcessParams &params)
532 {
533     APPSPAWN_CHECK_ONLY_EXPER(SandboxCommon::IsValidMountConfig(mntPoint, params.appProperty, params.checkFlag),
534                               return 0);
535     const char *srcPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_srcPath);
536     const char *sandboxPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_sandBoxPath);
537     if (srcPathChr == nullptr || sandboxPathChr == nullptr) {
538         return 0;
539     }
540     std::string srcPath(srcPathChr);
541     std::string sandboxPath(sandboxPathChr);
542     srcPath = SandboxCommon::ConvertToRealPath(params.appProperty, srcPath);
543     APPSPAWN_CHECK_ONLY_EXPER(SandboxCommon::IsCreateSandboxPathEnabled(mntPoint, srcPath), return 0);
544     sandboxPath = GetSandboxPath(params.appProperty, mntPoint, params.section, params.sandboxRoot);
545     SandboxMountConfig mountConfig = {0};
546     SandboxCommon::GetSandboxMountConfig(params.appProperty, params.section, mntPoint, mountConfig);
547     SharedMountArgs arg = {
548         .srcPath = srcPath.c_str(),
549         .destPath = sandboxPath.c_str(),
550         .fsType = mountConfig.fsType.c_str(),
551         .mountFlags = SandboxCommon::GetMountFlags(mntPoint),
552         .options = mountConfig.optionsPoint.c_str(),
553         .mountSharedFlag =
554             GetBoolValueFromJsonObj(mntPoint, SandboxCommonDef::g_mountSharedFlag, false) ? MS_SHARED : MS_SLAVE
555     };
556 
557     /* if app mount failed for special strategy, we need deal with common mount config */
558     int ret = HandleSpecialAppMount(params.appProperty, arg.srcPath, arg.destPath, arg.fsType, arg.mountFlags);
559     if (ret < 0) {
560         ret = SandboxCommon::DoAppSandboxMountOnce(params.appProperty, &arg);
561     }
562     APPSPAWN_CHECK(ret == 0 || !SandboxCommon::IsMountSuccessful(mntPoint),
563 #ifdef APPSPAWN_HISYSEVENT
564         ReportMountFail(params.bundleName.c_str(), arg.srcPath, arg.destPath, errno);
565         ret = APPSPAWN_SANDBOX_MOUNT_FAIL;
566 #endif
567         return ret,
568         "DoAppSandboxMountOnce section %{public}s failed, %{public}s", params.section.c_str(), arg.destPath);
569     SetDecPolicyWithPermission(params.appProperty, mountConfig);
570     SandboxCommon::SetSandboxPathChmod(mntPoint, params.sandboxRoot);
571     return 0;
572 }
573 
DoAllMntPointsMount(const AppSpawningCtx * appProperty,cJSON * appConfig,const char * typeName,const std::string & section)574 int32_t SandboxCore::DoAllMntPointsMount(const AppSpawningCtx *appProperty, cJSON *appConfig,
575                                          const char *typeName, const std::string &section)
576 {
577     std::string bundleName = GetBundleName(appProperty);
578     cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(appConfig, SandboxCommonDef::g_mountPrefix);
579     if (mountPoints == nullptr || !cJSON_IsArray(mountPoints)) {
580         APPSPAWN_LOGI("mount config is not found in %{public}s, app name is %{public}s",
581             section.c_str(), bundleName.c_str());
582         return 0;
583     }
584 
585     std::string sandboxRoot = SandboxCommon::GetSandboxRootPath(appProperty, appConfig);
586     bool checkFlag = CheckMountFlag(appProperty, bundleName, appConfig);
587     MountPointProcessParams mountPointParams = {
588         .appProperty = appProperty,
589         .checkFlag = checkFlag,
590         .section = section,
591         .sandboxRoot = sandboxRoot,
592         .bundleName = bundleName
593     };
594 
595     auto processor = [&mountPointParams](cJSON *mntPoint) {
596         return ProcessMountPoint(mntPoint, mountPointParams);
597     };
598 
599     return SandboxCommon::HandleArrayForeach(mountPoints, processor);
600 }
601 
DoAddGid(AppSpawningCtx * appProperty,cJSON * appConfig,const char * permissionName,const std::string & section)602 int32_t SandboxCore::DoAddGid(AppSpawningCtx *appProperty, cJSON *appConfig,
603                               const char *permissionName, const std::string &section)
604 {
605     AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
606     if (dacInfo == nullptr) {
607         return 0;
608     }
609 
610     cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(appConfig, SandboxCommonDef::g_gidPrefix);
611     if (mountPoints == nullptr || !cJSON_IsArray(mountPoints)) {
612         return 0;
613     }
614 
615     std::string bundleName = GetBundleName(appProperty);
616     auto processor = [&dacInfo](cJSON *item) {
617         gid_t gid = 0;
618         if (cJSON_IsNumber(item)) {
619             gid = (gid_t)cJSON_GetNumberValue(item);
620         }
621         if (gid <= 0) {
622             return 0;
623         }
624         if (dacInfo->gidCount < APP_MAX_GIDS) {
625             dacInfo->gidTable[dacInfo->gidCount++] = gid;
626         }
627         return 0;
628     };
629 
630     return SandboxCommon::HandleArrayForeach(mountPoints, processor);
631 }
632 
DoAllSymlinkPointslink(const AppSpawningCtx * appProperty,cJSON * appConfig)633 int32_t SandboxCore::DoAllSymlinkPointslink(const AppSpawningCtx *appProperty, cJSON *appConfig)
634 {
635     cJSON *symlinkPoints = cJSON_GetObjectItemCaseSensitive(appConfig, SandboxCommonDef::g_symlinkPrefix);
636     if (symlinkPoints == nullptr || !cJSON_IsArray(symlinkPoints)) {
637         APPSPAWN_LOGV("symlink config is not found");
638         return 0;
639     }
640 
641     std::string sandboxRoot = SandboxCommon::GetSandboxRootPath(appProperty, appConfig);
642     auto processor = [&appProperty, &sandboxRoot](cJSON *item) {
643         const char *targetNameChr = GetStringFromJsonObj(item, SandboxCommonDef::g_targetName);
644         const char *linkNameChr = GetStringFromJsonObj(item, SandboxCommonDef::g_linkName);
645         if (targetNameChr == nullptr || linkNameChr == nullptr) {
646             return 0;
647         }
648         std::string targetName(targetNameChr);
649         std::string linkName(linkNameChr);
650         targetName = SandboxCommon::ConvertToRealPath(appProperty, targetName);
651         linkName = sandboxRoot + SandboxCommon::ConvertToRealPath(appProperty, linkName);
652         int ret = symlink(targetName.c_str(), linkName.c_str());
653         if (ret && errno != EEXIST && SandboxCommon::IsMountSuccessful(item)) {
654             APPSPAWN_LOGE("errno is %{public}d, symlink failed, %{public}s", errno, linkName.c_str());
655             return -1;
656         }
657         SandboxCommon::SetSandboxPathChmod(item, sandboxRoot);
658         return 0;
659     };
660 
661     return SandboxCommon::HandleArrayForeach(symlinkPoints, processor);
662 }
663 
DoSandboxRootFolderCreateAdapt(std::string & sandboxPackagePath)664 int32_t SandboxCore::DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath)
665 {
666 #ifndef APPSPAWN_TEST
667     int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr);
668     APPSPAWN_CHECK(rc == 0, return rc, "set propagation slave failed");
669 #endif
670     (void)SandboxCommon::CreateDirRecursive(sandboxPackagePath, SandboxCommonDef::FILE_MODE);
671 
672     // bind mount "/" to /mnt/sandbox/<currentUserId>/<packageName> path
673     // rootfs: to do more resources bind mount here to get more strict resources constraints
674 #ifndef APPSPAWN_TEST
675     rc = mount("/", sandboxPackagePath.c_str(), nullptr, SandboxCommonDef::BASIC_MOUNT_FLAGS, nullptr);
676     APPSPAWN_CHECK(rc == 0, return rc, "mount bind / failed, %{public}d", errno);
677 #endif
678     return 0;
679 }
680 
DoSandboxRootFolderCreate(const AppSpawningCtx * appProperty,std::string & sandboxPackagePath)681 int32_t SandboxCore::DoSandboxRootFolderCreate(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath)
682 {
683 #ifndef APPSPAWN_TEST
684     int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr);
685     if (rc) {
686         return rc;
687     }
688 #endif
689     SharedMountArgs arg = {
690         .srcPath = sandboxPackagePath.c_str(),
691         .destPath = sandboxPackagePath.c_str()
692     };
693     SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg);
694 
695     return 0;
696 }
697 
GetSpecialMountCondition(bool & isPreInstalled,bool & isHaveSandBoxPermission,const AppSpawningCtx * appProperty)698 void SandboxCore::GetSpecialMountCondition(bool &isPreInstalled, bool &isHaveSandBoxPermission,
699                                            const AppSpawningCtx *appProperty)
700 {
701     const std::string preInstallFlag = "PREINSTALLED_HAP";
702     const std::string customSandBoxFlag = "CUSTOM_SANDBOX_HAP";
703     isPreInstalled = CheckAppMsgFlagsSet(appProperty, SandboxCommon::ConvertFlagStr(preInstallFlag)) != 0;
704     isHaveSandBoxPermission = CheckAppMsgFlagsSet(appProperty, SandboxCommon::ConvertFlagStr(customSandBoxFlag)) != 0;
705 }
706 
MountNonShellPreInstallHap(const AppSpawningCtx * appProperty,cJSON * item)707 int32_t SandboxCore::MountNonShellPreInstallHap(const AppSpawningCtx *appProperty, cJSON *item)
708 {
709     bool isPreInstalled = false;
710     bool isHaveSandBoxPermission = false;
711     GetSpecialMountCondition(isPreInstalled, isHaveSandBoxPermission, appProperty);
712     bool preInstallMount = (isPreInstalled && !isHaveSandBoxPermission);
713     if (preInstallMount) {
714         return DoAllMntPointsMount(appProperty, item, nullptr, SandboxCommonDef::g_flagePoint);
715     }
716     return 0;
717 }
718 
MountShellPreInstallHap(const AppSpawningCtx * appProperty,cJSON * item)719 int32_t SandboxCore::MountShellPreInstallHap(const AppSpawningCtx *appProperty, cJSON *item)
720 {
721     bool isPreInstalled = false;
722     bool isHaveSandBoxPermission = false;
723     GetSpecialMountCondition(isPreInstalled, isHaveSandBoxPermission, appProperty);
724     bool preInstallShellMount = (isPreInstalled && isHaveSandBoxPermission);
725     if (preInstallShellMount) {
726         return DoAllMntPointsMount(appProperty, item, nullptr, SandboxCommonDef::g_flagePoint);
727     }
728     return 0;
729 }
730 
HandleFlagsPoint(const AppSpawningCtx * appProperty,cJSON * appConfig)731 int32_t SandboxCore::HandleFlagsPoint(const AppSpawningCtx *appProperty, cJSON *appConfig)
732 {
733     cJSON *flagsPoints = cJSON_GetObjectItemCaseSensitive(appConfig, SandboxCommonDef::g_flagePoint);
734     if (flagsPoints == nullptr || !cJSON_IsArray(flagsPoints)) {
735         APPSPAWN_LOGV("flag points config is not found");
736         return 0;
737     }
738 
739     auto processor = [&appProperty](cJSON *item) {
740         const char *flagsChr = GetStringFromJsonObj(item, SandboxCommonDef::g_flags);
741         if (flagsChr == nullptr) {
742             return 0;
743         }
744         std::string flagsStr(flagsChr);
745 
746         const std::string preInstallFlag = "PREINSTALLED_HAP";
747         const std::string preInstallShellFlag = "PREINSTALLED_SHELL_HAP";
748 
749         if (flagsStr == preInstallFlag) {
750             return MountNonShellPreInstallHap(appProperty, item);
751         }
752 
753         if (flagsStr == preInstallShellFlag) {
754             return MountShellPreInstallHap(appProperty, item);
755         }
756 
757         uint32_t flag = SandboxCommon::ConvertFlagStr(flagsStr);
758         if (CheckAppMsgFlagsSet(appProperty, flag) == 0) {
759             return 0;
760         }
761         return DoAllMntPointsMount(appProperty, item, nullptr, SandboxCommonDef::g_flagePoint);
762     };
763     return SandboxCommon::HandleArrayForeach(flagsPoints, processor);
764 }
765 
SetOverlayAppSandboxProperty(const AppSpawningCtx * appProperty,std::string & sandboxPackagePath)766 int32_t SandboxCore::SetOverlayAppSandboxProperty(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath)
767 {
768     int ret = 0;
769     if (!CheckAppMsgFlagsSet(appProperty, APP_FLAGS_OVERLAY)) {
770         return ret;
771     }
772 
773     std::string overlayInfo = SandboxCommon::GetExtraInfoByType(appProperty, SandboxCommonDef::OVERLAY_SOCKET_TYPE);
774     std::set<std::string> mountedSrcSet;
775     std::vector<std::string> splits = SandboxCommon::SplitString(overlayInfo, SandboxCommonDef::g_overlayDecollator);
776     std::string sandboxOverlayPath = sandboxPackagePath + SandboxCommonDef::g_overlayPath;
777     for (auto hapPath : splits) {
778         size_t pathIndex = hapPath.find_last_of(SandboxCommonDef::g_fileSeparator);
779         if (pathIndex == std::string::npos) {
780             continue;
781         }
782         std::string srcPath = hapPath.substr(0, pathIndex);
783         if (mountedSrcSet.find(srcPath) != mountedSrcSet.end()) {
784             APPSPAWN_LOGV("%{public}s have mounted before, no need to mount twice.", srcPath.c_str());
785             continue;
786         }
787 
788         auto bundleNameIndex = srcPath.find_last_of(SandboxCommonDef::g_fileSeparator);
789         std::string destPath = sandboxOverlayPath + srcPath.substr(bundleNameIndex + 1, srcPath.length());
790         SharedMountArgs arg = {
791             .srcPath = srcPath.c_str(),
792             .destPath = destPath.c_str()
793         };
794         int32_t retMount = SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg);
795         if (retMount != 0) {
796             APPSPAWN_LOGE("fail to mount overlay path, src is %{public}s.", hapPath.c_str());
797             ret = retMount;
798         }
799 
800         mountedSrcSet.emplace(srcPath);
801     }
802     return ret;
803 }
804 
SetBundleResourceAppSandboxProperty(const AppSpawningCtx * appProperty,std::string & sandboxPackagePath)805 int32_t SandboxCore::SetBundleResourceAppSandboxProperty(const AppSpawningCtx *appProperty,
806                                                          std::string &sandboxPackagePath)
807 {
808     if (!CheckAppMsgFlagsSet(appProperty, APP_FLAGS_BUNDLE_RESOURCES)) {
809         return 0;
810     }
811 
812     std::string destPath = sandboxPackagePath + SandboxCommonDef::g_bundleResourceDestPath;
813     SharedMountArgs arg = {
814         .srcPath = SandboxCommonDef::g_bundleResourceSrcPath.c_str(),
815         .destPath = destPath.c_str()
816     };
817     return SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg);
818 }
819 
SetCommonAppSandboxProperty(const AppSpawningCtx * appProperty,std::string & sandboxPackagePath)820 int32_t SandboxCore::SetCommonAppSandboxProperty(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath)
821 {
822     int ret = 0;
823     SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
824         SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG;
825 
826     for (auto& jsonConfig : SandboxCommon::GetCJsonConfig(type)) {
827         ret = SetCommonAppSandboxProperty_(appProperty, jsonConfig);
828         APPSPAWN_CHECK(ret == 0, return ret,
829             "parse appdata config for common failed, %{public}s", sandboxPackagePath.c_str());
830     }
831     cJSON *hspRoot = GetJsonObjFromProperty(appProperty, SandboxCommonDef::HSPLIST_SOCKET_TYPE.c_str());
832     ret = MountAllHsp(appProperty, sandboxPackagePath, hspRoot);
833     cJSON_Delete(hspRoot);
834     APPSPAWN_CHECK(ret == 0, return ret, "mount extraInfo failed, %{public}s", sandboxPackagePath.c_str());
835 
836     ret = MountAllGroup(appProperty, sandboxPackagePath);
837     APPSPAWN_CHECK(ret == 0, return ret, "mount groupList failed, %{public}s", sandboxPackagePath.c_str());
838 
839     AppSpawnMsgDomainInfo *info =
840         reinterpret_cast<AppSpawnMsgDomainInfo *>(GetAppProperty(appProperty, TLV_DOMAIN_INFO));
841     APPSPAWN_CHECK(info != nullptr, return -1, "No domain info %{public}s", sandboxPackagePath.c_str());
842     if (strcmp(info->apl, SandboxCommonDef::APL_SYSTEM_BASIC.data()) == 0 ||
843         strcmp(info->apl, SandboxCommonDef::APL_SYSTEM_CORE.data()) == 0 ||
844         CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ACCESS_BUNDLE_DIR)) {
845         // need permission check for system app here
846         std::string destbundlesPath = sandboxPackagePath + SandboxCommonDef::g_dataBundles;
847         SharedMountArgs arg = {
848             .srcPath = SandboxCommonDef::g_physicalAppInstallPath.c_str(),
849             .destPath = destbundlesPath.c_str()
850         };
851         SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg);
852     }
853 
854     return 0;
855 }
856 
SetPrivateAppSandboxProperty(const AppSpawningCtx * appProperty)857 int32_t SandboxCore::SetPrivateAppSandboxProperty(const AppSpawningCtx *appProperty)
858 {
859     int ret = 0;
860     SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
861         SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG;
862 
863     for (auto& config : SandboxCommon::GetCJsonConfig(type)) {
864         ret = SetPrivateAppSandboxProperty_(appProperty, config);
865         APPSPAWN_CHECK(ret == 0, return ret, "parse adddata-sandbox config failed");
866     }
867     return ret;
868 }
869 
SetPermissionAppSandboxProperty(AppSpawningCtx * appProperty)870 int32_t SandboxCore::SetPermissionAppSandboxProperty(AppSpawningCtx *appProperty)
871 {
872     int ret = 0;
873     SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
874         SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG;
875 
876     for (auto& config : SandboxCommon::GetCJsonConfig(type)) {
877         ret = SetPermissionAppSandboxProperty_(appProperty, config);
878         APPSPAWN_CHECK(ret == 0, return ret, "parse permission config failed");
879     }
880     return ret;
881 }
882 
SetSandboxProperty(AppSpawningCtx * appProperty,std::string & sandboxPackagePath)883 int32_t SandboxCore::SetSandboxProperty(AppSpawningCtx *appProperty, std::string &sandboxPackagePath)
884 {
885     int32_t ret = 0;
886     const std::string bundleName = GetBundleName(appProperty);
887     StartAppspawnTrace("SetCommonAppSandboxProperty");
888     ret = SetCommonAppSandboxProperty(appProperty, sandboxPackagePath);
889     FinishAppspawnTrace();
890     APPSPAWN_CHECK(ret == 0, return ret, "SetCommonAppSandboxProperty failed, packagename is %{public}s",
891                    bundleName.c_str());
892     if (SandboxCommon::HasPrivateInBundleName(bundleName)) {
893         ret = SetPrivateAppSandboxProperty(appProperty);
894         APPSPAWN_CHECK(ret == 0, return ret, "SetPrivateAppSandboxProperty failed, packagename is %{public}s",
895                        bundleName.c_str());
896     }
897     StartAppspawnTrace("SetPermissionAppSandboxProperty");
898     ret = SetPermissionAppSandboxProperty(appProperty);
899     FinishAppspawnTrace();
900     APPSPAWN_CHECK(ret == 0, return ret, "SetPermissionAppSandboxProperty failed, packagename is %{public}s",
901                    bundleName.c_str());
902 
903     ret = SetOverlayAppSandboxProperty(appProperty, sandboxPackagePath);
904     APPSPAWN_CHECK(ret == 0, return ret, "SetOverlayAppSandboxProperty failed, packagename is %{public}s",
905                    bundleName.c_str());
906 
907     ret = SetBundleResourceAppSandboxProperty(appProperty, sandboxPackagePath);
908     APPSPAWN_CHECK(ret == 0, return ret, "SetBundleResourceAppSandboxProperty failed, packagename is %{public}s",
909                    bundleName.c_str());
910     APPSPAWN_LOGV("Set appsandbox property success");
911     return ret;
912 }
913 
SetAppSandboxProperty(AppSpawningCtx * appProperty,uint32_t sandboxNsFlags)914 int32_t SandboxCore::SetAppSandboxProperty(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags)
915 {
916     APPSPAWN_CHECK(appProperty != nullptr, return -1, "Invalid appspawn client");
917     if (SandboxCommon::CheckBundleName(GetBundleName(appProperty)) != 0) {
918         return -1;
919     }
920     AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
921     APPSPAWN_CHECK(dacInfo != nullptr, return -1, "No dac info in msg app property");
922 
923     const std::string bundleName = GetBundleName(appProperty);
924     cJSON *tmpJson = nullptr;
925     std::string sandboxPackagePath = SandboxCommon::GetSandboxRootPath(appProperty, tmpJson);
926     SandboxCommon::CreateDirRecursiveWithClock(sandboxPackagePath.c_str(), SandboxCommonDef::FILE_MODE);
927     bool sandboxSharedStatus = SandboxCommon::IsPrivateSharedStatus(bundleName, appProperty) ||
928         (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(GetPermissionIndex(nullptr,
929         SandboxCommonDef::ACCESS_DLP_FILE_MODE.c_str()))) != 0);
930 
931     // add pid to a new mnt namespace
932     StartAppspawnTrace("EnableSandboxNamespace");
933     int rc = EnableSandboxNamespace(appProperty, sandboxNsFlags);
934     FinishAppspawnTrace();
935     APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str());
936     APPSPAWN_CHECK(UpdatePointFlags(appProperty) == 0, return -1, "Set app permission flag fail.");
937 
938     UpdateMsgFlagsWithPermission(appProperty, SandboxCommonDef::GET_ALL_PROCESSES_MODE, APP_FLAGS_GET_ALL_PROCESSES);
939     UpdateMsgFlagsWithPermission(appProperty, SandboxCommonDef::APP_ALLOW_IOURING, APP_FLAGS_ALLOW_IOURING);
940     // check app sandbox switch
941     if (!SandboxCommon::IsTotalSandboxEnabled(appProperty) || !SandboxCommon::IsAppSandboxEnabled(appProperty)) {
942         rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath);
943     } else if (!sandboxSharedStatus) {
944         rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath);
945     }
946     APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str());
947     rc = SetSandboxProperty(appProperty, sandboxPackagePath);
948     APPSPAWN_CHECK(rc == 0, return rc, "SetSandboxProperty failed, %{public}s", bundleName.c_str());
949 
950 #ifdef APPSPAWN_MOUNT_TMPSHM
951     MountDevShmPath(sandboxPackagePath);
952 #endif
953 
954 #ifndef APPSPAWN_TEST
955     StartAppspawnTrace("ChangeCurrentDir");
956     rc = ChangeCurrentDir(sandboxPackagePath, bundleName, sandboxSharedStatus);
957     FinishAppspawnTrace();
958     APPSPAWN_CHECK(rc == 0, return rc, "change current dir failed");
959     APPSPAWN_LOGV("Change root dir success");
960 #endif
961     SetDecWithDir(appProperty, dacInfo->uid / UID_BASE);
962     SetDecDenyWithDir(appProperty);
963     SetDecPolicy();
964 #if defined(APPSPAWN_MOUNT_TMPSHM) && defined(WITH_SELINUX)
965     Restorecon(DEV_SHM_DIR);
966 #endif
967     return 0;
968 }
969 
SetRenderSandboxPropertyNweb(const AppSpawningCtx * appProperty,std::string & sandboxPackagePath)970 int32_t SandboxCore::SetRenderSandboxPropertyNweb(const AppSpawningCtx *appProperty, std::string &sandboxPackagePath)
971 {
972     char *processType = (char *)(GetAppSpawnMsgExtInfo(appProperty->message, MSG_EXT_NAME_PROCESS_TYPE, nullptr));
973     APPSPAWN_CHECK(processType != nullptr, return -1, "Invalid processType data");
974     SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(appProperty, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
975         SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG;
976 
977     int ret = 0;
978     const char *bundleName = GetBundleName(appProperty);
979     for (auto& config : SandboxCommon::GetCJsonConfig(type)) {
980         cJSON *firstIndividual = GetFirstCommonConfig(config, SandboxCommonDef::g_privatePrefix);
981         if (!firstIndividual) {
982             continue;
983         }
984         if (strcmp(processType, "render") == 0) {
985             cJSON *renderInfo = GetFirstSubConfig(firstIndividual, SandboxCommonDef::g_ohosRender.c_str());
986             if (!renderInfo) {
987                 continue;
988             }
989             ret = DoAllMntPointsMount(appProperty, renderInfo, nullptr, SandboxCommonDef::g_ohosRender);
990             APPSPAWN_CHECK(ret == 0, return ret, "DoAllMntPointsMount failed, %{public}s", bundleName);
991 
992             ret = DoAllSymlinkPointslink(appProperty, renderInfo);
993             APPSPAWN_CHECK(ret == 0, return ret, "DoAllSymlinkPointslink failed, %{public}s", bundleName);
994 
995             ret = HandleFlagsPoint(appProperty, renderInfo);
996             APPSPAWN_CHECK_ONLY_LOG(ret == 0, "HandleFlagsPoint for render-sandbox failed, %{public}s", bundleName);
997         } else if (strcmp(processType, "gpu") == 0) {
998             cJSON *gpuInfo = GetFirstSubConfig(firstIndividual, SandboxCommonDef::g_ohosGpu.c_str());
999             if (!gpuInfo) {
1000                 continue;
1001             }
1002             ret = DoAllMntPointsMount(appProperty, gpuInfo, nullptr, SandboxCommonDef::g_ohosGpu);
1003             APPSPAWN_CHECK(ret == 0, return ret, "DoAllMntPointsMount failed, %{public}s", bundleName);
1004 
1005             ret = DoAllSymlinkPointslink(appProperty, gpuInfo);
1006             APPSPAWN_CHECK(ret == 0, return ret, "DoAllSymlinkPointslink failed, %{public}s", bundleName);
1007 
1008             ret = HandleFlagsPoint(appProperty, gpuInfo);
1009             APPSPAWN_CHECK_ONLY_LOG(ret == 0, "HandleFlagsPoint for gpu-sandbox failed, %{public}s", bundleName);
1010         }
1011     }
1012 
1013     return 0;
1014 }
1015 
SetAppSandboxPropertyNweb(AppSpawningCtx * appProperty,uint32_t sandboxNsFlags)1016 int32_t SandboxCore::SetAppSandboxPropertyNweb(AppSpawningCtx *appProperty, uint32_t sandboxNsFlags)
1017 {
1018     APPSPAWN_CHECK(appProperty != nullptr, return -1, "Invalid appspawn client");
1019     if (SandboxCommon::CheckBundleName(GetBundleName(appProperty)) != 0) {
1020         return -1;
1021     }
1022     std::string sandboxPackagePath = SandboxCommonDef::g_sandBoxRootDirNweb;
1023     const std::string bundleName = GetBundleName(appProperty);
1024     bool sandboxSharedStatus = SandboxCommon::IsPrivateSharedStatus(bundleName, appProperty);
1025     sandboxPackagePath += bundleName;
1026     SandboxCommon::CreateDirRecursiveWithClock(sandboxPackagePath.c_str(), SandboxCommonDef::FILE_MODE);
1027 
1028     // add pid to a new mnt namespace
1029     StartAppspawnTrace("EnableSandboxNamespace");
1030     int rc = EnableSandboxNamespace(appProperty, sandboxNsFlags);
1031     FinishAppspawnTrace();
1032     APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %{public}s", bundleName.c_str());
1033 
1034     // check app sandbox switch
1035     if ((SandboxCommon::IsTotalSandboxEnabled(appProperty) == false) ||
1036         (SandboxCommon::IsAppSandboxEnabled(appProperty) == false)) {
1037         rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath);
1038     } else if (!sandboxSharedStatus) {
1039         rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath);
1040     }
1041     APPSPAWN_CHECK(rc == 0, return rc, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str());
1042 
1043     // rendering process can be created by different apps, and the bundle names of these apps are different,
1044     // so we can't use the method SetPrivateAppSandboxProperty which mount dirs by using bundle name.
1045     rc = SetRenderSandboxPropertyNweb(appProperty, sandboxPackagePath);
1046     APPSPAWN_CHECK(rc == 0, return rc, "SetRenderSandboxPropertyNweb for %{public}s failed", bundleName.c_str());
1047 
1048     rc = SetOverlayAppSandboxProperty(appProperty, sandboxPackagePath);
1049     APPSPAWN_CHECK(rc == 0, return rc, "SetOverlayAppSandboxProperty for %{public}s failed", bundleName.c_str());
1050 
1051     rc = SetBundleResourceAppSandboxProperty(appProperty, sandboxPackagePath);
1052     APPSPAWN_CHECK(rc == 0, return rc, "SetBundleResourceAppSandboxProperty for %{public}s failed", bundleName.c_str());
1053 
1054 #ifndef APPSPAWN_TEST
1055     rc = chdir(sandboxPackagePath.c_str());
1056     APPSPAWN_CHECK(rc == 0, return rc, "chdir %{public}s failed, err %{public}d", sandboxPackagePath.c_str(), errno);
1057 
1058     if (sandboxSharedStatus) {
1059         rc = chroot(sandboxPackagePath.c_str());
1060         APPSPAWN_CHECK(rc == 0, return rc, "chroot %{public}s failed, err %{public}d",
1061             sandboxPackagePath.c_str(), errno);
1062         return 0;
1063     }
1064 
1065     rc = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str());
1066     APPSPAWN_CHECK(rc == 0, return rc, "pivot %{public}s failed, err %{public}d", sandboxPackagePath.c_str(), errno);
1067 
1068     rc = umount2(".", MNT_DETACH);
1069     APPSPAWN_CHECK(rc == 0, return rc, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str());
1070 #endif
1071     return 0;
1072 }
1073 
ChangeCurrentDir(std::string & sandboxPackagePath,const std::string & bundleName,bool sandboxSharedStatus)1074 int32_t SandboxCore::ChangeCurrentDir(std::string &sandboxPackagePath, const std::string &bundleName,
1075                                     bool sandboxSharedStatus)
1076 {
1077     int32_t ret = 0;
1078     ret = chdir(sandboxPackagePath.c_str());
1079     APPSPAWN_CHECK(ret == 0, return ret, "chdir %{public}s failed, err %{public}d", sandboxPackagePath.c_str(), errno);
1080 
1081     if (sandboxSharedStatus) {
1082         ret = chroot(sandboxPackagePath.c_str());
1083         APPSPAWN_CHECK(ret == 0, return ret, "chroot %{public}s failed, err %{public}d",
1084             sandboxPackagePath.c_str(), errno);
1085         return ret;
1086     }
1087 
1088     ret = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str());
1089     APPSPAWN_CHECK(ret == 0, return ret, "pivot %{public}s failed, err %{public}d", sandboxPackagePath.c_str(), errno);
1090 
1091     ret = umount2(".", MNT_DETACH);
1092     APPSPAWN_CHECK(ret == 0, return ret, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str());
1093     return ret;
1094 }
1095 
1096 static const DecDenyPathTemplate DEC_DENY_PATH_MAP[] = {
1097     {"ohos.permission.READ_WRITE_DOWNLOAD_DIRECTORY", "/storage/Users/currentUser/Download"},
1098     {"ohos.permission.READ_WRITE_DESKTOP_DIRECTORY", "/storage/Users/currentUser/Desktop"},
1099     {"ohos.permission.READ_WRITE_DOCUMENTS_DIRECTORY", "/storage/Users/currentUser/Documents"},
1100 };
1101 
SetDecWithDir(const AppSpawningCtx * appProperty,uint32_t userId)1102 int32_t SandboxCore::SetDecWithDir(const AppSpawningCtx *appProperty, uint32_t userId)
1103 {
1104     AppSpawnMsgAccessToken *tokenInfo =
1105         reinterpret_cast<AppSpawnMsgAccessToken *>(GetAppProperty(appProperty, TLV_ACCESS_TOKEN_INFO));
1106     APPSPAWN_CHECK(tokenInfo != nullptr, return APPSPAWN_MSG_INVALID, "Get token id failed.");
1107 
1108     AppSpawnMsgBundleInfo *bundleInfo =
1109         reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO));
1110     APPSPAWN_CHECK(bundleInfo != nullptr, return APPSPAWN_MSG_INVALID, "No bundle info in msg %{public}s",
1111         GetBundleName(appProperty));
1112 
1113     uint32_t flags = CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE) ? 0x4 : 0;
1114     if (flags == 0) {
1115         flags = (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_CLONE_ENABLE) &&
1116             bundleInfo->bundleIndex > 0) ? 0x1 : 0;
1117     }
1118     std::ostringstream clonePackageName;
1119     if (flags == 1) {
1120         clonePackageName << "+clone-" << bundleInfo->bundleIndex << "+" << bundleInfo->bundleName;
1121     } else {
1122         clonePackageName << bundleInfo->bundleName;
1123     }
1124     std::string dir = "/storage/Users/currentUser/Download/" + clonePackageName.str();
1125     DecPolicyInfo decPolicyInfo = {0};
1126     decPolicyInfo.pathNum = 1;
1127     PathInfo pathInfo = {0};
1128     pathInfo.path = strdup(dir.c_str());
1129     if (pathInfo.path == nullptr) {
1130         APPSPAWN_LOGE("strdup %{public}s failed, err %{public}d", dir.c_str(), errno);
1131         return APPSPAWN_MSG_INVALID;
1132     }
1133     pathInfo.pathLen = static_cast<uint32_t>(strlen(pathInfo.path));
1134     pathInfo.mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ;
1135     decPolicyInfo.path[0] = pathInfo;
1136     decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx;
1137     decPolicyInfo.flag = true;
1138     SetDecPolicyInfos(&decPolicyInfo);
1139 
1140     if (decPolicyInfo.path[0].path) {
1141         free(decPolicyInfo.path[0].path);
1142         decPolicyInfo.path[0].path = nullptr;
1143     }
1144     return 0;
1145 }
1146 
SetDecPolicyWithPermission(const AppSpawningCtx * appProperty,SandboxMountConfig & mountConfig)1147 int32_t SandboxCore::SetDecPolicyWithPermission(const AppSpawningCtx *appProperty, SandboxMountConfig &mountConfig)
1148 {
1149     if (mountConfig.decPaths.size() == 0) {
1150         return 0;
1151     }
1152     AppSpawnMsgAccessToken *tokenInfo =
1153         reinterpret_cast<AppSpawnMsgAccessToken *>(GetAppProperty(appProperty, TLV_ACCESS_TOKEN_INFO));
1154     APPSPAWN_CHECK(tokenInfo != nullptr, return APPSPAWN_MSG_INVALID, "Get token id failed.");
1155 
1156     DecPolicyInfo decPolicyInfo = {0};
1157     decPolicyInfo.pathNum = mountConfig.decPaths.size();
1158     int ret = 0;
1159     for (uint32_t i = 0; i < decPolicyInfo.pathNum; i++) {
1160         PathInfo pathInfo = {0};
1161         pathInfo.path = strdup(mountConfig.decPaths[i].c_str());
1162         if (pathInfo.path == nullptr) {
1163             APPSPAWN_LOGE("strdup %{public}s failed, err %{public}d", mountConfig.decPaths[i].c_str(), errno);
1164             ret = APPSPAWN_ERROR_UTILS_MEM_FAIL;
1165             goto EXIT;
1166         }
1167         pathInfo.pathLen = static_cast<uint32_t>(strlen(pathInfo.path));
1168         pathInfo.mode = SANDBOX_MODE_WRITE | SANDBOX_MODE_READ;
1169         decPolicyInfo.path[i] = pathInfo;
1170     }
1171     decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx;
1172     decPolicyInfo.flag = true;
1173     SetDecPolicyInfos(&decPolicyInfo);
1174 EXIT:
1175     for (uint32_t i = 0; i < decPolicyInfo.pathNum; i++) {
1176         if (decPolicyInfo.path[i].path) {
1177             free(decPolicyInfo.path[i].path);
1178             decPolicyInfo.path[i].path = nullptr;
1179         }
1180     }
1181     return ret;
1182 }
1183 
SetDecDenyWithDir(const AppSpawningCtx * appProperty)1184 void SandboxCore::SetDecDenyWithDir(const AppSpawningCtx *appProperty)
1185 {
1186     int32_t userFileIndex = GetPermissionIndex(nullptr, SandboxCommonDef::READ_WRITE_USER_FILE_MODE.c_str());
1187     APPSPAWN_CHECK_LOGV(userFileIndex != -1, return, "userFileIndex Invalid index");
1188     if (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(userFileIndex)) == 0) {
1189         APPSPAWN_LOGV("The app doesn't have %{public}s, no need to set deny rules",
1190                       SandboxCommonDef::READ_WRITE_USER_FILE_MODE.c_str());
1191         return;
1192     }
1193 
1194     AppSpawnMsgAccessToken *tokenInfo =
1195         reinterpret_cast<AppSpawnMsgAccessToken *>(GetAppProperty(appProperty, TLV_ACCESS_TOKEN_INFO));
1196     APPSPAWN_CHECK(tokenInfo != nullptr, return, "Get token id failed");
1197 
1198     DecPolicyInfo decPolicyInfo = {0};
1199     decPolicyInfo.pathNum = 0;
1200     uint32_t count = ARRAY_LENGTH(DEC_DENY_PATH_MAP);
1201     for (uint32_t i = 0, j = 0; i < count; i++) {
1202         int32_t index = GetPermissionIndex(nullptr, DEC_DENY_PATH_MAP[i].permission);
1203         if (CheckAppPermissionFlagSet(appProperty, static_cast<uint32_t>(index))) {
1204             continue;
1205         }
1206         PathInfo pathInfo = {0};
1207         pathInfo.path = const_cast<char *>(DEC_DENY_PATH_MAP[i].decPath);
1208         pathInfo.pathLen = static_cast<uint32_t>(strlen(pathInfo.path));
1209         pathInfo.mode = DEC_MODE_DENY_INHERIT;
1210         decPolicyInfo.path[j++] = pathInfo;
1211         decPolicyInfo.pathNum += 1;
1212     }
1213     decPolicyInfo.tokenId = tokenInfo->accessTokenIdEx;
1214     decPolicyInfo.flag = true;
1215     SetDecPolicyInfos(&decPolicyInfo);
1216 }
1217 
ConvertDebugRealPath(const AppSpawningCtx * appProperty,std::string path)1218 std::string SandboxCore::ConvertDebugRealPath(const AppSpawningCtx *appProperty, std::string path)
1219 {
1220     AppSpawnMsgBundleInfo *info =
1221         reinterpret_cast<AppSpawnMsgBundleInfo *>(GetAppProperty(appProperty, TLV_BUNDLE_INFO));
1222     AppSpawnMsgDacInfo *dacInfo = reinterpret_cast<AppSpawnMsgDacInfo *>(GetAppProperty(appProperty, TLV_DAC_INFO));
1223     if (info == nullptr || dacInfo == nullptr) {
1224         return "";
1225     }
1226     if (CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE)) {
1227         path = SandboxCommon::ReplaceAllVariables(path, SandboxCommonDef::g_variablePackageName, info->bundleName);
1228     }
1229     return SandboxCommon::ConvertToRealPath(appProperty, path);
1230 }
1231 
DoUninstallDebugSandbox(std::vector<std::string> & bundleList,cJSON * config)1232 void SandboxCore::DoUninstallDebugSandbox(std::vector<std::string> &bundleList, cJSON *config)
1233 {
1234     cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(config, SandboxCommonDef::g_mountPrefix);
1235     if (mountPoints == nullptr || !cJSON_IsArray(mountPoints)) {
1236         APPSPAWN_LOGI("Invalid mountPoints");
1237         return;
1238     }
1239 
1240     auto processor = [&bundleList](cJSON *mntPoint) {
1241         const char *srcPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_srcPath);
1242         const char *sandboxPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_sandBoxPath);
1243         if (srcPathChr == nullptr || sandboxPathChr == nullptr) {
1244             return 0;
1245         }
1246         std::string tmpSandboxPath = sandboxPathChr;
1247         for (const auto& currentBundle : bundleList) {
1248             std::string sandboxPath = currentBundle + tmpSandboxPath;
1249             APPSPAWN_LOGV("DoUninstallDebugSandbox with path %{public}s", sandboxPath.c_str());
1250             APPSPAWN_CHECK(access(sandboxPath.c_str(), F_OK) == 0, continue,
1251                 "Invalid path %{public}s", sandboxPath.c_str());
1252             int ret = umount2(sandboxPath.c_str(), MNT_DETACH);
1253             APPSPAWN_CHECK_ONLY_LOG(ret == 0, "umount failed %{public}d %{public}d", ret, errno);
1254             ret = rmdir(sandboxPath.c_str());
1255             APPSPAWN_CHECK_ONLY_LOG(ret == 0, "rmdir failed %{public}d %{public}d", ret, errno);
1256         }
1257         return 0;
1258     };
1259 
1260     (void)SandboxCommon::HandleArrayForeach(mountPoints, processor);
1261 }
1262 
GetPackageList(AppSpawningCtx * property,std::vector<std::string> & bundleList,bool tmp)1263 int32_t SandboxCore::GetPackageList(AppSpawningCtx *property, std::vector<std::string> &bundleList, bool tmp)
1264 {
1265     APPSPAWN_CHECK(property != nullptr, return APPSPAWN_ARG_INVALID, "Invalid property");
1266     AppDacInfo *info = reinterpret_cast<AppDacInfo *>(GetAppProperty(property, TLV_DAC_INFO));
1267     if (GetBundleName(property) == nullptr || SandboxCommon::CheckBundleName(GetBundleName(property)) != 0 ||
1268         info == nullptr) {
1269         std::string uid;
1270         char *userId = (char *)GetAppSpawnMsgExtInfo(property->message, MSG_EXT_NAME_USERID, nullptr);
1271         if (userId != nullptr) {
1272             uid = std::string(userId);
1273         } else {
1274             APPSPAWN_CHECK(info != nullptr, return APPSPAWN_ARG_INVALID, "Invalid dacInfo");
1275             uid = std::to_string(info->uid / UID_BASE);
1276         }
1277         std::string defaultSandboxRoot = (tmp ? SandboxCommonDef::g_mntTmpRoot : SandboxCommonDef::g_mntShareRoot) +
1278                                           uid + "/debug_hap";
1279         APPSPAWN_CHECK(access(defaultSandboxRoot.c_str(), F_OK) == 0, return APPSPAWN_ARG_INVALID,
1280             "Failed to access %{public}s, err %{public}d", defaultSandboxRoot.c_str(), errno);
1281 
1282         DIR *dir = opendir(defaultSandboxRoot.c_str());
1283         if (dir == nullptr) {
1284             APPSPAWN_LOGE("Failed to open %{public}s, err %{public}d", defaultSandboxRoot.c_str(), errno);
1285             return APPSPAWN_SYSTEM_ERROR;
1286         }
1287         struct dirent *entry;
1288         while ((entry = readdir(dir)) != nullptr) {
1289             if (entry->d_name[0] == '.') {
1290                 continue;
1291             }
1292             std::string packagePath = defaultSandboxRoot + "/" + std::string(entry->d_name);
1293             APPSPAWN_LOGV("GetPackageList %{public}s", packagePath.c_str());
1294             bundleList.push_back(packagePath);
1295         }
1296         closedir(dir);
1297     } else {
1298         bundleList.push_back(ConvertDebugRealPath(property, tmp ? SandboxCommonDef::g_mntTmpSandboxRoot :
1299                              SandboxCommonDef::g_mntShareSandboxRoot));
1300     }
1301     return 0;
1302 }
1303 
UninstallDebugSandbox(AppSpawnMgr * content,AppSpawningCtx * property)1304 int32_t SandboxCore::UninstallDebugSandbox(AppSpawnMgr *content, AppSpawningCtx *property)
1305 {
1306     APPSPAWN_CHECK(property != nullptr && content != nullptr, return APPSPAWN_ARG_INVALID, "Invalid property");
1307 
1308     std::vector<std::string> bundleList;
1309     int ret = GetPackageList(property, bundleList, true);
1310     APPSPAWN_CHECK(ret == 0, return -1, "GetPackageList failed");
1311     SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
1312         SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG;
1313     for (auto& wholeConfig : SandboxCommon::GetCJsonConfig(type)) {
1314         cJSON *debugJson = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_debughap);
1315         if (!debugJson) {
1316             continue;
1317         }
1318         cJSON *debugCommonConfig = GetFirstSubConfig(debugJson, SandboxCommonDef::g_commonPrefix);
1319         if (!debugCommonConfig) {
1320             continue;
1321         }
1322         DoUninstallDebugSandbox(bundleList, debugCommonConfig);
1323 
1324         cJSON *debugPermissionConfig = GetFirstSubConfig(debugJson, SandboxCommonDef::g_permissionPrefix);
1325         if (!debugPermissionConfig) {
1326             continue;
1327         }
1328 
1329         cJSON *permissionChild = debugPermissionConfig->child;
1330         while (permissionChild != nullptr) {
1331             cJSON *permissionMountPaths = cJSON_GetArrayItem(permissionChild, 0);
1332             if (!permissionMountPaths) {
1333                 permissionChild = permissionChild->next;
1334                 continue;
1335             }
1336             DoUninstallDebugSandbox(bundleList, permissionMountPaths);
1337             permissionChild = permissionChild->next;
1338         }
1339     }
1340     bundleList.clear();
1341     ret = GetPackageList(property, bundleList, false);
1342     APPSPAWN_CHECK(ret == 0, return -1, "GetPackageList failed");
1343     for (const auto& currentBundle : bundleList) {
1344         std::string sandboxPath = currentBundle;
1345         APPSPAWN_LOGV("UninstallDebugSandbox with path %{public}s", sandboxPath.c_str());
1346             APPSPAWN_CHECK(access(sandboxPath.c_str(), F_OK) == 0, continue,
1347                 "Invalid path %{public}s", sandboxPath.c_str());
1348         ret = umount2(sandboxPath.c_str(), MNT_DETACH);
1349         APPSPAWN_CHECK_ONLY_LOG(ret == 0, "umount failed %{public}d %{public}d", ret, errno);
1350         ret = rmdir(sandboxPath.c_str());
1351         APPSPAWN_CHECK_ONLY_LOG(ret == 0, "rmdir failed %{public}d %{public}d", ret, errno);
1352     }
1353 
1354     return 0;
1355 }
1356 
DoMountDebugPoints(const AppSpawningCtx * appProperty,cJSON * appConfig)1357 int32_t SandboxCore::DoMountDebugPoints(const AppSpawningCtx *appProperty, cJSON *appConfig)
1358 {
1359     std::string bundleName = GetBundleName(appProperty);
1360     cJSON *mountPoints = cJSON_GetObjectItemCaseSensitive(appConfig, SandboxCommonDef::g_mountPrefix);
1361     if (mountPoints == nullptr || !cJSON_IsArray(mountPoints)) {
1362         APPSPAWN_LOGI("mount config is not found, app name is %{public}s", bundleName.c_str());
1363         return 0;
1364     }
1365 
1366     std::string sandboxRoot = ConvertDebugRealPath(appProperty, SandboxCommonDef::g_mntTmpSandboxRoot);
1367     int atomicService = CheckAppSpawnMsgFlag(appProperty->message, TLV_MSG_FLAGS, APP_FLAGS_ATOMIC_SERVICE);
1368 
1369     auto processor = [&sandboxRoot, &atomicService, &appProperty](cJSON *mntPoint) {
1370         const char *srcPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_srcPath);
1371         const char *sandboxPathChr = GetStringFromJsonObj(mntPoint, SandboxCommonDef::g_sandBoxPath);
1372         if (srcPathChr == nullptr || sandboxPathChr == nullptr) {
1373             return 0;
1374         }
1375         std::string srcPath(srcPathChr);
1376         std::string sandboxPath(sandboxPathChr);
1377         srcPath = SandboxCommon::ConvertToRealPath(appProperty, srcPath);
1378         sandboxPath = GetSandboxPath(appProperty, mntPoint, SandboxCommonDef::g_debughap, sandboxRoot);
1379         if (access(sandboxPath.c_str(), F_OK) == 0) {
1380             APPSPAWN_CHECK(atomicService, return 0, "sandbox path already exist");
1381             APPSPAWN_CHECK(umount2(sandboxPath.c_str(), MNT_DETACH) == 0, return 0,
1382                 "umount sandbox path failed, errno is %{public}d %{public}s", errno, sandboxPath.c_str());
1383         }
1384         SandboxMountConfig mountConfig = {0};
1385         SandboxCommon::GetSandboxMountConfig(appProperty, SandboxCommonDef::g_debughap, mntPoint, mountConfig);
1386         SharedMountArgs arg = {
1387             .srcPath = srcPath.c_str(),
1388             .destPath = sandboxPath.c_str(),
1389             .fsType = mountConfig.fsType.c_str(),
1390             .mountFlags = SandboxCommon::GetMountFlags(mntPoint),
1391             .options = mountConfig.optionsPoint.c_str(),
1392             .mountSharedFlag =
1393                 GetBoolValueFromJsonObj(mntPoint, SandboxCommonDef::g_mountSharedFlag, false) ? MS_SHARED : MS_SLAVE
1394         };
1395         int ret = SandboxCommon::DoAppSandboxMountOnce(appProperty, &arg);
1396         APPSPAWN_CHECK(ret == 0 || !SandboxCommon::IsMountSuccessful(mntPoint), return ret,
1397             "DoMountDebugPoints %{public}s failed", arg.destPath);
1398         return ret;
1399     };
1400 
1401     (void)SandboxCommon::HandleArrayForeach(mountPoints, processor);
1402     return 0;
1403 }
1404 
MountDebugSharefs(const AppSpawningCtx * property,const char * src,const char * target)1405 int32_t SandboxCore::MountDebugSharefs(const AppSpawningCtx *property, const char *src, const char *target)
1406 {
1407     char dataPath[SandboxCommonDef::OPTIONS_MAX_LEN] = {0};
1408     int ret = snprintf_s(dataPath, SandboxCommonDef::OPTIONS_MAX_LEN, SandboxCommonDef::OPTIONS_MAX_LEN - 1,
1409                          "%s/data", target);
1410     if (ret >= 0 && access(dataPath, F_OK) == 0) {
1411         return 0;
1412     }
1413 
1414     ret = MakeDirRec(target, SandboxCommonDef::FILE_MODE, 1);
1415     if (ret != 0) {
1416         return APPSPAWN_SANDBOX_ERROR_MKDIR_FAIL;
1417     }
1418 
1419     AppDacInfo *info = reinterpret_cast<AppDacInfo *>(GetAppProperty(property, TLV_DAC_INFO));
1420     if (info == nullptr) {
1421         return APPSPAWN_ARG_INVALID;
1422     }
1423     char options[SandboxCommonDef::OPTIONS_MAX_LEN] = {0};
1424     ret = snprintf_s(options, SandboxCommonDef::OPTIONS_MAX_LEN, SandboxCommonDef::OPTIONS_MAX_LEN - 1,
1425                      "override_support_delete,user_id=%u", info->uid / UID_BASE);
1426     if (ret <= 0) {
1427         return APPSPAWN_ERROR_UTILS_MEM_FAIL;
1428     }
1429 
1430     if (mount(src, target, "sharefs", MS_NODEV, options) != 0) {
1431         APPSPAWN_LOGE("sharefs mount %{public}s to %{public}s failed, errno %{public}d", src, target, errno);
1432         return APPSPAWN_SANDBOX_ERROR_MOUNT_FAIL;
1433     }
1434     if (mount(nullptr, target, nullptr, MS_SHARED, nullptr) != 0) {
1435         APPSPAWN_LOGE("mount path %{public}s to shared failed, errno %{public}d", target, errno);
1436         return APPSPAWN_SANDBOX_ERROR_MOUNT_FAIL;
1437     }
1438 
1439     return 0;
1440 }
1441 
InstallDebugSandbox(AppSpawnMgr * content,AppSpawningCtx * property)1442 int32_t SandboxCore::InstallDebugSandbox(AppSpawnMgr *content, AppSpawningCtx *property)
1443 {
1444     if (!IsDeveloperModeOn(property)) {
1445         return 0;
1446     }
1447 
1448     uint32_t len = 0;
1449     char *provisionType = reinterpret_cast<char *>(GetAppPropertyExt(property,
1450         MSG_EXT_NAME_PROVISION_TYPE, &len));
1451     if (provisionType == nullptr || len == 0 || strcmp(provisionType, "debug") != 0) {
1452         return 0;
1453     }
1454 
1455     SandboxCommonDef::SandboxConfigType type = CheckAppMsgFlagsSet(property, APP_FLAGS_ISOLATED_SANDBOX_TYPE) ?
1456         SandboxCommonDef::SANDBOX_ISOLATED_JSON_CONFIG : SandboxCommonDef::SANDBOX_APP_JSON_CONFIG;
1457 
1458     for (auto& wholeConfig : SandboxCommon::GetCJsonConfig(type)) {
1459         cJSON *debugJson = GetFirstCommonConfig(wholeConfig, SandboxCommonDef::g_debughap);
1460         if (!debugJson) {
1461             continue;
1462         }
1463         cJSON *debugCommonConfig = GetFirstSubConfig(debugJson, SandboxCommonDef::g_commonPrefix);
1464         if (!debugCommonConfig) {
1465             continue;
1466         }
1467         DoMountDebugPoints(property, debugCommonConfig);
1468 
1469         cJSON *debugPermissionConfig = GetFirstSubConfig(debugJson, SandboxCommonDef::g_permissionPrefix);
1470         if (!debugPermissionConfig) {
1471             continue;
1472         }
1473 
1474         cJSON *permissionChild = debugPermissionConfig->child;
1475         while (permissionChild != nullptr) {
1476             int index = GetPermissionIndex(nullptr, permissionChild->string);
1477             if (CheckAppPermissionFlagSet(property, static_cast<uint32_t>(index)) == 0) {
1478                 permissionChild = permissionChild->next;
1479                 continue;
1480             }
1481             cJSON *permissionMountPaths = cJSON_GetArrayItem(permissionChild, 0);
1482             if (!permissionMountPaths) {
1483                 permissionChild = permissionChild->next;
1484                 continue;
1485             }
1486             DoMountDebugPoints(property, permissionMountPaths);
1487 
1488             permissionChild = permissionChild->next;
1489         }
1490     }
1491 
1492     MountDebugSharefs(property, ConvertDebugRealPath(property, SandboxCommonDef::g_mntTmpSandboxRoot).c_str(),
1493         ConvertDebugRealPath(property, SandboxCommonDef::g_mntShareSandboxRoot).c_str());
1494     return 0;
1495 }
1496 } // namespace AppSpawn
1497 } // namespace OHOS