mirror of
https://gitee.com/openharmony/startup_appspawn
synced 2024-11-23 07:00:17 +00:00
使能应用沙箱可配置功能
Signed-off-by: Zheng Yongjun <zhengyongjun3@huawei.com>
This commit is contained in:
parent
542d4aeafc
commit
01ee17293a
7
BUILD.gn
7
BUILD.gn
@ -22,6 +22,7 @@ config("appspawn_config") {
|
||||
"adapter",
|
||||
"interfaces/innerkits/include",
|
||||
"//utils/native/base/include",
|
||||
"util/include",
|
||||
"${aafwk_path}/frameworks/kits/appkit/native/app/include",
|
||||
"${aafwk_path}/interfaces/innerkits/app_manager/include/appmgr",
|
||||
"${appexecfwk_path}/interfaces/innerkits/libeventhandler/include",
|
||||
@ -42,6 +43,7 @@ config("appspawn_config") {
|
||||
"//base/startup/init_lite/interfaces/innerkits/include",
|
||||
"//base/startup/init_lite/interfaces/innerkits/sandbox/include",
|
||||
"//base/startup/syspara_lite/interfaces/innerkits/native/syspara/include",
|
||||
"//third_party/json/include",
|
||||
]
|
||||
|
||||
if (build_selinux) {
|
||||
@ -80,6 +82,8 @@ ohos_static_library("appspawn_server") {
|
||||
"${appspawn_path}/common/appspawn_server.c",
|
||||
"${appspawn_path}/standard/appspawn_process.c",
|
||||
"${appspawn_path}/standard/appspawn_service.c",
|
||||
"${appspawn_path}/util/src/json_utils.cpp",
|
||||
"${appspawn_path}/util/src/sandbox_utils.cpp",
|
||||
]
|
||||
defines = [
|
||||
"GRAPHIC_PERMISSION_CHECK",
|
||||
@ -118,12 +122,15 @@ ohos_executable("nwebspawn") {
|
||||
sources = [
|
||||
"${appspawn_path}/adapter/appspawn_nweb.cpp",
|
||||
"${appspawn_path}/standard/main.c",
|
||||
"${appspawn_path}/util/src/json_utils.cpp",
|
||||
"${appspawn_path}/util/src/sandbox_utils.cpp",
|
||||
]
|
||||
configs = [ ":appspawn_config" ]
|
||||
deps = [
|
||||
"${appspawn_path}:appspawn_server",
|
||||
"//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox",
|
||||
]
|
||||
external_deps = [ "hiviewdfx_hilog_native:libhilog" ]
|
||||
|
||||
install_enable = true
|
||||
subsystem_name = "${subsystem_name}"
|
||||
|
@ -31,6 +31,7 @@ void RunChildProcessor(AppSpawnContent *content, AppSpawnClient *client);
|
||||
void RegisterAppSandbox(struct AppSpawnContent_ *content, AppSpawnClient *client);
|
||||
int GetRenderProcessTerminationStatus(int32_t pid, int *status);
|
||||
void RecordRenderProcessExitedStatus(pid_t pid, int status);
|
||||
void LoadAppSandboxConfig(void);
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
@ -29,15 +29,33 @@
|
||||
|
||||
#include "sandbox.h"
|
||||
#include "sandbox_namespace.h"
|
||||
#include "json_utils.h"
|
||||
#include "sandbox_utils.h"
|
||||
#include "hilog/log.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace OHOS;
|
||||
using namespace OHOS::HiviewDFX;
|
||||
using namespace OHOS::AppSpawn;
|
||||
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawn_SandboxUtil"};
|
||||
|
||||
bool g_isPrivAppSandboxCreated = false;
|
||||
bool g_isAppSandboxCreated = false;
|
||||
|
||||
constexpr std::string_view APL_SYSTEM_CORE("system_core");
|
||||
constexpr std::string_view APL_SYSTEM_BASIC("system_basic");
|
||||
constexpr static int UID_BASE = 200000;
|
||||
constexpr static mode_t FILE_MODE = 0711;
|
||||
constexpr static mode_t NWEB_FILE_MODE = 0511;
|
||||
namespace {
|
||||
const std::string APP_JSON_CONFIG("/system/etc/sandbox/appdata-sandbox.json");
|
||||
}
|
||||
|
||||
void LoadAppSandboxConfig(void)
|
||||
{
|
||||
// load sandbox config
|
||||
nlohmann::json appSandboxConfig;
|
||||
bool rc = JsonUtils::GetJsonObjFromJson(appSandboxConfig, APP_JSON_CONFIG);
|
||||
if (!rc) {
|
||||
HiLog::Error(LABEL, "AppSpawnServer::Failed to load app private sandbox config");
|
||||
}
|
||||
SandboxUtils::StoreJsonConfig(appSandboxConfig);
|
||||
}
|
||||
|
||||
static void RegisterSandbox(AppSpawnContentExt *appSpawnContent, const char *sandbox)
|
||||
{
|
||||
@ -92,244 +110,6 @@ void RegisterAppSandbox(struct AppSpawnContent_ *content, AppSpawnClient *client
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t DoAppSandboxMountOnce(const std::string originPath, const std::string destinationPath)
|
||||
{
|
||||
int rc = 0;
|
||||
|
||||
rc = mount(originPath.c_str(), destinationPath.c_str(), NULL, MS_BIND | MS_REC, NULL);
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("bind mount %s to %s failed %d", originPath.c_str(),
|
||||
destinationPath.c_str(), errno);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = mount(NULL, destinationPath.c_str(), NULL, MS_PRIVATE, NULL);
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("private mount to %s failed %d", destinationPath.c_str(), errno);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t DoAppSandboxMount(const AppParameter &appProperty, std::string rootPath)
|
||||
{
|
||||
std::string currentUserId = std::to_string(appProperty.uid / UID_BASE);
|
||||
std::string oriInstallPath = "/data/app/el1/bundle/public/";
|
||||
std::string oriel1DataPath = "/data/app/el1/" + currentUserId + "/base/";
|
||||
std::string oriel2DataPath = "/data/app/el2/" + currentUserId + "/base/";
|
||||
std::string oriDatabasePath = "/data/app/el2/" + currentUserId + "/database/";
|
||||
std::string destDatabasePath = rootPath + "/data/storage/el2/database";
|
||||
std::string destInstallPath = rootPath + "/data/storage/el1/bundle";
|
||||
std::string destel1DataPath = rootPath + "/data/storage/el1/base";
|
||||
std::string destel2DataPath = rootPath + "/data/storage/el2/base";
|
||||
|
||||
int rc = 0;
|
||||
|
||||
std::string bundleName = appProperty.bundleName;
|
||||
oriInstallPath += bundleName;
|
||||
oriel1DataPath += bundleName;
|
||||
oriel2DataPath += bundleName;
|
||||
oriDatabasePath += bundleName;
|
||||
|
||||
std::map<std::string, std::string> mountMap;
|
||||
mountMap[destDatabasePath] = oriDatabasePath;
|
||||
mountMap[destInstallPath] = oriInstallPath;
|
||||
mountMap[destel1DataPath] = oriel1DataPath;
|
||||
mountMap[destel2DataPath] = oriel2DataPath;
|
||||
|
||||
std::map<std::string, std::string>::iterator iter;
|
||||
for (iter = mountMap.begin(); iter != mountMap.end(); ++iter) {
|
||||
rc = DoAppSandboxMountOnce(iter->second.c_str(), iter->first.c_str());
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
// to create some useful dir when mount point created
|
||||
std::vector<std::string> mkdirInfo;
|
||||
std::string dirPath;
|
||||
mkdirInfo.push_back("/data/storage/el1/bundle/nweb");
|
||||
mkdirInfo.push_back("/data/storage/el1/bundle/ohos.global.systemres");
|
||||
|
||||
for (size_t i = 0; i < mkdirInfo.size(); i++) {
|
||||
dirPath = rootPath + mkdirInfo[i];
|
||||
mkdir(dirPath.c_str(), FILE_MODE);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t DoAppSandboxMountCustomized(const AppParameter &appProperty, const std::string &rootPath)
|
||||
{
|
||||
std::string bundleName = appProperty.bundleName;
|
||||
std::string currentUserId = std::to_string(appProperty.uid / UID_BASE);
|
||||
std::string destInstallPath = rootPath + "/data/storage/el1/bundle";
|
||||
bool AuthFlag = false;
|
||||
const std::vector<std::string> AuthAppList = {"com.ohos.launcher", "com.ohos.permissionmanager"};
|
||||
if (std::find(AuthAppList.begin(), AuthAppList.end(), bundleName) != AuthAppList.end()) {
|
||||
AuthFlag = true;
|
||||
}
|
||||
|
||||
if (strcmp(appProperty.apl, APL_SYSTEM_BASIC.data()) == 0 ||
|
||||
strcmp(appProperty.apl, APL_SYSTEM_CORE.data()) == 0 || AuthFlag) {
|
||||
// account_0/applications/ dir can still access other packages' data now for compatibility purpose
|
||||
std::string oriapplicationsPath = "/data/app/el1/bundle/public/";
|
||||
std::string destapplicationsPath = rootPath + "/data/accounts/account_0/applications/";
|
||||
DoAppSandboxMountOnce(oriapplicationsPath.c_str(), destapplicationsPath.c_str());
|
||||
|
||||
// need permission check for system app here
|
||||
std::string destbundlesPath = rootPath + "/data/bundles/";
|
||||
DoAppSandboxMountOnce(oriapplicationsPath.c_str(), destbundlesPath.c_str());
|
||||
}
|
||||
|
||||
std::string orimntHmdfsPath = "/mnt/hmdfs/";
|
||||
std::string destmntHmdfsPath = rootPath + orimntHmdfsPath;
|
||||
DoAppSandboxMountOnce(orimntHmdfsPath.c_str(), destmntHmdfsPath.c_str());
|
||||
|
||||
// Add distributedfile module support, later reconstruct it
|
||||
std::string oriDistributedPath = "/mnt/hmdfs/" + currentUserId + "/account/merge_view/data/" + bundleName;
|
||||
std::string destDistributedPath = rootPath + "/data/storage/el2/distributedfiles";
|
||||
DoAppSandboxMountOnce(oriDistributedPath.c_str(), destDistributedPath.c_str());
|
||||
|
||||
std::string oriDistributedGroupPath = "/mnt/hmdfs/" + currentUserId + "/non_account/merge_view/data/" + bundleName;
|
||||
std::string destDistributedGroupPath = rootPath + "/data/storage/el2/auth_groups";
|
||||
DoAppSandboxMountOnce(oriDistributedGroupPath.c_str(), destDistributedGroupPath.c_str());
|
||||
|
||||
// do nweb adaption
|
||||
std::string orinwebPath = "/data/app/el1/bundle/public/com.ohos.nweb";
|
||||
std::string destnwebPath = destInstallPath + "/nweb";
|
||||
chmod(destnwebPath.c_str(), NWEB_FILE_MODE);
|
||||
DoAppSandboxMountOnce(orinwebPath.c_str(), destnwebPath.c_str());
|
||||
|
||||
// do systemres adaption
|
||||
std::string oriSysresPath = "/data/app/el1/bundle/public/ohos.global.systemres";
|
||||
std::string destSysresPath = destInstallPath + "/ohos.global.systemres";
|
||||
chmod(destSysresPath.c_str(), NWEB_FILE_MODE);
|
||||
DoAppSandboxMountOnce(oriSysresPath.c_str(), destSysresPath.c_str());
|
||||
|
||||
if (bundleName.find("medialibrary") != std::string::npos) {
|
||||
std::string oriMediaPath = "/storage/media/" + currentUserId;
|
||||
std::string destMediaPath = rootPath + "/storage/media";
|
||||
DoAppSandboxMountOnce(oriMediaPath.c_str(), destMediaPath.c_str());
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void DoAppSandboxMkdir(const std::string &sandboxPackagePath, const AppParameter &appProperty)
|
||||
{
|
||||
std::vector<std::string> mkdirInfo;
|
||||
std::string dirPath;
|
||||
|
||||
mkdirInfo.push_back("/mnt/");
|
||||
mkdirInfo.push_back("/mnt/hmdfs/");
|
||||
mkdirInfo.push_back("/data/");
|
||||
mkdirInfo.push_back("/storage/");
|
||||
mkdirInfo.push_back("/storage/media");
|
||||
mkdirInfo.push_back("/data/storage");
|
||||
// to create /mnt/sandbox/<packagename>/data/storage/el1 related path, later should delete this code.
|
||||
mkdirInfo.push_back("/data/storage/el1");
|
||||
mkdirInfo.push_back("/data/storage/el1/bundle");
|
||||
mkdirInfo.push_back("/data/storage/el1/base");
|
||||
mkdirInfo.push_back("/data/storage/el1/database");
|
||||
mkdirInfo.push_back("/data/storage/el2");
|
||||
mkdirInfo.push_back("/data/storage/el2/base");
|
||||
mkdirInfo.push_back("/data/storage/el2/database");
|
||||
mkdirInfo.push_back("/data/storage/el2/distributedfiles");
|
||||
mkdirInfo.push_back("/data/storage/el2/auth_groups");
|
||||
// create applications folder for compatibility purpose
|
||||
mkdirInfo.push_back("/data/accounts");
|
||||
mkdirInfo.push_back("/data/accounts/account_0");
|
||||
mkdirInfo.push_back("/data/accounts/account_0/applications/");
|
||||
mkdirInfo.push_back("/data/bundles/");
|
||||
|
||||
for (size_t i = 0; i < mkdirInfo.size(); i++) {
|
||||
dirPath = sandboxPackagePath + mkdirInfo[i];
|
||||
mkdir(dirPath.c_str(), FILE_MODE);
|
||||
}
|
||||
}
|
||||
|
||||
static int32_t DoSandboxRootFolderCreateAdapt(const std::string &sandboxPackagePath)
|
||||
{
|
||||
int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr);
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("set propagation slave failed");
|
||||
return rc;
|
||||
}
|
||||
|
||||
// bind mount "/" to /mnt/sandbox/<packageName> path
|
||||
// rootfs: to do more resources bind mount here to get more strict resources constraints
|
||||
rc = mount("/", sandboxPackagePath.c_str(), nullptr, MS_BIND | MS_REC, nullptr);
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("mount bind / failed");
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int32_t DoSandboxRootFolderCreate(const std::string &sandboxPackagePath)
|
||||
{
|
||||
int rc = mount(nullptr, "/", nullptr, MS_REC | MS_SLAVE, nullptr);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
// bind mount sandboxPackagePath to make it a mount point for pivot_root syscall
|
||||
DoAppSandboxMountOnce(sandboxPackagePath.c_str(), sandboxPackagePath.c_str());
|
||||
|
||||
// do /mnt/sandbox/<packageName> path mkdir
|
||||
std::map<std::string, std::string> mountMap;
|
||||
std::vector<std::string> vecInfo;
|
||||
std::string tmpDir = "";
|
||||
|
||||
vecInfo.push_back("/config");
|
||||
vecInfo.push_back("/dev");
|
||||
vecInfo.push_back("/proc");
|
||||
vecInfo.push_back("/sys");
|
||||
vecInfo.push_back("/sys_prod");
|
||||
vecInfo.push_back("/system");
|
||||
|
||||
for (size_t i = 0; i < vecInfo.size(); i++) {
|
||||
tmpDir = sandboxPackagePath + vecInfo[i];
|
||||
mkdir(tmpDir.c_str(), FILE_MODE);
|
||||
mountMap[vecInfo[i]] = tmpDir;
|
||||
}
|
||||
|
||||
// bind mount root folder to /mnt/sandbox/<packageName> path
|
||||
std::map<std::string, std::string>::iterator iter;
|
||||
for (iter = mountMap.begin(); iter != mountMap.end(); ++iter) {
|
||||
rc = DoAppSandboxMountOnce(iter->first.c_str(), iter->second.c_str());
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("move root folder failed, %s", sandboxPackagePath.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
// to create symlink at /mnt/sandbox/<packageName> path
|
||||
// bin -> /system/bin
|
||||
// d -> /sys/kernel/debug
|
||||
// etc -> /system/etc
|
||||
// init -> /system/bin/init
|
||||
// lib -> /system/lib
|
||||
// sdcard -> /storage/self/primary
|
||||
std::map<std::string, std::string> symlinkMap;
|
||||
symlinkMap["/system/bin"] = sandboxPackagePath + "/bin";
|
||||
symlinkMap["/sys/kernel/debug"] = sandboxPackagePath + "/d";
|
||||
symlinkMap["/system/etc"] = sandboxPackagePath + "/etc";
|
||||
symlinkMap["/system/bin/init"] = sandboxPackagePath + "/init";
|
||||
#ifdef __aarch64__
|
||||
symlinkMap["/system/lib64"] = sandboxPackagePath + "/lib64";
|
||||
#else
|
||||
symlinkMap["/system/lib"] = sandboxPackagePath + "/lib";
|
||||
#endif
|
||||
|
||||
for (iter = symlinkMap.begin(); iter != symlinkMap.end(); ++iter) {
|
||||
symlink(iter->first.c_str(), iter->second.c_str());
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void MatchSandbox(AppSpawnClientExt *appProperty)
|
||||
{
|
||||
if (appProperty == nullptr) {
|
||||
@ -349,66 +129,9 @@ static void MatchSandbox(AppSpawnClientExt *appProperty)
|
||||
|
||||
int32_t SetAppSandboxProperty(struct AppSpawnContent_ *content, AppSpawnClient *client)
|
||||
{
|
||||
int rc = 0;
|
||||
APPSPAWN_CHECK(client != NULL, return -1, "Invalid appspwn client");
|
||||
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
|
||||
MatchSandbox(appProperty);
|
||||
// create /mnt/sandbox/<packagename> path<74>?later put it to rootfs module
|
||||
std::string sandboxPackagePath = "/";
|
||||
sandboxPackagePath += appProperty->property.bundleName;
|
||||
mkdir(sandboxPackagePath.c_str(), FILE_MODE);
|
||||
|
||||
// add pid to a new mnt namespace
|
||||
rc = unshare(CLONE_NEWNS);
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("unshare failed, packagename is %s", appProperty->property.processName);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// to make wargnar work
|
||||
if (access("/3rdmodem", F_OK) == 0) {
|
||||
rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath);
|
||||
} else {
|
||||
rc = DoSandboxRootFolderCreate(sandboxPackagePath);
|
||||
}
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("DoSandboxRootFolderCreate failed, %s", appProperty->property.processName);
|
||||
return rc;
|
||||
}
|
||||
|
||||
// to create /mnt/sandbox/<packagename>/data/storage related path
|
||||
DoAppSandboxMkdir(sandboxPackagePath, appProperty->property);
|
||||
|
||||
rc = DoAppSandboxMount(appProperty->property, sandboxPackagePath);
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("DoAppSandboxMount failed, packagename is %s", appProperty->property.processName);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = DoAppSandboxMountCustomized(appProperty->property, sandboxPackagePath);
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("DoAppSandboxMountCustomized failed, packagename is %s", appProperty->property.processName);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = chdir(sandboxPackagePath.c_str());
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("chdir failed, packagename is %s, path is %s", \
|
||||
appProperty->property.processName, sandboxPackagePath.c_str());
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str());
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("pivot root failed, packagename is %s, errno is %d", \
|
||||
appProperty->property.processName, errno);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = umount2(".", MNT_DETACH);
|
||||
if (rc) {
|
||||
APPSPAWN_LOGE("MNT_DETACH failed, packagename is %s", appProperty->property.processName);
|
||||
return rc;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return SandboxUtils::SetAppSandboxProperty(&appProperty->property);
|
||||
}
|
||||
|
189
appdata-sandbox.json
Normal file
189
appdata-sandbox.json
Normal file
@ -0,0 +1,189 @@
|
||||
{
|
||||
"common" : [{
|
||||
"top-sandbox-switch": "ON",
|
||||
"app-base" : [{
|
||||
"sandbox-root" : "/mnt/sandbox/<PackageName>",
|
||||
"mount-bind-paths" : [{
|
||||
"src-path" : "/config",
|
||||
"sandbox-path" : "/config",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/dev",
|
||||
"sandbox-path" : "/dev",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/proc",
|
||||
"sandbox-path" : "/proc",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/sys",
|
||||
"sandbox-path" : "/sys",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/sys_prod",
|
||||
"sandbox-path" : "/sys_prod",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/system",
|
||||
"sandbox-path" : "/system",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/data/app/el1/bundle/public/<PackageName>",
|
||||
"sandbox-path" : "/data/storage/el1/bundle",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/data/app/el2/<currentUserId>/base/<PackageName>",
|
||||
"sandbox-path" : "/data/storage/el2/base",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/data/app/el2/<currentUserId>/database/<PackageName>",
|
||||
"sandbox-path" : "/data/storage/el2/database",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/data/app/el1/<currentUserId>/base/<PackageName>",
|
||||
"sandbox-path" : "/data/storage/el1/base",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/mnt/hmdfs/",
|
||||
"sandbox-path" : "/mnt/hmdfs/",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "false"
|
||||
}, {
|
||||
"src-path" : "/mnt/hmdfs/<currentUserId>/account/merge_view/data/<PackageName>",
|
||||
"sandbox-path" : "/data/storage/el2/distributedfiles",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "false"
|
||||
}, {
|
||||
"src-path" : "/mnt/hmdfs/<currentUserId>/non_account/merge_view/data/",
|
||||
"sandbox-path" : "/data/storage/el2/auth_groups",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "false"
|
||||
}, {
|
||||
"src-path" : "/data/app/el1/bundle/public/com.ohos.nweb",
|
||||
"sandbox-path" : "/data/storage/el1/bundle/nweb",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "false"
|
||||
}, {
|
||||
"src-path" : "/data/app/el1/bundle/public/ohos.global.systemres",
|
||||
"sandbox-path" : "/data/storage/el1/bundle/ohos.global.systemres",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "false"
|
||||
}
|
||||
],
|
||||
"symbol-links" : [{
|
||||
"target-name" : "/system/bin",
|
||||
"link-name" : "/bin",
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"target-name" : "/system/lib",
|
||||
"link-name" : "/lib",
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"target-name" : "/system/etc",
|
||||
"link-name" : "/etc",
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"target-name" : "/system/bin/init",
|
||||
"link-name" : "/init",
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"target-name" : "/sys/kernel/debug",
|
||||
"link-name" : "/d",
|
||||
"check-action-status": "true"
|
||||
}
|
||||
]
|
||||
}],
|
||||
"app-resources" : [{
|
||||
"sandbox-root" : "/mnt/sandbox/<PackageName>",
|
||||
"mount-bind-paths" : [{
|
||||
"src-path" : "/data/app/el1/bundle/public/com.ohos.nweb",
|
||||
"sandbox-path" : "/data/storage/el1/bundle/nweb",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "false"
|
||||
}, {
|
||||
"src-path" : "/data/app/el1/bundle/public/ohos.global.systemres",
|
||||
"sandbox-path" : "/data/storage/el1/bundle/ohos.global.systemres",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "false"
|
||||
}
|
||||
],
|
||||
"symbol-links" : [
|
||||
]
|
||||
}]
|
||||
}],
|
||||
"individual" : [{
|
||||
"com.ohos.medialibrary.MediaLibraryDataA" : [{
|
||||
"sandbox-switch": "ON",
|
||||
"sandbox-root" : "/mnt/sandbox/<PackageName>",
|
||||
"mount-bind-paths" : [{
|
||||
"src-path" : "/storage/media/<currentUserId>",
|
||||
"sandbox-path" : "/storage/media",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "false"
|
||||
}
|
||||
],
|
||||
"symbol-links" : []
|
||||
}],
|
||||
"com.ohos.launcher" : [{
|
||||
"sandbox-switch": "ON",
|
||||
"sandbox-root" : "/mnt/sandbox/<PackageName>",
|
||||
"mount-bind-paths" : [{
|
||||
"src-path" : "/data/app/el1/bundle/public/",
|
||||
"sandbox-path" : "/data/accounts/account_0/applications/",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/data/app/el1/bundle/public/",
|
||||
"sandbox-path" : "/data/bundles/",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}
|
||||
],
|
||||
"symbol-links" : []
|
||||
}],
|
||||
"com.ohos.permissionmanager" : [{
|
||||
"sandbox-switch": "ON",
|
||||
"sandbox-root" : "/mnt/sandbox/<PackageName>",
|
||||
"mount-bind-paths" : [{
|
||||
"src-path" : "/data/app/el1/bundle/public/",
|
||||
"sandbox-path" : "/data/accounts/account_0/applications/",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/data/app/el1/bundle/public/",
|
||||
"sandbox-path" : "/data/bundles/",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}
|
||||
],
|
||||
"symbol-links" : []
|
||||
}],
|
||||
"ohos.samples.ecg" : [{
|
||||
"sandbox-switch": "OFF",
|
||||
"sandbox-root" : "/mnt/sandbox/<PackageName>",
|
||||
"mount-bind-paths" : [{
|
||||
"src-path" : "/data/app/el1/bundle/public/",
|
||||
"sandbox-path" : "/data/accounts/account_0/applications/",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}, {
|
||||
"src-path" : "/data/app/el1/bundle/public/",
|
||||
"sandbox-path" : "/data/bundles/",
|
||||
"sandbox-flags" : [ "bind", "rec" ],
|
||||
"check-action-status": "true"
|
||||
}
|
||||
],
|
||||
"symbol-links" : []
|
||||
}]
|
||||
}]
|
||||
}
|
@ -32,6 +32,7 @@
|
||||
#include "appspawn_adapter.h"
|
||||
#include "securec.h"
|
||||
|
||||
|
||||
#define DEVICE_NULL_STR "/dev/null"
|
||||
|
||||
static int SetProcessName(struct AppSpawnContent_ *content, AppSpawnClient *client,
|
||||
|
@ -14,6 +14,7 @@
|
||||
*/
|
||||
|
||||
#include "appspawn_service.h"
|
||||
#include "appspawn_adapter.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/capability.h>
|
||||
@ -352,6 +353,9 @@ static void AppSpawnInit(AppSpawnContent *content)
|
||||
content->notifyResToParent = NotifyResToParent;
|
||||
// set private function
|
||||
SetContentFunction(content);
|
||||
|
||||
// load app sandbox config
|
||||
LoadAppSandboxConfig();
|
||||
}
|
||||
|
||||
void AppSpawnColdRun(AppSpawnContent *content, int argc, char *const argv[])
|
||||
|
@ -39,6 +39,7 @@ config("appspawn_test_config") {
|
||||
"${appspawn_path}/test/mock/include",
|
||||
"${appspawn_path}/common",
|
||||
"${appspawn_path}/interfaces/innerkits/include",
|
||||
"${appspawn_path}/util/include",
|
||||
]
|
||||
}
|
||||
|
||||
|
37
util/include/json_utils.h
Normal file
37
util/include/json_utils.h
Normal file
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef JSON_UTILS_H
|
||||
#define JSON_UTILS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "nlohmann/json.hpp"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AppSpawn {
|
||||
class JsonUtils {
|
||||
public:
|
||||
static bool GetJsonObjFromJson(nlohmann::json& jsonObj, const std::string& jsonPath);
|
||||
static bool GetStringFromJson(const nlohmann::json& json, const std::string& key, std::string& value);
|
||||
static bool GetIntFromJson(const nlohmann::json& json, const std::string& key, int& value);
|
||||
static bool GetStringVecFromJson(
|
||||
const nlohmann::json& json, const std::string& key, std::vector<std::string>& value);
|
||||
static bool ParseObjVecFromJson(
|
||||
const nlohmann::json& json, const std::string& key, std::vector<nlohmann::json>& value);
|
||||
};
|
||||
} // namespace AppSpawn
|
||||
} // namespace OHOS
|
||||
#endif // JSON_UTILS_H
|
45
util/include/parcel_util.h
Normal file
45
util/include/parcel_util.h
Normal file
@ -0,0 +1,45 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef PACEL_UTIL_H
|
||||
#define PACEL_UTIL_H
|
||||
|
||||
#include <cstdint>
|
||||
#include <list>
|
||||
#include "parcel.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AppSpawn {
|
||||
template<class T>
|
||||
std::vector<T> TranslateListToVector(const std::list<T> &originList)
|
||||
{
|
||||
std::size_t len = originList.size();
|
||||
std::vector<T> destVector(len);
|
||||
std::copy(originList.begin(), originList.end(), destVector.begin());
|
||||
return destVector;
|
||||
}
|
||||
|
||||
template<class T>
|
||||
std::list<T> TranslateVectorToList(const std::vector<T> &originVector)
|
||||
{
|
||||
int len = originVector.length();
|
||||
std::list<T> destList(len);
|
||||
std::copy(originVector.begin(), originVector.end(), destList.begin());
|
||||
return destList;
|
||||
}
|
||||
} // namespace AppSpawn
|
||||
} // namespace OHOS
|
||||
|
||||
#endif // PACEL_UTIL_H
|
64
util/include/sandbox_utils.h
Normal file
64
util/include/sandbox_utils.h
Normal file
@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef SANDBOX_UTILS_H
|
||||
#define SANDBOX_UTILS_H
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <sys/types.h>
|
||||
#include "nlohmann/json.hpp"
|
||||
#include "client_socket.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace AppSpawn {
|
||||
class SandboxUtils {
|
||||
public:
|
||||
static void StoreJsonConfig(nlohmann::json &appSandboxConfig);
|
||||
static nlohmann::json GetJsonConfig();
|
||||
static int32_t SetAppSandboxProperty(const ClientSocket::AppProperty *appProperty);
|
||||
|
||||
private:
|
||||
static void MakeDirRecursive(const std::string path, mode_t mode);
|
||||
static int32_t DoAppSandboxMountOnce(const std::string originPath, const std::string destinationPath,
|
||||
unsigned long mountFlags);
|
||||
static int32_t DoSandboxFileCommonBind(const ClientSocket::AppProperty *appProperty, nlohmann::json &wholeConfig);
|
||||
static int32_t DoSandboxFileCommonSymlink(const ClientSocket::AppProperty *appProperty,
|
||||
nlohmann::json &wholeConfig);
|
||||
static int32_t DoSandboxFilePrivateBind(const ClientSocket::AppProperty *appProperty, nlohmann::json &wholeConfig);
|
||||
static int32_t DoSandboxFilePrivateSymlink(const ClientSocket::AppProperty *appProperty,
|
||||
nlohmann::json &wholeConfig);
|
||||
static int32_t SetPrivateAppSandboxProperty(const ClientSocket::AppProperty *appProperty);
|
||||
static int32_t SetCommonAppSandboxProperty(const ClientSocket::AppProperty *appProperty,
|
||||
std::string &sandboxPackagePath);
|
||||
static int32_t DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath);
|
||||
static int32_t DoSandboxRootFolderCreate(const ClientSocket::AppProperty *appProperty,
|
||||
std::string &sandboxPackagePath);
|
||||
static void DoSandboxChmod(nlohmann::json jsonConfig, std::string &sandboxRoot);
|
||||
static int DoAllMntPointsMount(const ClientSocket::AppProperty *appProperty, nlohmann::json &appConfig);
|
||||
static int DoAllSymlinkPointslink(const ClientSocket::AppProperty *appProperty, nlohmann::json &appConfig);
|
||||
static std::string ConvertToRealPath(const ClientSocket::AppProperty *appProperty, std::string sandboxRoot);
|
||||
static std::string GetSbxPathByConfig(const ClientSocket::AppProperty *appProperty, nlohmann::json &config);
|
||||
static bool CheckTotalSandboxSwitchStatus(const ClientSocket::AppProperty *appProperty);
|
||||
static bool CheckAppSandboxSwitchStatus(const ClientSocket::AppProperty *appProperty);
|
||||
static bool GetSbxSwitchStatusByConfig(nlohmann::json &config);
|
||||
static unsigned long GetMountFlagsFromConfig(const std::vector<std::string> &vec);
|
||||
|
||||
private:
|
||||
static nlohmann::json appSandboxConfig_;
|
||||
};
|
||||
} // namespace AppSpawn
|
||||
} // namespace OHOS
|
||||
#endif // SANDBOX_UTILS_H
|
119
util/src/json_utils.cpp
Normal file
119
util/src/json_utils.cpp
Normal file
@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "json_utils.h"
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
#include "hilog/log.h"
|
||||
|
||||
using namespace std;
|
||||
using namespace OHOS;
|
||||
using namespace OHOS::HiviewDFX;
|
||||
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawn_JsonUtil"};
|
||||
|
||||
namespace OHOS {
|
||||
namespace AppSpawn {
|
||||
bool JsonUtils::GetJsonObjFromJson(nlohmann::json &jsonObj, const std::string &jsonPath)
|
||||
{
|
||||
if (jsonPath.length() > PATH_MAX) {
|
||||
HiLog::Error(LABEL, "jsonPath is too long");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ifstream jsonFileStream;
|
||||
jsonFileStream.open(jsonPath.c_str(), std::ios::in);
|
||||
if (!jsonFileStream.is_open()) {
|
||||
HiLog::Error(LABEL, "Open json file failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::ostringstream buf;
|
||||
char ch;
|
||||
while (buf && jsonFileStream.get(ch)) {
|
||||
buf.put(ch);
|
||||
}
|
||||
jsonFileStream.close();
|
||||
|
||||
jsonObj = nlohmann::json::parse(buf.str(), nullptr, false);
|
||||
if (!jsonObj.is_structured()) {
|
||||
HiLog::Error(LABEL, "Parse json file into jsonObj failed.");
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool JsonUtils::GetStringFromJson(const nlohmann::json &json, const std::string &key, std::string &value)
|
||||
{
|
||||
if (!json.is_object()) {
|
||||
HiLog::Error(LABEL, "json is not object.");
|
||||
return false;
|
||||
}
|
||||
if (json.find(key) != json.end() && json.at(key).is_string()) {
|
||||
HiLog::Error(LABEL, "Find key[%{public}s] successful.", key.c_str());
|
||||
value = json.at(key).get<std::string>();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JsonUtils::GetIntFromJson(const nlohmann::json &json, const std::string &key, int &value)
|
||||
{
|
||||
if (!json.is_object()) {
|
||||
HiLog::Error(LABEL, "json is not object.");
|
||||
return false;
|
||||
}
|
||||
if (json.find(key) != json.end() && json.at(key).is_number()) {
|
||||
HiLog::Error(LABEL, "Find key[%{public}s] successful.", key.c_str());
|
||||
value = json.at(key).get<int>();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JsonUtils::GetStringVecFromJson(const nlohmann::json &json, const std::string &key,
|
||||
std::vector<std::string> &value)
|
||||
{
|
||||
if (!json.is_object()) {
|
||||
HiLog::Error(LABEL, "json is not object.");
|
||||
return false;
|
||||
}
|
||||
if (json.find(key) != json.end() && json.at(key).is_array()) {
|
||||
HiLog::Error(LABEL, "Find key[%{public}s] successful.", key.c_str());
|
||||
value = json.at(key).get<std::vector<std::string>>();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool JsonUtils::ParseObjVecFromJson(const nlohmann::json &json, const std::string &key,
|
||||
std::vector<nlohmann::json> &value)
|
||||
{
|
||||
if (!json.is_object()) {
|
||||
HiLog::Error(LABEL, "json is not object.");
|
||||
return false;
|
||||
}
|
||||
if (json.find(key) != json.end() && json.at(key).is_array()) {
|
||||
HiLog::Error(LABEL, "Find key[%{public}s] successful.", key.c_str());
|
||||
value = json.at(key).get<std::vector<nlohmann::json>>();
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} // namespace AppSpawn
|
||||
} // namespace OHOS
|
579
util/src/sandbox_utils.cpp
Normal file
579
util/src/sandbox_utils.cpp
Normal file
@ -0,0 +1,579 @@
|
||||
/*
|
||||
* Copyright (C) 2022 Huawei Device Co., Ltd.
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "sandbox_utils.h"
|
||||
#include "json_utils.h"
|
||||
#include "hilog/log.h"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/wait.h>
|
||||
#include <sys/mount.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <cerrno>
|
||||
#include <dirent.h>
|
||||
#include <dlfcn.h>
|
||||
#include <fstream>
|
||||
#include <sstream>
|
||||
|
||||
using namespace std;
|
||||
using namespace OHOS;
|
||||
using namespace OHOS::HiviewDFX;
|
||||
static constexpr HiLogLabel LABEL = {LOG_CORE, 0, "AppSpawn_SandboxUtil"};
|
||||
|
||||
namespace OHOS {
|
||||
namespace AppSpawn {
|
||||
namespace {
|
||||
constexpr int32_t UID_BASE = 200000;
|
||||
constexpr static mode_t FILE_MODE = 0711;
|
||||
constexpr static mode_t BASIC_MOUNT_FLAGS = MS_REC | MS_BIND;
|
||||
constexpr std::string_view APL_SYSTEM_CORE("system_core");
|
||||
constexpr std::string_view APL_SYSTEM_BASIC("system_basic");
|
||||
const std::string PHYSICAL_APP_INSTALL_PATH = "/data/app/el1/bundle/public/";
|
||||
const std::string SANDBOX_APP_INSTALL_PATH = "/data/accounts/account_0/applications/";
|
||||
const std::string DATA_BUNDLES = "/data/bundles/";
|
||||
const std::string USERID = "<currentUserId>";
|
||||
const std::string PACKAGE_NAME = "<PackageName>";
|
||||
const std::string SANDBOX_DIR = "/mnt/sandbox/";
|
||||
const std::string STATUS_CHECK = "true";
|
||||
const std::string SBX_SWITCH_CHECK = "ON";
|
||||
const char *COMMON_PREFIX = "common";
|
||||
const char *PRIVATE_PREFIX = "individual";
|
||||
const char *SRC_PATH = "src-path";
|
||||
const char *SANDBOX_PATH = "sandbox-path";
|
||||
const char *SANDBOX_FLAGS = "sandbox-flags";
|
||||
const char *DEST_MODE = "dest-mode";
|
||||
const char *ACTION_STATUS = "check-action-status";
|
||||
const char *TARGET_NAME = "target-name";
|
||||
const char *LINK_NAME = "link-name";
|
||||
const char *MOUNT_PREFIX = "mount-bind-paths";
|
||||
const char *SANDBOX_SWITCH_PREFIX = "sandbox-switch";
|
||||
const char *TOP_SANDBOX_SWITCH_PREFIX = "top-sandbox-switch";
|
||||
const char *SYMLINK_PREFIX = "symbol-links";
|
||||
const char *SANDBOX_ROOT_PREFIX = "sandbox-root";
|
||||
const char *WARGNAR_DEVICE_PATH = "/3rdmodem";
|
||||
const char *APP_BASE = "app-base";
|
||||
const char *APP_RESOURCES = "app-resources";
|
||||
}
|
||||
|
||||
|
||||
nlohmann::json SandboxUtils::appSandboxConfig_;
|
||||
|
||||
void SandboxUtils::StoreJsonConfig(nlohmann::json &appSandboxConfig)
|
||||
{
|
||||
SandboxUtils::appSandboxConfig_ = appSandboxConfig;
|
||||
}
|
||||
|
||||
nlohmann::json SandboxUtils::GetJsonConfig()
|
||||
{
|
||||
return SandboxUtils::appSandboxConfig_;
|
||||
}
|
||||
|
||||
void SandboxUtils::MakeDirRecursive(const std::string path, mode_t mode)
|
||||
{
|
||||
size_t size = path.size();
|
||||
if (size == 0)
|
||||
return;
|
||||
|
||||
size_t index = 0;
|
||||
do {
|
||||
size_t pathIndex = path.find_first_of('/', index);
|
||||
index = pathIndex == std::string::npos ? size : pathIndex + 1;
|
||||
std::string dir = path.substr(0, index);
|
||||
if (access(dir.c_str(), F_OK) < 0 && mkdir(dir.c_str(), mode) < 0) {
|
||||
HiLog::Error(LABEL, "mkdir %{public}s error", dir.c_str());
|
||||
return;
|
||||
}
|
||||
} while (index < size);
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::DoAppSandboxMountOnce(const std::string originPath, const std::string destinationPath,
|
||||
unsigned long mountFlags)
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
// To make sure destinationPath exist
|
||||
MakeDirRecursive(destinationPath, FILE_MODE);
|
||||
|
||||
ret = mount(originPath.c_str(), destinationPath.c_str(), NULL, mountFlags, NULL);
|
||||
if (ret) {
|
||||
HiLog::Error(LABEL, "bind mount %{public}s to %{public}s failed %{public}d", originPath.c_str(),
|
||||
destinationPath.c_str(), errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mount(NULL, destinationPath.c_str(), NULL, MS_PRIVATE, NULL);
|
||||
if (ret) {
|
||||
HiLog::Error(LABEL, "private mount to %{public}s failed %{public}d", destinationPath.c_str(), errno);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static std::string& replace_all(std::string& str, const std::string& old_value, const std::string& new_value)
|
||||
{
|
||||
while (true) {
|
||||
std::string::size_type pos(0);
|
||||
if ((pos = str.find(old_value)) != std::string::npos)
|
||||
str.replace(pos, old_value.length(), new_value);
|
||||
else break;
|
||||
}
|
||||
return str;
|
||||
}
|
||||
|
||||
static std::vector<std::string> split(std::string &str, const std::string &pattern)
|
||||
{
|
||||
std::string::size_type pos;
|
||||
std::vector<std::string> result;
|
||||
str += pattern;
|
||||
size_t size = str.size();
|
||||
|
||||
for (int i = 0; i < int(size); i++) {
|
||||
pos = str.find(pattern, i);
|
||||
if (pos < size) {
|
||||
std::string s = str.substr(i, pos - i);
|
||||
result.push_back(s);
|
||||
i = pos + pattern.size() - 1;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
void SandboxUtils::DoSandboxChmod(nlohmann::json jsonConfig, std::string &sandboxRoot)
|
||||
{
|
||||
const std::map<std::string, mode_t> modeMap = {{"S_IRUSR", S_IRUSR}, {"S_IWUSR", S_IWUSR}, {"S_IXUSR", S_IXUSR},
|
||||
{"S_IRGRP", S_IRGRP}, {"S_IWGRP", S_IWGRP}, {"S_IXGRP", S_IXGRP},
|
||||
{"S_IROTH", S_IROTH}, {"S_IWOTH", S_IWOTH}, {"S_IXOTH", S_IXOTH},
|
||||
{"S_IRWXU", S_IRWXU}, {"S_IRWXG", S_IRWXG}, {"S_IRWXO", S_IRWXO}};
|
||||
std::string fileModeStr;
|
||||
mode_t mode = 0;
|
||||
|
||||
bool rc = JsonUtils::GetStringFromJson(jsonConfig, DEST_MODE, fileModeStr);
|
||||
if (rc == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> modeVec = split(fileModeStr, "|");
|
||||
for (unsigned int i = 0; i < modeVec.size(); i++) {
|
||||
if (modeMap.count(modeVec[i])) {
|
||||
mode |= modeMap.at(modeVec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
chmod(sandboxRoot.c_str(), mode);
|
||||
}
|
||||
|
||||
unsigned long SandboxUtils::GetMountFlagsFromConfig(const std::vector<std::string> &vec)
|
||||
{
|
||||
const std::map<std::string, mode_t> MountFlagsMap = { {"rec", MS_REC}, {"MS_REC", MS_REC},
|
||||
{"bind", MS_BIND}, {"MS_BIND", MS_BIND},
|
||||
{"move", MS_MOVE}, {"MS_MOVE", MS_MOVE},
|
||||
{"slave", MS_SLAVE}, {"MS_SLAVE", MS_SLAVE},
|
||||
{"rdonly", MS_RDONLY}, {"MS_RDONLY", MS_RDONLY},
|
||||
{"shared", MS_SHARED}, {"MS_SHARED", MS_SHARED},
|
||||
{"unbindable", MS_UNBINDABLE},
|
||||
{"MS_UNBINDABLE", MS_UNBINDABLE},
|
||||
{"remount", MS_REMOUNT}, {"MS_REMOUNT", MS_REMOUNT}};
|
||||
unsigned long mountFlags = 0;
|
||||
|
||||
for (unsigned int i = 0; i < vec.size(); i++) {
|
||||
if (MountFlagsMap.count(vec[i])) {
|
||||
mountFlags |= MountFlagsMap.at(vec[i]);
|
||||
}
|
||||
}
|
||||
|
||||
return mountFlags;
|
||||
}
|
||||
|
||||
string SandboxUtils::ConvertToRealPath(const ClientSocket::AppProperty *appProperty, std::string path)
|
||||
{
|
||||
if (path.find(PACKAGE_NAME) != -1) {
|
||||
path = replace_all(path, PACKAGE_NAME, appProperty->bundleName);
|
||||
}
|
||||
|
||||
if (path.find(USERID) != -1) {
|
||||
path = replace_all(path, USERID, std::to_string(appProperty->uid / UID_BASE));
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
|
||||
std::string SandboxUtils::GetSbxPathByConfig(const ClientSocket::AppProperty *appProperty, nlohmann::json &config)
|
||||
{
|
||||
std::string sandboxRoot = "";
|
||||
if (config.find(SANDBOX_ROOT_PREFIX) != config.end()) {
|
||||
sandboxRoot = config[SANDBOX_ROOT_PREFIX].get<std::string>();
|
||||
sandboxRoot = ConvertToRealPath(appProperty, sandboxRoot);
|
||||
} else {
|
||||
sandboxRoot = SANDBOX_DIR + appProperty->bundleName;
|
||||
HiLog::Error(LABEL, "read sandbox-root config failed, set sandbox-root to default root"
|
||||
"app name is %{public}s", appProperty->bundleName);
|
||||
}
|
||||
|
||||
return sandboxRoot;
|
||||
}
|
||||
|
||||
bool SandboxUtils::GetSbxSwitchStatusByConfig(nlohmann::json &config)
|
||||
{
|
||||
if (config.find(SANDBOX_SWITCH_PREFIX) != config.end()) {
|
||||
std::string switchStatus = config[SANDBOX_SWITCH_PREFIX].get<std::string>();
|
||||
if (switchStatus == SBX_SWITCH_CHECK) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// if not find sandbox-switch node, default switch status is true
|
||||
return true;
|
||||
}
|
||||
|
||||
int SandboxUtils::DoAllMntPointsMount(const ClientSocket::AppProperty *appProperty, nlohmann::json &appConfig)
|
||||
{
|
||||
if (appConfig.find(MOUNT_PREFIX) == appConfig.end()) {
|
||||
HiLog::Debug(LABEL, "mount config is not found, maybe reuslt sandbox launch failed"
|
||||
"app name is %{public}s", appProperty->bundleName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nlohmann::json mountPoints = appConfig[MOUNT_PREFIX];
|
||||
std::string sandboxRoot = GetSbxPathByConfig(appProperty, appConfig);
|
||||
int mountPointSize = mountPoints.size();
|
||||
|
||||
for (int i = 0; i < mountPointSize; i++) {
|
||||
nlohmann::json mntPoint = mountPoints[i];
|
||||
|
||||
// Check the validity of the mount configuration
|
||||
if (mntPoint.find(SRC_PATH) == mntPoint.end() || mntPoint.find(SANDBOX_PATH) == mntPoint.end()
|
||||
|| mntPoint.find(SANDBOX_FLAGS) == mntPoint.end()) {
|
||||
HiLog::Error(LABEL, "read mount config failed, app name is %{public}s", appProperty->bundleName);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string srcPath = ConvertToRealPath(appProperty, mntPoint[SRC_PATH].get<std::string>());
|
||||
std::string sandboxPath = sandboxRoot + ConvertToRealPath(appProperty,
|
||||
mntPoint[SANDBOX_PATH].get<std::string>());
|
||||
unsigned long mountFlags = GetMountFlagsFromConfig(mntPoint[SANDBOX_FLAGS].get<std::vector<std::string>>());
|
||||
|
||||
int ret = DoAppSandboxMountOnce(srcPath.c_str(), sandboxPath.c_str(), mountFlags);
|
||||
if (ret) {
|
||||
HiLog::Error(LABEL, "DoAppSandboxMountOnce failed, %{public}s", sandboxPath.c_str());
|
||||
|
||||
std::string actionStatus = STATUS_CHECK;
|
||||
(void)JsonUtils::GetStringFromJson(mntPoint, ACTION_STATUS, actionStatus);
|
||||
if (actionStatus == STATUS_CHECK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
DoSandboxChmod(mntPoint, sandboxRoot);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SandboxUtils::DoAllSymlinkPointslink(const ClientSocket::AppProperty *appProperty, nlohmann::json &appConfig)
|
||||
{
|
||||
if (appConfig.find(SYMLINK_PREFIX) == appConfig.end()) {
|
||||
HiLog::Debug(LABEL, "symlink config is not found, maybe reuslt sandbox launch failed"
|
||||
"app name is %{public}s", appProperty->bundleName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
nlohmann::json symlinkPoints = appConfig[SYMLINK_PREFIX];
|
||||
std::string sandboxRoot = GetSbxPathByConfig(appProperty, appConfig);
|
||||
int symlinkPointSize = symlinkPoints.size();
|
||||
|
||||
for (int i = 0; i < symlinkPointSize; i++) {
|
||||
nlohmann::json symPoint = symlinkPoints[i];
|
||||
|
||||
// Check the validity of the symlink configuration
|
||||
if (symPoint.find(TARGET_NAME) == symPoint.end() || symPoint.find(LINK_NAME) == symPoint.end()) {
|
||||
HiLog::Error(LABEL, "read symlink config failed, app name is %{public}s", appProperty->bundleName);
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string targetName = ConvertToRealPath(appProperty, symPoint[TARGET_NAME].get<std::string>());
|
||||
std::string linkName = sandboxRoot + ConvertToRealPath(appProperty, symPoint[LINK_NAME].get<std::string>());
|
||||
HiLog::Debug(LABEL, "symlink, from %{public}s to %{public}s", targetName.c_str(), linkName.c_str());
|
||||
|
||||
int ret = symlink(targetName.c_str(), linkName.c_str());
|
||||
if (ret && errno != EEXIST) {
|
||||
HiLog::Error(LABEL, "symlink failed, %{public}s, errno is %{public}d", linkName.c_str(), errno);
|
||||
|
||||
std::string actionStatus = STATUS_CHECK;
|
||||
(void)JsonUtils::GetStringFromJson(symPoint, ACTION_STATUS, actionStatus);
|
||||
if (actionStatus == STATUS_CHECK) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
DoSandboxChmod(symPoint, sandboxRoot);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::DoSandboxFilePrivateBind(const ClientSocket::AppProperty *appProperty,
|
||||
nlohmann::json &wholeConfig)
|
||||
{
|
||||
nlohmann::json privateAppConfig = wholeConfig[PRIVATE_PREFIX][0];
|
||||
if (privateAppConfig.find(appProperty->bundleName) != privateAppConfig.end()) {
|
||||
return DoAllMntPointsMount(appProperty, privateAppConfig[appProperty->bundleName][0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::DoSandboxFilePrivateSymlink(const ClientSocket::AppProperty *appProperty,
|
||||
nlohmann::json &wholeConfig)
|
||||
{
|
||||
nlohmann::json privateAppConfig = wholeConfig[PRIVATE_PREFIX][0];
|
||||
if (privateAppConfig.find(appProperty->bundleName) != privateAppConfig.end()) {
|
||||
return DoAllSymlinkPointslink(appProperty, privateAppConfig[appProperty->bundleName][0]);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::DoSandboxFileCommonBind(const ClientSocket::AppProperty *appProperty, nlohmann::json &wholeConfig)
|
||||
{
|
||||
nlohmann::json commonConfig = wholeConfig[COMMON_PREFIX][0];
|
||||
int ret = 0;
|
||||
|
||||
if (commonConfig.find(APP_BASE) != commonConfig.end()) {
|
||||
ret = DoAllMntPointsMount(appProperty, commonConfig[APP_BASE][0]);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (commonConfig.find(APP_RESOURCES) != commonConfig.end()) {
|
||||
ret = DoAllMntPointsMount(appProperty, commonConfig[APP_RESOURCES][0]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::DoSandboxFileCommonSymlink(const ClientSocket::AppProperty *appProperty,
|
||||
nlohmann::json &wholeConfig)
|
||||
{
|
||||
nlohmann::json commonConfig = wholeConfig[COMMON_PREFIX][0];
|
||||
int ret = 0;
|
||||
|
||||
if (commonConfig.find(APP_BASE) != commonConfig.end()) {
|
||||
ret = DoAllSymlinkPointslink(appProperty, commonConfig[APP_BASE][0]);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (commonConfig.find(APP_RESOURCES) != commonConfig.end()) {
|
||||
ret = DoAllSymlinkPointslink(appProperty, commonConfig[APP_RESOURCES][0]);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::SetPrivateAppSandboxProperty(const ClientSocket::AppProperty *appProperty)
|
||||
{
|
||||
nlohmann::json config = SandboxUtils::GetJsonConfig();
|
||||
int ret;
|
||||
|
||||
ret = DoSandboxFilePrivateBind(appProperty, config);
|
||||
if (ret) {
|
||||
HiLog::Error(LABEL, "DoSandboxFilePrivateBind failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = DoSandboxFilePrivateSymlink(appProperty, config);
|
||||
if (ret) {
|
||||
HiLog::Error(LABEL, "DoSandboxFilePrivateSymlink failed");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::SetCommonAppSandboxProperty(const ClientSocket::AppProperty *appProperty,
|
||||
std::string &sandboxPackagePath)
|
||||
{
|
||||
nlohmann::json jsonConfig = SandboxUtils::GetJsonConfig();
|
||||
|
||||
int rc = DoSandboxFileCommonBind(appProperty, jsonConfig);
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "DoSandboxFileCommonBind failed, %{public}s", sandboxPackagePath.c_str());
|
||||
return rc;
|
||||
}
|
||||
|
||||
// if sandbox switch is off, don't do symlink work again
|
||||
if (CheckAppSandboxSwitchStatus(appProperty) == true && (CheckTotalSandboxSwitchStatus(appProperty) == true)) {
|
||||
rc = DoSandboxFileCommonSymlink(appProperty, jsonConfig);
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "DoSandboxFileCommonSymlink failed, %{public}s", sandboxPackagePath.c_str());
|
||||
return rc;
|
||||
}
|
||||
}
|
||||
|
||||
if (strcmp(appProperty->apl, APL_SYSTEM_BASIC.data()) == 0 ||
|
||||
strcmp(appProperty->apl, APL_SYSTEM_CORE.data()) == 0) {
|
||||
// account_0/applications/ dir can still access other packages' data now for compatibility purpose
|
||||
std::string destapplicationsPath = sandboxPackagePath + SANDBOX_APP_INSTALL_PATH;
|
||||
DoAppSandboxMountOnce(PHYSICAL_APP_INSTALL_PATH.c_str(), destapplicationsPath.c_str(), BASIC_MOUNT_FLAGS);
|
||||
|
||||
// need permission check for system app here
|
||||
std::string destbundlesPath = sandboxPackagePath + DATA_BUNDLES;
|
||||
DoAppSandboxMountOnce(PHYSICAL_APP_INSTALL_PATH.c_str(), destbundlesPath.c_str(), BASIC_MOUNT_FLAGS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::DoSandboxRootFolderCreateAdapt(std::string &sandboxPackagePath)
|
||||
{
|
||||
int rc = mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL);
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "set propagation slave failed");
|
||||
return rc;
|
||||
}
|
||||
|
||||
MakeDirRecursive(sandboxPackagePath, FILE_MODE);
|
||||
|
||||
// bind mount "/" to /mnt/sandbox/<packageName> path
|
||||
// rootfs: to do more resources bind mount here to get more strict resources constraints
|
||||
rc = mount("/", sandboxPackagePath.c_str(), NULL, BASIC_MOUNT_FLAGS, NULL);
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "mount bind / failed, %{public}d", errno);
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::DoSandboxRootFolderCreate(const ClientSocket::AppProperty *appProperty,
|
||||
std::string &sandboxPackagePath)
|
||||
{
|
||||
int rc = mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
|
||||
DoAppSandboxMountOnce(sandboxPackagePath.c_str(), sandboxPackagePath.c_str(), BASIC_MOUNT_FLAGS);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool SandboxUtils::CheckTotalSandboxSwitchStatus(const ClientSocket::AppProperty *appProperty)
|
||||
{
|
||||
nlohmann::json wholeConfig = SandboxUtils::GetJsonConfig();
|
||||
HiLog::Error(LABEL, "CheckAppSandboxSwitchStatus total start, %{public}s", appProperty->bundleName);
|
||||
|
||||
nlohmann::json commonAppConfig = wholeConfig[COMMON_PREFIX][0];
|
||||
if (commonAppConfig.find(TOP_SANDBOX_SWITCH_PREFIX) != commonAppConfig.end()) {
|
||||
std::string switchStatus = commonAppConfig[TOP_SANDBOX_SWITCH_PREFIX].get<std::string>();
|
||||
if (switchStatus == SBX_SWITCH_CHECK) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// default sandbox switch is on
|
||||
return true;
|
||||
}
|
||||
|
||||
bool SandboxUtils::CheckAppSandboxSwitchStatus(const ClientSocket::AppProperty *appProperty)
|
||||
{
|
||||
nlohmann::json wholeConfig = SandboxUtils::GetJsonConfig();
|
||||
bool rc = true;
|
||||
HiLog::Error(LABEL, "CheckAppSandboxSwitchStatus start, %{public}s", appProperty->bundleName);
|
||||
|
||||
nlohmann::json privateAppConfig = wholeConfig[PRIVATE_PREFIX][0];
|
||||
if (privateAppConfig.find(appProperty->bundleName) != privateAppConfig.end()) {
|
||||
nlohmann::json appConfig = privateAppConfig[appProperty->bundleName][0];
|
||||
rc = GetSbxSwitchStatusByConfig(appConfig);
|
||||
HiLog::Error(LABEL, "CheckAppSandboxSwitchStatus middle, %{public}d", rc);
|
||||
}
|
||||
|
||||
// default sandbox switch is on
|
||||
return rc;
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::SetAppSandboxProperty(const ClientSocket::AppProperty *appProperty)
|
||||
{
|
||||
std::string sandboxPackagePath = "/mnt/sandbox/";
|
||||
const std::string bundleName = appProperty->bundleName;
|
||||
sandboxPackagePath += bundleName;
|
||||
int rc = 0;
|
||||
|
||||
// add pid to a new mnt namespace
|
||||
rc = unshare(CLONE_NEWNS);
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "unshare failed, packagename is %{public}s", bundleName.c_str());
|
||||
return rc;
|
||||
}
|
||||
|
||||
// to make wargnar work and check app sandbox switch
|
||||
if (access(WARGNAR_DEVICE_PATH, F_OK) == 0 || (CheckTotalSandboxSwitchStatus(appProperty) == false) ||
|
||||
(CheckAppSandboxSwitchStatus(appProperty) == false)) {
|
||||
rc = DoSandboxRootFolderCreateAdapt(sandboxPackagePath);
|
||||
HiLog::Error(LABEL, "CheckAppSandboxSwitchStatus 1111, %{public}d", rc);
|
||||
} else {
|
||||
rc = DoSandboxRootFolderCreate(appProperty, sandboxPackagePath);
|
||||
HiLog::Error(LABEL, "CheckAppSandboxSwitchStatus 2222, %{public}d", rc);
|
||||
}
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "DoSandboxRootFolderCreate failed, %{public}s", bundleName.c_str());
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = SetCommonAppSandboxProperty(appProperty, sandboxPackagePath);
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "SetCommonAppSandboxProperty failed, packagename is %{public}s", bundleName.c_str());
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = SetPrivateAppSandboxProperty(appProperty);
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "SetPrivateAppSandboxProperty failed, packagename is %{public}s", bundleName.c_str());
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = chdir(sandboxPackagePath.c_str());
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "chdir failed, packagename is %{public}s, path is %{public}s", \
|
||||
bundleName.c_str(), sandboxPackagePath.c_str());
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = syscall(SYS_pivot_root, sandboxPackagePath.c_str(), sandboxPackagePath.c_str());
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "pivot root failed, packagename is %{public}s, errno is %{public}d", \
|
||||
bundleName.c_str(), errno);
|
||||
return rc;
|
||||
}
|
||||
|
||||
rc = umount2(".", MNT_DETACH);
|
||||
if (rc) {
|
||||
HiLog::Error(LABEL, "MNT_DETACH failed, packagename is %{public}s", bundleName.c_str());
|
||||
return rc;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
} // namespace AppSpawn
|
||||
} // namespace OHOS
|
Loading…
Reference in New Issue
Block a user