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 §ion, 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 ¶ms)
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 §ion)
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 §ion)
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