mirror of
https://gitee.com/openharmony/startup_appspawn
synced 2024-11-27 01:00:38 +00:00
feat: 应用沙箱增强,使能pid namespace
Close #I5OE8Q Signed-off-by: zhushengle <zhushengle@huawei.com> Change-Id: I2897c0c9aacff3a06212d27956e3cb46ea03799e
This commit is contained in:
parent
c41d515381
commit
4f35b367da
@ -34,6 +34,7 @@ void RecordRenderProcessExitedStatus(pid_t pid, int status);
|
||||
void LoadAppSandboxConfig(void);
|
||||
void SetUidGidFilter(struct AppSpawnContent_ *content);
|
||||
int SetSeccompFilter(struct AppSpawnContent_ *content, AppSpawnClient *client);
|
||||
int32_t GetAppNamespaceFlags(const char *bundleName);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -25,7 +25,8 @@ using namespace OHOS;
|
||||
using namespace OHOS::AppSpawn;
|
||||
|
||||
namespace {
|
||||
const std::string MODULE_TEST_BUNDLE_NAME("moduleTestProcessName");
|
||||
const std::string MODULE_TEST_BUNDLE_NAME("moduleTestProcessName");
|
||||
const std::string NAMESPACE_JSON_CONFIG("/system/etc/sandbox/sandbox-config.json");
|
||||
#ifdef __aarch64__
|
||||
const std::string APP_JSON_CONFIG("/system/etc/sandbox/appdata-sandbox64.json");
|
||||
#else
|
||||
@ -45,12 +46,18 @@ void LoadAppSandboxConfig(void)
|
||||
rc = JsonUtils::GetJsonObjFromJson(appSandboxConfig, PRODUCT_JSON_CONFIG);
|
||||
APPSPAWN_CHECK_ONLY_LOG(rc, "AppSpawnServer::Failed to load app product sandbox config");
|
||||
SandboxUtils::StoreProductJsonConfig(appSandboxConfig);
|
||||
|
||||
nlohmann::json appNamespaceConfig;
|
||||
rc = JsonUtils::GetJsonObjFromJson(appNamespaceConfig, NAMESPACE_JSON_CONFIG);
|
||||
APPSPAWN_CHECK_ONLY_LOG(rc, "AppSpawnServer::Failed to load app sandbox namespace config");
|
||||
SandboxUtils::StoreNamespaceJsonConfig(appNamespaceConfig);
|
||||
}
|
||||
|
||||
int32_t SetAppSandboxProperty(struct AppSpawnContent_ *content, AppSpawnClient *client)
|
||||
{
|
||||
APPSPAWN_CHECK(client != NULL, return -1, "Invalid appspwn client");
|
||||
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
|
||||
appProperty->property.cloneFlags = client->cloneFlags;
|
||||
int ret = SandboxUtils::SetAppSandboxProperty(&appProperty->property);
|
||||
// for module test do not create sandbox
|
||||
if (strncmp(appProperty->property.bundleName,
|
||||
@ -59,3 +66,9 @@ int32_t SetAppSandboxProperty(struct AppSpawnContent_ *content, AppSpawnClient *
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int32_t GetAppNamespaceFlags(const char *bundleName)
|
||||
{
|
||||
return SandboxUtils::GetNamespaceFlagsFromConfig(bundleName);
|
||||
}
|
||||
|
||||
|
@ -19,6 +19,10 @@
|
||||
#include <errno.h>
|
||||
#include <sys/stat.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#undef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <sched.h>
|
||||
#ifdef OHOS_DEBUG
|
||||
#include <time.h>
|
||||
#endif // OHOS_DEBUG
|
||||
@ -31,6 +35,8 @@ void DisallowInternet(void);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#define SANDBOX_STACK_SIZE (1024 * 1024 * 8)
|
||||
|
||||
static void SetInternetPermission(const AppSpawnClient *client)
|
||||
{
|
||||
#ifndef APPSPAWN_TEST
|
||||
@ -74,7 +80,7 @@ int DoStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client, char *l
|
||||
APPSPAWN_LOGI("DoStartApp id %d longProcNameLen %u", client->id, longProcNameLen);
|
||||
int32_t ret = 0;
|
||||
|
||||
if (client->flags != UI_SERVICE_DIALOG && content->setAppSandbox) {
|
||||
if ((client->cloneFlags & CLONE_NEWNS) && (content->setAppSandbox)) {
|
||||
ret = content->setAppSandbox(content, client);
|
||||
APPSPAWN_CHECK(ret == 0, NotifyResToParent(content, client, ret);
|
||||
return ret, "Failed to set app sandbox");
|
||||
@ -122,73 +128,96 @@ int DoStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client, char *l
|
||||
return 0;
|
||||
}
|
||||
|
||||
int ForkChildProc(struct AppSpawnContent_ *content, AppSpawnClient *client, pid_t pid)
|
||||
int AppSpawnChild(void *arg)
|
||||
{
|
||||
if (pid < 0) {
|
||||
return -errno;
|
||||
} else if (pid == 0) {
|
||||
APPSPAWN_CHECK(arg != NULL, return -1, "Invalid arg for appspawn child");
|
||||
AppSandboxArg *sandbox = (AppSandboxArg *)arg;
|
||||
struct AppSpawnContent_ *content = sandbox->content;
|
||||
AppSpawnClient *client = sandbox->client;
|
||||
|
||||
#ifdef OHOS_DEBUG
|
||||
struct timespec tmStart = {0};
|
||||
GetCurTime(&tmStart);
|
||||
struct timespec tmStart = {0};
|
||||
GetCurTime(&tmStart);
|
||||
#endif // OHOS_DEBUG
|
||||
|
||||
// close socket id and signal for child
|
||||
if (content->clearEnvironment != NULL) {
|
||||
content->clearEnvironment(content, client);
|
||||
}
|
||||
// close socket id and signal for child
|
||||
if (content->clearEnvironment != NULL) {
|
||||
content->clearEnvironment(content, client);
|
||||
}
|
||||
|
||||
if (content->setAppAccessToken != NULL) {
|
||||
content->setAppAccessToken(content, client);
|
||||
}
|
||||
if (content->setAppAccessToken != NULL) {
|
||||
content->setAppAccessToken(content, client);
|
||||
}
|
||||
|
||||
int ret = -1;
|
||||
int ret = -1;
|
||||
#ifdef ASAN_DETECTOR
|
||||
if ((content->getWrapBundleNameValue != NULL && content->getWrapBundleNameValue(content, client) == 0)
|
||||
|| ((client->flags & APP_COLD_START) != 0)) {
|
||||
if ((content->getWrapBundleNameValue != NULL && content->getWrapBundleNameValue(content, client) == 0)
|
||||
|| ((client->flags & APP_COLD_START) != 0)) {
|
||||
#else
|
||||
if ((client->flags & APP_COLD_START) != 0) {
|
||||
if ((client->flags & APP_COLD_START) != 0) {
|
||||
#endif
|
||||
if (content->coldStartApp != NULL && content->coldStartApp(content, client) == 0) {
|
||||
if (content->coldStartApp != NULL && content->coldStartApp(content, client) == 0) {
|
||||
#ifndef APPSPAWN_TEST
|
||||
_exit(0x7f); // 0x7f user exit
|
||||
_exit(0x7f); // 0x7f user exit
|
||||
#endif
|
||||
return -1;
|
||||
} else {
|
||||
ret = DoStartApp(content, client, content->longProcName, content->longProcNameLen);
|
||||
}
|
||||
return -1;
|
||||
} else {
|
||||
ret = DoStartApp(content, client, content->longProcName, content->longProcNameLen);
|
||||
}
|
||||
} else {
|
||||
ret = DoStartApp(content, client, content->longProcName, content->longProcNameLen);
|
||||
}
|
||||
|
||||
#ifdef OHOS_DEBUG
|
||||
struct timespec tmEnd = {0};
|
||||
GetCurTime(&tmEnd);
|
||||
// 1s = 1000000000ns
|
||||
long timeUsed = (tmEnd.tv_sec - tmStart.tv_sec) * 1000000000L + (tmEnd.tv_nsec - tmStart.tv_nsec);
|
||||
APPSPAWN_LOGI("App timeused %d %ld ns.", getpid(), timeUsed);
|
||||
struct timespec tmEnd = {0};
|
||||
GetCurTime(&tmEnd);
|
||||
// 1s = 1000000000ns
|
||||
long timeUsed = (tmEnd.tv_sec - tmStart.tv_sec) * 1000000000L + (tmEnd.tv_nsec - tmStart.tv_nsec);
|
||||
APPSPAWN_LOGI("App timeused %d %ld ns.", getpid(), timeUsed);
|
||||
#endif // OHOS_DEBUG
|
||||
|
||||
if (ret == 0 && content->runChildProcessor != NULL) {
|
||||
content->runChildProcessor(content, client);
|
||||
}
|
||||
ProcessExit();
|
||||
if (ret == 0 && content->runChildProcessor != NULL) {
|
||||
content->runChildProcessor(content, client);
|
||||
}
|
||||
ProcessExit();
|
||||
return 0;
|
||||
}
|
||||
|
||||
int AppSpawnProcessMsg(struct AppSpawnContent_ *content, AppSpawnClient *client, pid_t *childPid)
|
||||
int AppSpawnProcessMsg(AppSandboxArg *sandbox, pid_t *childPid)
|
||||
{
|
||||
APPSPAWN_CHECK(content != NULL, return -1, "Invalid content for appspawn");
|
||||
APPSPAWN_CHECK(client != NULL && childPid != NULL, return -1, "Invalid client for appspawn");
|
||||
APPSPAWN_LOGI("AppSpawnProcessMsg id %d 0x%x", client->id, client->flags);
|
||||
pid_t pid;
|
||||
APPSPAWN_CHECK(sandbox != NULL && sandbox->content != NULL, return -1, "Invalid content for appspawn");
|
||||
APPSPAWN_CHECK(sandbox->client != NULL && childPid != NULL, return -1, "Invalid client for appspawn");
|
||||
APPSPAWN_LOGI("AppSpawnProcessMsg id %d 0x%x", sandbox->client->id, sandbox->client->flags);
|
||||
|
||||
#ifndef APPSPAWN_TEST
|
||||
pid_t pid = fork();
|
||||
#else
|
||||
pid_t pid = 0;
|
||||
#endif
|
||||
int ret = ForkChildProc(content, client, pid);
|
||||
APPSPAWN_CHECK(ret == 0, return ret, "fork child process error: %d", ret);
|
||||
AppSpawnClient *client = sandbox->client;
|
||||
if (client->cloneFlags & CLONE_NEWPID) {
|
||||
APPSPAWN_CHECK(client->cloneFlags & CLONE_NEWNS, return -1, "clone flags error");
|
||||
char *childStack = (char *)malloc(SANDBOX_STACK_SIZE);
|
||||
APPSPAWN_CHECK(childStack != NULL, return -1, "malloc failed");
|
||||
|
||||
pid = clone(AppSpawnChild, childStack + SANDBOX_STACK_SIZE, client->cloneFlags | SIGCHLD, (void *)sandbox);
|
||||
if (pid > 0) {
|
||||
free(childStack);
|
||||
*childPid = pid;
|
||||
return 0;
|
||||
}
|
||||
|
||||
client->cloneFlags &= ~CLONE_NEWPID;
|
||||
free(childStack);
|
||||
}
|
||||
|
||||
pid = fork();
|
||||
APPSPAWN_CHECK(pid >= 0, return -errno, "fork child process error: %d", -errno);
|
||||
*childPid = pid;
|
||||
#else
|
||||
pid = 0;
|
||||
*childPid = pid;
|
||||
#endif
|
||||
if (pid == 0) {
|
||||
AppSpawnChild((void *)sandbox);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ extern "C" {
|
||||
typedef struct AppSpawnClient_ {
|
||||
uint32_t id;
|
||||
uint32_t flags;
|
||||
uint32_t cloneFlags;
|
||||
#ifndef APPSPAWN_TEST
|
||||
#ifndef OHOS_LITE
|
||||
uint8_t setAllowInternet;
|
||||
@ -84,10 +85,15 @@ typedef struct AppSpawnContent_ {
|
||||
int (*setSeccompFilter)(struct AppSpawnContent_ *content, AppSpawnClient *client);
|
||||
} AppSpawnContent;
|
||||
|
||||
typedef struct {
|
||||
struct AppSpawnContent_ *content;
|
||||
AppSpawnClient *client;
|
||||
} AppSandboxArg;
|
||||
|
||||
AppSpawnContent *AppSpawnCreateContent(const char *socketName, char *longProcName, uint32_t longProcNameLen, int cold);
|
||||
int AppSpawnProcessMsg(struct AppSpawnContent_ *content, AppSpawnClient *client, pid_t *childPid);
|
||||
int AppSpawnProcessMsg(AppSandboxArg *sandbox, pid_t *childPid);
|
||||
int DoStartApp(struct AppSpawnContent_ *content, AppSpawnClient *client, char *longProcName, uint32_t longProcNameLen);
|
||||
int ForkChildProc(struct AppSpawnContent_ *content, AppSpawnClient *client, pid_t pid);
|
||||
int AppSpawnChild(void *arg);
|
||||
|
||||
#ifdef OHOS_DEBUG
|
||||
void GetCurTime(struct timespec* tmCur);
|
||||
|
@ -32,9 +32,16 @@ ohos_prebuilt_etc("product-sandbox.json") {
|
||||
module_install_dir = "etc/sandbox"
|
||||
}
|
||||
|
||||
ohos_prebuilt_etc("sandbox-config.json") {
|
||||
source = "//base/startup/appspawn/sandbox-config.json"
|
||||
part_name = "${part_name}"
|
||||
module_install_dir = "etc/sandbox"
|
||||
}
|
||||
|
||||
group("etc_files") {
|
||||
deps = [
|
||||
":appdata-sandbox.json",
|
||||
":product-sandbox.json",
|
||||
":sandbox-config.json",
|
||||
]
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ typedef enum AppOperateType_ {
|
||||
#define FD_INIT_VALUE 0
|
||||
|
||||
typedef struct AppParameter_ {
|
||||
uint32_t cloneFlags;
|
||||
uint32_t uid; // the UNIX uid that the child process setuid() to after fork()
|
||||
uint32_t gid; // the UNIX gid that the child process setgid() to after fork()
|
||||
uint32_t gidTable[APP_MAX_GIDS]; // a list of UNIX gids that the child process setgroups() to after fork()
|
||||
|
@ -134,6 +134,7 @@ static int Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, Ip
|
||||
AppSpawnClientLite client = {};
|
||||
client.client.id = CLIENT_ID;
|
||||
client.client.flags = 0;
|
||||
client.client.cloneFlags = 0;
|
||||
if (GetMessageSt(&client.message, req) != EC_SUCCESS) {
|
||||
APPSPAWN_LOGE("[appspawn] invoke, parse failed! reply %d.", INVALID_PID);
|
||||
WriteInt64(reply, INVALID_PID);
|
||||
@ -142,14 +143,24 @@ static int Invoke(IServerProxy *iProxy, int funcId, void *origin, IpcIo *req, Ip
|
||||
|
||||
APPSPAWN_LOGI("[appspawn] invoke, msg<%s,%s,%d,%d %d>", client.message.bundleName, client.message.identityID,
|
||||
client.message.uID, client.message.gID, client.message.capsCnt);
|
||||
/* Clone support only one parameter, so need to package application parameters */
|
||||
AppSandboxArg *sandboxArg = (AppSandboxArg *)malloc(sizeof(AppSandboxArg));
|
||||
if (sandboxArg == NULL) {
|
||||
WriteInt64(reply, INVALID_PID);
|
||||
return EC_FAILURE;
|
||||
}
|
||||
(void)memset_s(sandboxArg, sizeof(AppSandboxArg), 0, sizeof(AppSandboxArg));
|
||||
|
||||
pid_t newPid = 0;
|
||||
int ret = AppSpawnProcessMsg(&g_appSpawnContentLite->content, &client.client, &newPid);
|
||||
sandboxArg->content = &g_appSpawnContentLite->content;
|
||||
sandboxArg->client = &client.client;
|
||||
int ret = AppSpawnProcessMsg(sandboxArg, &newPid);
|
||||
if (ret != 0) {
|
||||
newPid = -1;
|
||||
}
|
||||
FreeMessageSt(&client.message);
|
||||
WriteInt64(reply, newPid);
|
||||
free(sandboxArg);
|
||||
|
||||
#ifdef OHOS_DEBUG
|
||||
struct timespec tmEnd = {0};
|
||||
|
19
sandbox-config.json
Executable file
19
sandbox-config.json
Executable file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"sandbox-namespace" : [{
|
||||
"com.ohos.note" : [{
|
||||
"clone-flags": [ "mnt", "pid" ]
|
||||
}],
|
||||
"com.ohos.screenlock" : [{
|
||||
"clone-flags": [ "mnt", "pid" ]
|
||||
}],
|
||||
"ohos.samples.flashlight" : [{
|
||||
"clone-flags": [ "mnt", "pid" ]
|
||||
}],
|
||||
"ohos.samples.ecg" : [{
|
||||
"clone-flags": [ "mnt", "pid" ]
|
||||
}],
|
||||
"ohos.samples.clock" : [{
|
||||
"clone-flags": [ "mnt", "pid" ]
|
||||
}]
|
||||
}]
|
||||
}
|
@ -28,6 +28,7 @@
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include "securec.h"
|
||||
#include "parameter.h"
|
||||
@ -165,18 +166,32 @@ static void ClearEnvironment(AppSpawnContent *content, AppSpawnClient *client)
|
||||
static int SetUidGid(struct AppSpawnContent_ *content, AppSpawnClient *client)
|
||||
{
|
||||
#ifdef GRAPHIC_PERMISSION_CHECK
|
||||
long ret;
|
||||
AppSpawnClientExt *appProperty = (AppSpawnClientExt *)client;
|
||||
// set gids
|
||||
bool isRet = setgroups(appProperty->property.gidCount, (const gid_t *)(&appProperty->property.gidTable[0])) == -1;
|
||||
APPSPAWN_CHECK(!isRet, return -errno, "setgroups failed: %d, gids.size=%u", errno, appProperty->property.gidCount);
|
||||
|
||||
// set gid
|
||||
isRet = setresgid(appProperty->property.gid, appProperty->property.gid, appProperty->property.gid) == -1;
|
||||
APPSPAWN_CHECK(!isRet, return -errno, "setgid(%u) failed: %d", appProperty->property.gid, errno);
|
||||
if (client->cloneFlags & CLONE_NEWPID) {
|
||||
/* setresuid and setresgid have multi-thread synchronous operations.
|
||||
* after clone, the C library has not cleaned up the multi-thread information, so need to call syscall.
|
||||
*/
|
||||
// set gid
|
||||
ret = syscall(SYS_setresgid, appProperty->property.gid, appProperty->property.gid, appProperty->property.gid);
|
||||
APPSPAWN_CHECK(ret == 0, return -errno, "setgid(%u) failed: %d", appProperty->property.gid, errno);
|
||||
|
||||
// If the effective user ID is changed from 0 to nonzero, then all capabilities are cleared from the effective set
|
||||
isRet = setresuid(appProperty->property.uid, appProperty->property.uid, appProperty->property.uid) == -1;
|
||||
APPSPAWN_CHECK(!isRet, return -errno, "setuid(%u) failed: %d", appProperty->property.uid, errno);
|
||||
// If the effective user ID is changed from 0 to nonzero, then all capabilities are cleared from the effective set
|
||||
ret = syscall(SYS_setresuid, appProperty->property.uid, appProperty->property.uid, appProperty->property.uid);
|
||||
APPSPAWN_CHECK(ret == 0, return -errno, "setuid(%u) failed: %d", appProperty->property.uid, errno);
|
||||
} else {
|
||||
// set gid
|
||||
isRet = setresgid(appProperty->property.gid, appProperty->property.gid, appProperty->property.gid) == -1;
|
||||
APPSPAWN_CHECK(!isRet, return -errno, "setgid(%u) failed: %d", appProperty->property.gid, errno);
|
||||
|
||||
// If the effective user ID is changed from 0 to nonzero, then all capabilities are cleared from the effective set
|
||||
isRet = setresuid(appProperty->property.uid, appProperty->property.uid, appProperty->property.uid) == -1;
|
||||
APPSPAWN_CHECK(!isRet, return -errno, "setuid(%u) failed: %d", appProperty->property.uid, errno);
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
#include <sched.h>
|
||||
|
||||
#include "init_hashmap.h"
|
||||
#include "init_socket.h"
|
||||
@ -376,13 +377,30 @@ APPSPAWN_STATIC void OnReceiveRequest(const TaskHandle taskHandle, const uint8_t
|
||||
appProperty->client.flags = appProperty->property.flags;
|
||||
fcntl(appProperty->fd[0], F_SETFL, O_NONBLOCK);
|
||||
|
||||
/* Clone support only one parameter, so need to package application parameters */
|
||||
AppSandboxArg *sandboxArg = (AppSandboxArg *)malloc(sizeof(AppSandboxArg));
|
||||
if (sandboxArg == NULL) {
|
||||
close(appProperty->fd[0]);
|
||||
close(appProperty->fd[1]);
|
||||
LE_CloseTask(LE_GetDefaultLoop(), taskHandle);
|
||||
return;
|
||||
}
|
||||
(void)memset_s(sandboxArg, sizeof(AppSandboxArg), 0, sizeof(AppSandboxArg));
|
||||
|
||||
pid_t pid = 0;
|
||||
int result = AppSpawnProcessMsg(&g_appSpawnContent->content, &appProperty->client, &pid);
|
||||
sandboxArg->content = &g_appSpawnContent->content;
|
||||
sandboxArg->client = &appProperty->client;
|
||||
sandboxArg->client->cloneFlags = 0;
|
||||
if (appProperty->client.flags != UI_SERVICE_DIALOG) {
|
||||
sandboxArg->client->cloneFlags = GetAppNamespaceFlags(appProperty->property.bundleName);
|
||||
}
|
||||
int result = AppSpawnProcessMsg(sandboxArg, &pid);
|
||||
if (result == 0) { // wait child process result
|
||||
result = WaitChild(appProperty->fd[0], pid, appProperty);
|
||||
}
|
||||
close(appProperty->fd[0]);
|
||||
close(appProperty->fd[1]);
|
||||
free(sandboxArg);
|
||||
APPSPAWN_LOGI("child process %s %s pid %d",
|
||||
appProperty->property.processName, (result == 0) ? "success" : "fail", pid);
|
||||
if (result == 0) {
|
||||
|
@ -123,6 +123,7 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_002, TestSize.Level0)
|
||||
AppSpawnClientExt* client = (AppSpawnClientExt*)malloc(sizeof(AppSpawnClientExt));
|
||||
client->client.id = 8; // 8 is client id
|
||||
client->client.flags = 0;
|
||||
client->client.cloneFlags = CLONE_NEWNS;
|
||||
client->fd[0] = 100; // 100 is fd
|
||||
client->fd[1] = 200; // 200 is fd
|
||||
client->property.uid = 10000; // 10000 is uid
|
||||
@ -149,8 +150,11 @@ HWTEST(AppSpawnStandardTest, App_Spawn_Standard_002, TestSize.Level0)
|
||||
content->loadExtendLib = LoadExtendLib;
|
||||
content->runChildProcessor = RunChildProcessor;
|
||||
SetContentFunction(content);
|
||||
EXPECT_EQ(ForkChildProc(content, &client->client, 0), 0);
|
||||
EXPECT_NE(ForkChildProc(content, &client->client, -1), 0);
|
||||
AppSandboxArg *sandboxArg = (AppSandboxArg *)malloc(sizeof(AppSandboxArg));
|
||||
sandboxArg->content = content;
|
||||
sandboxArg->client = &client->client;
|
||||
EXPECT_EQ(AppSpawnChild(sandboxArg), 0);
|
||||
free(sandboxArg);
|
||||
|
||||
content->clearEnvironment(content, &client->client);
|
||||
EXPECT_EQ(content->setProcessName(content, &client->client, (char *)longProcName, longProcNameLen), 0);
|
||||
|
@ -26,11 +26,14 @@ namespace OHOS {
|
||||
namespace AppSpawn {
|
||||
class SandboxUtils {
|
||||
public:
|
||||
static void StoreNamespaceJsonConfig(nlohmann::json &appNamespaceConfig);
|
||||
static nlohmann::json GetNamespaceJsonConfig(void);
|
||||
static void StoreJsonConfig(nlohmann::json &appSandboxConfig);
|
||||
static nlohmann::json GetJsonConfig();
|
||||
static void StoreProductJsonConfig(nlohmann::json &productSandboxConfig);
|
||||
static nlohmann::json GetProductJsonConfig();
|
||||
static int32_t SetAppSandboxProperty(const ClientSocket::AppProperty *appProperty);
|
||||
static int32_t GetNamespaceFlagsFromConfig(const char *bundleName);
|
||||
|
||||
private:
|
||||
static int32_t DoAppSandboxMountOnce(const char *originPath, const char *destinationPath,
|
||||
@ -69,6 +72,7 @@ private:
|
||||
nlohmann::json &config);
|
||||
|
||||
private:
|
||||
static nlohmann::json appNamespaceConfig_;
|
||||
static nlohmann::json appSandboxConfig_;
|
||||
static nlohmann::json productSandboxConfig_;
|
||||
};
|
||||
|
@ -71,11 +71,24 @@ namespace {
|
||||
const char *TARGET_NAME = "target-name";
|
||||
const char *FLAGS_POINT = "flags-point";
|
||||
const char *FLAGS = "flags";
|
||||
const char *SANDBOX_NAMESPACE = "sandbox-namespace";
|
||||
const char *SANDBOX_CLONE_FLAGS = "clone-flags";
|
||||
}
|
||||
|
||||
nlohmann::json SandboxUtils::appNamespaceConfig_;
|
||||
nlohmann::json SandboxUtils::appSandboxConfig_;
|
||||
nlohmann::json SandboxUtils::productSandboxConfig_;
|
||||
|
||||
void SandboxUtils::StoreNamespaceJsonConfig(nlohmann::json &appNamespaceConfig)
|
||||
{
|
||||
SandboxUtils::appNamespaceConfig_ = appNamespaceConfig;
|
||||
}
|
||||
|
||||
nlohmann::json SandboxUtils::GetNamespaceJsonConfig(void)
|
||||
{
|
||||
return SandboxUtils::appNamespaceConfig_;
|
||||
}
|
||||
|
||||
void SandboxUtils::StoreJsonConfig(nlohmann::json &appSandboxConfig)
|
||||
{
|
||||
SandboxUtils::appSandboxConfig_ = appSandboxConfig;
|
||||
@ -96,6 +109,39 @@ nlohmann::json SandboxUtils::GetProductJsonConfig()
|
||||
return SandboxUtils::productSandboxConfig_;
|
||||
}
|
||||
|
||||
static int32_t NamespaceFlagsFromConfig(const std::vector<std::string> &vec)
|
||||
{
|
||||
const std::map<std::string, int32_t> NamespaceFlagsMap = { {"mnt", CLONE_NEWNS}, {"pid", CLONE_NEWPID} };
|
||||
int32_t cloneFlags = 0;
|
||||
|
||||
for (unsigned int j = 0; j < vec.size(); j++) {
|
||||
if (NamespaceFlagsMap.count(vec[j])) {
|
||||
cloneFlags |= NamespaceFlagsMap.at(vec[j]);
|
||||
}
|
||||
}
|
||||
return cloneFlags;
|
||||
}
|
||||
|
||||
int32_t SandboxUtils::GetNamespaceFlagsFromConfig(const char *bundleName)
|
||||
{
|
||||
nlohmann::json config = SandboxUtils::GetNamespaceJsonConfig();
|
||||
int32_t cloneFlags = CLONE_NEWNS;
|
||||
|
||||
if (config.find(SANDBOX_NAMESPACE) == config.end()) {
|
||||
APPSPAWN_LOGE("namespace config is not found");
|
||||
return 0;
|
||||
}
|
||||
|
||||
nlohmann::json namespaceApp = config[SANDBOX_NAMESPACE][0];
|
||||
if (namespaceApp.find(bundleName) == namespaceApp.end()) {
|
||||
return cloneFlags;
|
||||
}
|
||||
|
||||
nlohmann::json app = namespaceApp[bundleName][0];
|
||||
cloneFlags |= NamespaceFlagsFromConfig(app[SANDBOX_CLONE_FLAGS].get<std::vector<std::string>>());
|
||||
return cloneFlags;
|
||||
}
|
||||
|
||||
static void MakeDirRecursive(const std::string &path, mode_t mode)
|
||||
{
|
||||
size_t size = path.size();
|
||||
@ -723,9 +769,13 @@ int32_t SandboxUtils::SetAppSandboxProperty(const ClientSocket::AppProperty *app
|
||||
sandboxPackagePath += bundleName;
|
||||
mkdir(sandboxPackagePath.c_str(), FILE_MODE);
|
||||
|
||||
// add pid to a new mnt namespace
|
||||
int rc = unshare(CLONE_NEWNS);
|
||||
APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %s", bundleName.c_str());
|
||||
int rc;
|
||||
// when CLONE_NEWPID is enabled, CLONE_NEWNS must be enabled.
|
||||
if (!(appProperty->cloneFlags & CLONE_NEWPID)) {
|
||||
// add pid to a new mnt namespace
|
||||
rc = unshare(CLONE_NEWNS);
|
||||
APPSPAWN_CHECK(rc == 0, return rc, "unshare failed, packagename is %s", bundleName.c_str());
|
||||
}
|
||||
|
||||
// to make wargnar work and check app sandbox switch
|
||||
if ((CheckTotalSandboxSwitchStatus(appProperty) == false) ||
|
||||
|
Loading…
Reference in New Issue
Block a user