提交 6b0cd809 编写于 作者: X xionglei6

init: add sandbox func

Signed-off-by: Nxionglei6 <xionglei6@huawei.com>
上级 85a97645
......@@ -48,7 +48,8 @@
"//base/startup/init_lite/interfaces/innerkits/socket:libsocket",
"//base/startup/init_lite/services/loopevent:loopevent",
"//base/startup/init_lite/interfaces/innerkits/plugin:libplugin",
"//base/startup/init_lite/device_info:device_info_group"
"//base/startup/init_lite/device_info:device_info_group",
"//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox"
],
"inner_kits": [
{
......
# 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.
import("//base/startup/init_lite/begetd.gni")
import("//build/ohos.gni")
config("exported_header_files") {
visibility = [ ":*" ]
include_dirs = [ "include/" ]
}
ohos_shared_library("libsandbox") {
sources = [
"sandbox.c",
"sandbox_namespace.c",
]
public_configs = [ ":exported_header_files" ]
include_dirs = [
"//third_party/bounds_checking_function/include",
"//base/startup/init_lite/services/include",
"//base/startup/init_lite/interfaces/innerkits/include",
"//third_party/cJSON",
]
defines = [ "INIT_AGENT" ]
deps = [
"//base/startup/init_lite/services/utils:libinit_utils",
"//third_party/bounds_checking_function:libsec_shared",
"//third_party/cJSON:cjson_static",
]
deps += [ "//base/startup/init_lite/services/log:init_log" ]
part_name = "init"
install_images = [ "system" ]
}
# For init only
ohos_static_library("libsandbox_static") {
sources = [
"sandbox.c",
"sandbox_namespace.c",
]
public_configs = [ ":exported_header_files" ]
include_dirs = [
"//third_party/bounds_checking_function/include",
"//base/startup/init_lite/interfaces/innerkits/include",
"//base/startup/init_lite/services/include",
"//third_party/cJSON",
]
deps = [
"//base/startup/init_lite/services/utils:libinit_utils",
"//third_party/bounds_checking_function:libsec_static",
"//third_party/cJSON:cjson_static",
]
deps += [ "//base/startup/init_lite/services/log:init_log" ]
part_name = "init"
}
{
"sandbox-root" : "/mnt/sandbox/chipset",
"mount-bind-paths" : [{
"src-path" : "/system/lib/vndk",
"sandbox-path" : "/system/lib/vndk",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/system/lib/platform-vndk",
"sandbox-path" : "/system/lib/platform-vndk",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/system/lib/ndk",
"sandbox-path" : "/system/lib/ndk",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/vendor/lib",
"sandbox-path" : "/vendor/lib",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/vendor/bin",
"sandbox-path" : "/vendor/bin",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/vendor/etc",
"sandbox-path" : "/vendor/etc",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/dev",
"sandbox-path" : "/dev",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/proc",
"sandbox-path" : "/proc",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/data",
"sandbox-path" : "/data",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/sys",
"sandbox-path" : "/sys",
"sandbox-flags" : [ "bind", "rec", "private" ]
}
],
"mount-bind-files" : [{
}],
"symbol-links" : [{
"target-name" : "/vendor/lib",
"link-name" : "/lib"
}, {
"target-name" : "/vendor/bin",
"link-name" : "/bin"
}, {
"target-name" : "/vendor/etc",
"link-name" : "/etc"
}
]
}
\ No newline at end of file
/*
* 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 BASE_STARTUP_INITLITE_SANDBOX_H
#define BASE_STARTUP_INITLITE_SANDBOX_H
#ifdef __cplusplus
extern "C" {
#endif
#include <stdbool.h>
#include "init_utils.h"
typedef struct {
char *source; // source 目录,一般是全局的fs 目录
char *target; // 沙盒化后的目录
unsigned long flags;
} mount_t;
typedef struct MountList {
mount_t *info;
struct MountList *next;
} mountlist_t;
typedef struct {
char *target;
char *linkName;
} linker_t;
typedef struct LinkList {
linker_t *info;
struct LinkList *next;
} linklist_t;
typedef struct {
mountlist_t *mounts;
linklist_t *links;
char *rootPath; // /mnt/sandbox/system|vendor|xxx
char name[MAX_BUFFER_LEN]; // name of sandbox. i.e system, chipset etc.
bool isCreated; // sandbox already created or not
int ns; // namespace
} sandbox_t;
bool InitSandboxWithName(const char *name);
int PrepareSandbox(const char *name);
int EnterSandbox(const char *name);
void DestroySandbox(const char *name);
int CheckSupportSandbox(void);
void DumpSandboxByName(const char *name);
#ifdef __cplusplus
}
#endif
#endif
/*
* 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_NAMESPACE_H
#define SANDBOX_NAMESPACE_H
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
int GetNamespaceFd(const char *nsPath);
int UnshareNamespace(int nsType);
int SetNamespce(int nsFd, int nsType);
void InitDefaultNamespace(void);
int EnterDefaultNamespace(void);
void CloseDefaultNamespace(void);
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif
\ No newline at end of file
/*
* 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.h"
#include <limits.h>
#include <string.h>
#include <unistd.h>
#include <sched.h>
#include <sys/mount.h>
#include <sys/syscall.h>
#include <errno.h>
#include "beget_ext.h"
#include "init_utils.h"
#include "cJSON.h"
#include "sandbox_namespace.h"
#include "securec.h"
#define SANDBOX_ROOT_TAG "sandbox-root"
#define SANDBOX_MOUNT_PATH_TAG "mount-bind-paths"
#define SANDBOX_MOUNT_FILE_TAG "mount-bind-files"
#define SANDBOX_SOURCE "src-path"
#define SANDBOX_TARGET "sandbox-path"
#define SANDBOX_FLAGS "sandbox-flags"
#define SANDBOX_SYMLINK_TAG "symbol-links"
#define SANDBOX_SYMLINK_TARGET "target-name"
#define SANDBOX_SYMLINK_NAME "link-name"
#define SANDBOX_SYSTEM_CONFIG_FILE "/system/etc/sandbox/system-sandbox.json"
#define SANDBOX_CHIPSET_CONFIG_FILE "/system/etc/sandbox/chipset-sandbox.json"
#define SANDBOX_PRIVAPP_CONFIG_FILE "/system/etc/sandbox/privapp-sandbox.json"
#define SANDBOX_APP_CONFIG_FILE "/system/etc/sandbox/app-sandbox.json"
#define SANDBOX_MOUNT_FLAGS_MS_BIND "bind"
#define SANDBOX_MOUNT_FLAGS_MS_PRIVATE "private"
#define SANDBOX_MOUNT_FLAGS_MS_REC "rec"
#define SANDBOX_MOUNT_FLAGS_MS_MOVE "move"
struct SandboxMountFlags {
const char *flag;
unsigned long value;
};
struct SandboxMountFlags g_flags[] = {
{
.flag = "bind",
.value = MS_BIND,
},
{
.flag = "private",
.value = MS_PRIVATE,
},
{
.flag = "rec",
.value = MS_REC,
},
{
.flag = "move",
.value = MS_MOVE,
}
};
static sandbox_t g_systemSandbox;
static sandbox_t g_chipsetSandbox;
static sandbox_t g_privAppSandbox;
static sandbox_t g_appSandbox;
struct SandboxMap {
const char *name;
sandbox_t *sandbox;
const char *configfile;
};
struct SandboxMap g_map[] = {
{
.name = "system",
.sandbox = &g_systemSandbox,
.configfile = SANDBOX_SYSTEM_CONFIG_FILE,
},
{
.name = "chipset",
.sandbox = &g_chipsetSandbox,
.configfile = SANDBOX_CHIPSET_CONFIG_FILE,
},
{
.name = "priv-app",
.sandbox = &g_privAppSandbox,
.configfile = SANDBOX_PRIVAPP_CONFIG_FILE,
},
{
.name = "app",
.sandbox = &g_appSandbox,
.configfile = SANDBOX_APP_CONFIG_FILE,
}
};
static unsigned long GetSandboxMountFlags(cJSON *item)
{
BEGET_ERROR_CHECK(item != NULL, return 0, "Invalid parameter.");
char *str = cJSON_GetStringValue(item);
if (str == NULL) {
return 0;
}
for (size_t i = 0; i < ARRAY_LENGTH(g_flags); i++) {
if (strcmp(str, g_flags[i].flag) == 0) {
return g_flags[i].value;
}
}
return 0;
}
typedef int (*AddInfoToSandboxCallback)(sandbox_t *sandbox, cJSON *item);
static int AddMountInfoToSandbox(sandbox_t *sandbox, cJSON *item)
{
if (sandbox == NULL || item == NULL) {
return -1;
}
mountlist_t *tmpMount = (mountlist_t *)calloc(1, sizeof(mountlist_t));
BEGET_ERROR_CHECK(tmpMount != NULL, return -1, "Failed calloc err=%d", errno);
tmpMount->info = (mount_t *)calloc(1, sizeof(mount_t));
BEGET_ERROR_CHECK(tmpMount->info != NULL, return -1, "Failed calloc err=%d", errno);
char *srcPath = cJSON_GetStringValue(cJSON_GetObjectItem(item, SANDBOX_SOURCE));
if (srcPath != NULL) {
tmpMount->info->source = strdup(srcPath);
}
char *dstPath = cJSON_GetStringValue(cJSON_GetObjectItem(item, SANDBOX_TARGET));
if (dstPath != NULL) {
tmpMount->info->target = strdup(dstPath);
}
cJSON *obj = cJSON_GetObjectItem(item, SANDBOX_FLAGS);
BEGET_ERROR_CHECK(obj != NULL, return -1, "Failed get sandbox-flags.");
int ret = cJSON_IsArray(obj);
BEGET_ERROR_CHECK(ret, return -1, "Failed get sandbox-flags array. ");
int count = cJSON_GetArraySize(obj);
BEGET_ERROR_CHECK(count > 0, return -1, "Failed get sandbox-flags array size.");
for (int i = 0; i < count; i++) {
cJSON *item = cJSON_GetArrayItem(obj, i);
tmpMount->info->flags |= GetSandboxMountFlags(item);
}
if (sandbox->mounts == NULL) {
sandbox->mounts = tmpMount;
tmpMount->next = NULL;
} else {
tmpMount->next = sandbox->mounts->next;
sandbox->mounts->next = tmpMount;
}
return 0;
}
static int AddSymbolLinksToSandbox(sandbox_t *sandbox, cJSON *item)
{
if (sandbox == NULL || item == NULL) {
return -1;
}
linklist_t *tmpLink = (linklist_t *)calloc(1, sizeof(linklist_t));
BEGET_ERROR_CHECK(tmpLink != NULL, return -1, "Failed calloc err=%d", errno);
tmpLink->info = (linker_t *)calloc(1, sizeof(linker_t));
BEGET_ERROR_CHECK(tmpLink->info != NULL, return -1, "Failed calloc err=%d", errno);
char *target = cJSON_GetStringValue(cJSON_GetObjectItem(item, SANDBOX_SYMLINK_TARGET));
if (target != NULL) {
tmpLink->info->target = strdup(target);
}
char *name = cJSON_GetStringValue(cJSON_GetObjectItem(item, SANDBOX_SYMLINK_NAME));
if (name != NULL) {
tmpLink->info->linkName = strdup(name);
}
if (sandbox->links == NULL) {
sandbox->links = tmpLink;
tmpLink->next = NULL;
} else {
tmpLink->next = sandbox->links->next;
sandbox->links->next = tmpLink;
}
return 0;
}
static int GetSandboxInfo(sandbox_t *sandbox, cJSON *root, const char *itemName)
{
if (sandbox == NULL || root == NULL || itemName == NULL) {
BEGET_LOGE("Get sandbox mount info with invalid argument");
return -1;
}
cJSON *obj = cJSON_GetObjectItem(root, itemName);
if (obj == NULL) {
BEGET_LOGE("Cannot find item \' %s \' in sandbox config", itemName);
return -1;
}
if (!cJSON_IsArray(obj)) {
BEGET_LOGE("%s with invalid type, should be array", itemName);
return -1;
}
int counts = cJSON_GetArraySize(obj);
if (counts <= 0) {
BEGET_LOGE("%s with invalid content", itemName);
return -1;
}
AddInfoToSandboxCallback func;
if (strcmp(itemName, SANDBOX_MOUNT_PATH_TAG) == 0) {
func = AddMountInfoToSandbox;
} else if (strcmp(itemName, SANDBOX_SYMLINK_TAG) == 0) {
func = AddSymbolLinksToSandbox;
} else {
BEGET_LOGE("Failed %s item name is not support.", itemName);
return -1;
}
for (int i = 0; i < counts; i++) {
cJSON *item = cJSON_GetArrayItem(obj, i);
BEGET_ERROR_CHECK(item != NULL, return -1, "Failed get json array item %d", i);
if (func(sandbox, item) < 0) {
BEGET_LOGE("Failed add info to sandbox.");
return -1;
}
}
return 0;
}
static int ParseSandboxConfig(sandbox_t *sandbox, const char *sandboxConfig)
{
if (sandbox == NULL || sandboxConfig == NULL) {
BEGET_LOGE("Parse sandbox config with invalid argument");
return -1;
}
char *contents = ReadFileToBuf(sandboxConfig);
if (contents == NULL) {
return -1;
}
cJSON *root = cJSON_Parse(contents);
if (root == NULL) {
BEGET_LOGE("Parse sandbox config \' %s \' failed", sandboxConfig);
return -1;
}
cJSON *sandboxRoot = cJSON_GetObjectItem(root, SANDBOX_ROOT_TAG);
if (sandboxRoot == NULL) {
BEGET_LOGE("Cannot find item \' %s \' in sandbox config", SANDBOX_ROOT_TAG);
cJSON_Delete(root);
return -1;
}
char *rootdir = cJSON_GetStringValue(sandboxRoot);
if (rootdir != NULL) {
sandbox->rootPath = strdup(rootdir);
if (sandbox->rootPath == NULL) {
BEGET_LOGE("Get sandbox root path out of memory");
cJSON_Delete(root);
return -1;
}
}
if (GetSandboxInfo(sandbox, root, SANDBOX_MOUNT_PATH_TAG) < 0) {
cJSON_Delete(root);
return -1;
}
if (GetSandboxInfo(sandbox, root, SANDBOX_SYMLINK_TAG) < 0) {
cJSON_Delete(root);
return -1;
}
cJSON_Delete(root);
return 0;
}
static struct SandboxMap *GetSandboxMapByName(const char *name)
{
if (name == NULL) {
BEGET_LOGE("Failed get sandbox map name is NULL.");
return NULL;
}
int len = ARRAY_LENGTH(g_map);
for (int i = 0; i < len; i++) {
if (strcmp(g_map[i].name, name) == 0) {
return &g_map[i];
}
}
return NULL;
}
static void InitSandbox(sandbox_t *sandbox, const char *sandboxConfig, const char *name)
{
if (sandbox == NULL || sandboxConfig == NULL || name == NULL) {
BEGET_LOGE("Init sandbox with invalid arguments");
return;
}
if (sandbox->isCreated) {
BEGET_LOGE("Sandbox %s has created.");
return;
}
if (UnshareNamespace(CLONE_NEWNS) < 0) {
return;
}
sandbox->ns = GetNamespaceFd("/proc/self/ns/mnt");
if (sandbox->ns < 0) {
BEGET_LOGE("Failed get sandbox namespace fd.");
return;
}
if (strcpy_s(sandbox->name, MAX_BUFFER_LEN - 1, name) != 0) {
BEGET_LOGE("Failed to copy sandbox name");
return;
}
// parse json config
if (ParseSandboxConfig(sandbox, sandboxConfig) < 0) {
return;
}
}
static int CheckAndMakeDir(const char *dir, mode_t mode)
{
if (access(dir, F_OK) == 0) {
BEGET_LOGW("Mount point \' %s \' already exist", dir);
return 0;
} else {
if (errno == ENOENT) {
if (MakeDirRecursive(dir, mode) != 0) {
BEGET_LOGE("Failed MakeDirRecursive %s, err=%d", dir, errno);
return -1;
}
} else {
BEGET_LOGW("Failed to access mount point \' %s \', err = %d", dir, errno);
return -1;
}
}
return 0;
}
static int BindMount(const char *source, const char *target, unsigned long flags)
{
if (source == NULL || target == NULL) {
BEGET_LOGE("Mount with invalid arguments");
errno = EINVAL;
return -1;
}
mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
if (CheckAndMakeDir(target, mode) != 0) {
BEGET_LOGE("Failed make %s dir.", target);
return -1;
}
if ((flags & MS_BIND) == 0) {
BEGET_LOGW("Not configure bind, must configure bind flag.");
flags |= MS_BIND;
}
if ((flags & MS_REC) == 0) {
BEGET_LOGW("Not configure rec, must configure rec flag.");
flags |= MS_REC;
}
// do mount
if (mount(source, target, NULL, flags, NULL) != 0) {
BEGET_LOGE("Failed to bind mount \' %s \' to \' %s \', err = %d", source, target, errno);
return -1;
}
return 0;
}
static bool IsValidSandbox(sandbox_t *sandbox)
{
if (sandbox == NULL) {
BEGET_LOGE("preparing sandbox with invalid argument");
return false;
}
if (sandbox->rootPath == NULL) {
return false;
}
if (sandbox->mounts == NULL) {
return false;
}
return true;
}
static int MountSandboxInfo(const mountlist_t *mounts, const char *rootPath)
{
if (mounts == NULL) {
return -1;
}
if (mounts->info == NULL) {
return -1;
}
while (mounts != NULL) {
mount_t *mount = mounts->info;
char *source = mount->source;
char target[PATH_MAX] = {};
if (snprintf_s(target, PATH_MAX, PATH_MAX - 1, "%s%s", rootPath, mount->target) < 0) {
BEGET_LOGE("Failed snprintf_s err=%d", errno);
return -1;
}
int rc = BindMount(source, target, mount->flags);
BEGET_ERROR_CHECK(rc == 0, return -1, "Failed bind mount %s to %s.", source, target);
mounts = mounts->next;
}
return 0;
}
static int LinkSandboxInfo(const linklist_t *links, const char *rootPath)
{
if (links == NULL) {
return -1;
}
if (links->info == NULL) {
return -1;
}
while (links != NULL) {
linker_t *link = links->info;
char linkName[PATH_MAX] = {0};
if (snprintf_s(linkName, PATH_MAX, PATH_MAX - 1, "%s%s", rootPath, link->linkName) < 0) {
BEGET_LOGE("Failed snprintf_s err=%d", errno);
return -1;
}
int rc = symlink(link->target, linkName);
if (rc != 0) {
if (errno == EEXIST) {
BEGET_LOGE("symbol link name \' %s \' already exist", linkName);
} else {
BEGET_LOGE("Failed to link \' %s \' to \' %s \', err = %d", link->target, linkName, errno);
return -1;
}
}
links = links->next;
}
return 0;
}
int PrepareSandbox(const char *name)
{
BEGET_ERROR_CHECK(name != NULL, return -1, "Prepare sandbox name is NULL.");
BEGET_ERROR_CHECK(getuid() == 0, return -1, "Current process uid is not root, exit.");
struct SandboxMap *map = GetSandboxMapByName(name);
BEGET_ERROR_CHECK(map != NULL, return -1, "Failed get sandbox map by name %s.", name);
sandbox_t *sandbox = map->sandbox;
BEGET_CHECK(IsValidSandbox(sandbox) == true, return -1);
BEGET_INFO_CHECK(sandbox->isCreated == false, return 0, "Sandbox %s already created", sandbox->name);
BEGET_CHECK(sandbox->rootPath != NULL, return -1);
mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH;
BEGET_ERROR_CHECK(CheckAndMakeDir(sandbox->rootPath, mode) == 0, return -1, "Failed root %s.", sandbox->rootPath);
int rc = mount(NULL, "/", NULL, MS_REC | MS_SLAVE, NULL);
BEGET_ERROR_CHECK(rc == 0, return -1, "Failed set mount slave err = %d", errno);
rc = BindMount(sandbox->rootPath, sandbox->rootPath, MS_BIND | MS_REC);
BEGET_ERROR_CHECK(rc == 0, return -1, "Failed to mount rootpath bind err = %d", errno);
// 1) walk through all mounts and do bind mount
rc = MountSandboxInfo(sandbox->mounts, sandbox->rootPath);
if (rc < 0) {
return -1;
}
// 2) walk through all links and do symbol link
rc = LinkSandboxInfo(sandbox->links, sandbox->rootPath);
if (rc < 0) {
return -1;
}
BEGET_ERROR_CHECK(chdir(sandbox->rootPath) == 0, return -1, "Change to %s, err = %d", sandbox->rootPath, errno);
BEGET_ERROR_CHECK(syscall(SYS_pivot_root, sandbox->rootPath, sandbox->rootPath) == 0, return -1,
"Failed system call pivot root, err=%d", errno);
BEGET_ERROR_CHECK(umount2(".", MNT_DETACH) == 0, return -1, "Failed umount2 MNT_DETACH, err=%d", errno);
sandbox->isCreated = true;
return 0;
}
static void FreeLink(linker_t *link)
{
if (link == NULL) {
return;
}
if (link->linkName != NULL) {
free(link->linkName);
link->linkName = NULL;
}
if (link->target != NULL) {
free(link->target);
link->target = NULL;
}
}
static void FreeLinks(linklist_t *links)
{
if (links == NULL) {
return;
}
linklist_t *tmp = links;
while (tmp != NULL) {
linklist_t *next = tmp ->next;
FreeLink(tmp->info);
free(tmp);
tmp = next;
}
}
static void FreeMount(mount_t *mount)
{
if (mount == NULL) {
return;
}
if (mount->source != NULL) {
free(mount->source);
mount->source = NULL;
}
if (mount->target != NULL) {
free(mount->target);
mount->target = NULL;
}
}
static void FreeMounts(mountlist_t *mounts)
{
if (mounts == NULL) {
return;
}
mountlist_t *tmp = mounts;
while (tmp != NULL) {
mountlist_t *next = tmp ->next;
FreeMount(tmp->info);
free(tmp);
tmp = next;
}
}
bool InitSandboxWithName(const char *name)
{
bool isFound = false;
if (name == NULL) {
BEGET_LOGE("Init sandbox name is NULL.");
return isFound;
}
struct SandboxMap *map = GetSandboxMapByName(name);
if (map != NULL) {
InitSandbox(map->sandbox, map->configfile, name);
isFound = true;
}
if (!isFound) {
BEGET_LOGE("Cannot find sandbox with name %s.", name);
}
return isFound;
}
void DestroySandbox(const char *name)
{
if (name == NULL) {
BEGET_LOGE("Destroy sandbox name is NULL.");
return;
}
struct SandboxMap *map = GetSandboxMapByName(name);
if (map == NULL) {
BEGET_LOGE("Failed get sandbox map by name %s.", name);
return;
}
sandbox_t *sandbox = map->sandbox;
if (sandbox == NULL) {
return;
}
if (sandbox->rootPath != NULL) {
free(sandbox->rootPath);
sandbox->rootPath = NULL;
}
FreeLinks(sandbox->links);
FreeMounts(sandbox->mounts);
if (sandbox->ns > 0) {
(void)close(sandbox->ns);
}
sandbox->isCreated = false;
return;
}
int EnterSandbox(const char *name)
{
if (name == NULL) {
BEGET_LOGE("Destroy sandbox name is NULL.");
return -1;
}
struct SandboxMap *map = GetSandboxMapByName(name);
if (map == NULL) {
BEGET_LOGE("Failed get sandbox map by name %s.", name);
return -1;
}
sandbox_t *sandbox = map->sandbox;
if (sandbox == NULL) {
return -1;
}
if (sandbox->isCreated == false) {
BEGET_LOGE("Sandbox has not created.");
return -1;
}
if (sandbox->ns > 0) {
if (SetNamespce(sandbox->ns, CLONE_NEWNS) < 0) {
BEGET_LOGE("Failed set namespace CLONE_NEWNS, err=%d.", errno);
return -1;
}
} else {
BEGET_LOGE("System sandbox namespace fd is error.");
return -1;
}
return 0;
}
void DumpSandboxByName(const char *name)
{
if (name == NULL) {
BEGET_LOGE("Init sandbox name is NULL.");
return;
}
struct SandboxMap *map = GetSandboxMapByName(name);
if (map == NULL) {
return;
}
BEGET_LOGI("Sandbox Map name: %s.", map->name);
BEGET_LOGI("Sandbox Map config file: %s.", map->configfile);
BEGET_LOGI("Sandbox name: %s.", map->sandbox->name);
BEGET_LOGI("Sandbox rootPath: %s.", map->sandbox->rootPath);
BEGET_LOGI("Sandbox mounts info:");
mountlist_t *mounts = map->sandbox->mounts;
while (mounts != NULL) {
mount_t *mount = mounts->info;
BEGET_LOGI("Sandbox mounts list source: %s", mount->source);
BEGET_LOGI("Sandbox mounts list target: %s", mount->target);
mounts = mounts->next;
}
BEGET_LOGI("Sandbox links info:");
linklist_t *links = map->sandbox->links;
while (links != NULL) {
linker_t *link = links->info;
BEGET_LOGI("Sandbox links list source: %s", link->target);
BEGET_LOGI("Sandbox links list target: %s", link->linkName);
links = links->next;
}
return;
}
/*
* 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 <errno.h>
#include <fcntl.h>
#include <sched.h>
#include <string.h>
#include <sys/types.h>
#include <unistd.h>
#include "beget_ext.h"
static int g_defaultNs;
int GetNamespaceFd(const char *nsPath)
{
if (nsPath == NULL) {
return -1;
}
int ns = open(nsPath, O_RDONLY | O_CLOEXEC);
if (ns < 0) {
BEGET_LOGE("Failed unshare namespace, err=%d", errno);
return -1;
}
return ns;
}
int UnshareNamespace(int nsType)
{
if (nsType == CLONE_NEWNS) {
if (unshare(nsType) < 0) {
BEGET_LOGE("Failed unshare namespace, err=%d", errno);
return -1;
} else {
return 0;
}
} else {
BEGET_LOGE("Failed unshare, type is not support");
return -1;
}
}
int SetNamespce(int nsFd, int nsType)
{
if (nsFd < 0) {
BEGET_LOGE("Failed get namespace fd");
return -1;
}
if (nsType != CLONE_NEWNS) {
BEGET_LOGE("Failed get namespace type");
return -1;
}
return setns(nsFd, nsType);
}
void InitDefaultNamespace(void)
{
if (g_defaultNs > 0) {
(void)close(g_defaultNs);
}
g_defaultNs = GetNamespaceFd("/proc/self/ns/mnt");
return;
}
int EnterDefaultNamespace(void)
{
if (g_defaultNs < 0) {
return -1;
}
return SetNamespce(g_defaultNs, CLONE_NEWNS);
}
void CloseDefaultNamespace(void)
{
if (g_defaultNs > 0) {
(void)close(g_defaultNs);
g_defaultNs = -1;
}
return;
}
{
"sandbox-root" : "/mnt/sandbox/system",
"mount-bind-paths" : [{
"src-path" : "/system/bin",
"sandbox-path" : "/system/bin",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/system/etc",
"sandbox-path" : "/system/etc",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/system/lib",
"sandbox-path" : "/system/lib",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/system/profile",
"sandbox-path" : "/system/profile",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/system/app",
"sandbox-path" : "/system/app",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/system/fonts",
"sandbox-path" : "/system/fonts",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/vendor",
"sandbox-path" : "/vendor",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/dev",
"sandbox-path" : "/dev",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/proc",
"sandbox-path" : "/proc",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/data",
"sandbox-path" : "/data",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/sys",
"sandbox-path" : "/sys",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/config",
"sandbox-path" : "/config",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/mnt",
"sandbox-path" : "/mnt",
"sandbox-flags" : [ "bind", "rec", "private" ]
}, {
"src-path" : "/storage",
"sandbox-path" : "/storage",
"sandbox-flags" : [ "bind", "rec", "private" ]
}
],
"mount-bind-files" : [{
}],
"symbol-links" : [{
"target-name" : "/system/lib",
"link-name" : "/lib"
}, {
"target-name" : "/system/bin",
"link-name" : "/bin"
}, {
"target-name" : "/system/etc",
"link-name" : "/etc"
}
]
}
\ No newline at end of file
......@@ -49,5 +49,6 @@ if (defined(ohos_lite)) {
"system",
"updater",
]
relative_install_dir = "platform-vndk"
}
}
......@@ -125,6 +125,7 @@ if (defined(ohos_lite)) {
include_dirs = [
"//base/security/access_token/interfaces/innerkits/token_setproc/include",
"//base/security/access_token/interfaces/innerkits/nativetoken/include",
"//base/startup/init_lite/interfaces/innerkits/sandbox/include",
"//base/startup/init_lite/services/include/param",
"//base/startup/init_lite/services/include",
"//base/startup/init_lite/services/init/include",
......@@ -141,6 +142,7 @@ if (defined(ohos_lite)) {
"//base/security/access_token/interfaces/innerkits/nativetoken:libnativetoken",
"//base/security/access_token/interfaces/innerkits/token_setproc:libtoken_setproc",
"//base/startup/init_lite/interfaces/innerkits:libfsmanager_static",
"//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox_static",
"//base/startup/init_lite/services/log:init_log",
"//base/startup/init_lite/services/loopevent:loopevent",
"//base/startup/init_lite/services/param:param_service",
......@@ -301,10 +303,23 @@ if (defined(ohos_lite)) {
part_name = "init"
}
ohos_prebuilt_etc("system-sandbox.json") {
source = "//base/startup/init_lite/interfaces/innerkits/sandbox/system-sandbox.json"
part_name = "init"
module_install_dir = "etc/sandbox"
}
ohos_prebuilt_etc("chipset-sandbox.json") {
source = "//base/startup/init_lite/interfaces/innerkits/sandbox/chipset-sandbox.json"
part_name = "init"
module_install_dir = "etc/sandbox"
}
group("init_etc") {
deps = [
":boot.group",
":charing.group",
":chipset-sandbox.json",
":group",
":init.cfg",
":init.usb.cfg",
......@@ -315,6 +330,7 @@ if (defined(ohos_lite)) {
":plugin_modules",
":syscap.json",
":syscap.para",
":system-sandbox.json",
":systemcapability.json",
]
}
......
......@@ -20,6 +20,7 @@ ohos_executable("begetctl") {
"main.c",
"misc_daemon.cpp",
"param_cmd.c",
"sandbox.cpp",
"service_control.c",
"shell/shell_bas.c",
]
......@@ -41,12 +42,16 @@ ohos_executable("begetctl") {
"//base/startup/init_lite/services/param/include",
"//base/startup/init_lite/services/loopevent/include",
"//third_party/bounds_checking_function/include",
"//base/startup/init_lite/interfaces/innerkits/sandbox/include",
"//utils/native/base/include",
]
deps = [
"//base/startup/init_lite/interfaces/innerkits:libbegetutil",
"//base/startup/init_lite/interfaces/innerkits/sandbox:libsandbox_static",
"//base/startup/init_lite/services/log:agent_log",
"//base/startup/init_lite/services/param:param_client",
"//third_party/bounds_checking_function:libsec_static",
"//utils/native/base:utils",
]
if (param_test) {
......@@ -72,6 +77,7 @@ ohos_executable("begetctl") {
"stop_service",
"service",
"param",
"sandbox",
]
install_images = [ "system" ]
......
/*
* 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 <cerrno>
#include <cstdlib>
#include <cstdio>
#include <cstdint>
#include <getopt.h>
#include <iostream>
#include <map>
#include <string>
#include <unistd.h>
#include <vector>
#include "begetctl.h"
#include "init_utils.h"
#include "sandbox.h"
#include "sandbox_namespace.h"
#include "string_ex.h"
using namespace OHOS;
struct option g_options[] = {
{ "config_file", required_argument, nullptr, 'c' },
{ "sandbox_name", required_argument, nullptr, 's' },
{ "process_name", required_argument, nullptr, 'p' },
{ "help", no_argument, nullptr, 'h' },
{ nullptr, 0, nullptr, 0 },
};
static void Usage()
{
std::cout << "sandbox -c, --config_file=sandbox config file \"config file with json format\"" << std::endl;
std::cout << "sandbox -s, --sandbox_name=sandbox name \"Sandbox name, system, chipset etc.\"" << std::endl;
std::cout << "sandbox -p, --process=process name \"sh, hdcd, hdf_devhost, etc.\"" << std::endl;
std::cout << "sandbox -h, --help \"Show help\"" << std::endl;
exit(0);
}
static std::string SearchConfigBySandboxName(const std::string &sandboxName)
{
std::map<std::string, std::string> sandboxConfigMap = {
{"system", "/system/etc/system-sandbox.json"},
{"chipset", "/system/etc/chipset-sandbox.json"},
{"priv-app", "/system/etc/priv-app-sandbox.json"},
{"app", "/system/etc/app-sandbox.json"},
};
auto it = sandboxConfigMap.find(sandboxName);
if (it == sandboxConfigMap.end()) {
return "";
} else {
return it->second;
}
}
static void RunSandbox(const std::string &configFile, const std::string &name)
{
std::string config {};
std::string sandboxName {};
if (!name.empty()) {
config = SearchConfigBySandboxName(name);
sandboxName = name;
} else {
// Without sandbox name, give one.
sandboxName = "sandbox_test";
}
if (config.empty()) {
std::cout << "No sandbox name " << sandboxName << "or config file specified!" << std::endl;
return;
}
InitDefaultNamespace();
if (!InitSandboxWithName(sandboxName.c_str())) {
std::cout << "Init sandbox failed." << std::endl;
return;
}
DumpSandboxByName(sandboxName.c_str());
if (PrepareSandbox(sandboxName.c_str()) != 0) {
std::cout << "Prepare sandbox failed." << std::endl;
return;
}
EnterDefaultNamespace();
CloseDefaultNamespace();
EnterSandbox(sandboxName.c_str());
return;
}
static void EnterShell()
{
char *argv[] = { (char *)"sh", NULL };
char *envp[] = { nullptr };
if (execve("/system/bin/sh", argv, envp) != 0) {
std::cout << "execve sh failed! err = "<< errno << std::endl;
}
return;
}
static const int MAX_PROCESS_ARGC = 8;
static void EnterExec(const std::string &processName)
{
if (processName.empty()) {
std::cout << "process name is nullptr." << std::endl;
return;
}
std::string tmpName = processName;
std::vector<std::string> vtr;
const std::string sep = " ";
OHOS::SplitStr(tmpName, sep, vtr, true, false);
if ((vtr.size() > MAX_PROCESS_ARGC) || (vtr.size() <= 0)) {
std::cout << "Service parameters is error." << std::endl;
return;
}
char *argv[MAX_PROCESS_ARGC] = {};
std::vector<std::string>::iterator it;
int i = 0;
for (it = vtr.begin(); it != vtr.end(); it++) {
argv[i] = (char *)(*it).c_str();
std::cout << std::string(argv[i]) << std::endl;
i++;
}
argv[i] = NULL;
char *envp[] = { NULL };
if (execve(argv[0], argv, envp) != 0) {
std::cout << "execve:" << argv[0] << "failed! err = "<< errno << std::endl;
}
return;
}
static void RunCmd(const std::string &configFile, const std::string &sandboxName, const std::string &processName)
{
if (!sandboxName.empty() && processName.empty()) {
RunSandbox(configFile, sandboxName);
EnterShell();
} else if (!sandboxName.empty() && !processName.empty()) {
RunSandbox(configFile, sandboxName);
EnterExec(processName);
} else if (sandboxName.empty() && !processName.empty()) {
std::cout << "process name:" << processName << std::endl;
RunSandbox(configFile, std::string("system"));
EnterExec(processName);
} else {
Usage();
}
}
static int main_cmd(BShellHandle shell, int argc, char **argv)
{
int rc = -1;
int optIndex = -1;
std::string configFile {};
std::string sandboxName {};
std::string processName {};
while ((rc = getopt_long(argc, argv, "c:s:p:h", g_options, &optIndex)) != -1) {
switch (rc) {
case 0: {
std::string optionName = g_options[optIndex].name;
if (optionName == "config_file") {
configFile = optarg;
} else if (optionName == "help") {
Usage();
} else if (optionName == "sandbox_name") {
sandboxName = optarg;
} else if (optionName == "process_name") {
processName = optarg;
}
break;
}
case 'c':
configFile = optarg;
break;
case 'h':
Usage();
break;
case 's':
sandboxName = optarg;
break;
case 'p':
std::cout << "1111 process name:" << optarg << std::endl;
processName = optarg;
break;
case '?':
std::cout << "Invalid arugment\n";
break;
default:
std::cout << "Invalid arugment\n";
break;
}
}
RunCmd(configFile, sandboxName, processName);
return 0;
}
MODULE_CONSTRUCTOR(void)
{
CmdInfo infos[] = {
{
(char *)"sandbox", main_cmd, (char *)"sandbox debug tool",
(char *)"sandbox -s, --sandbox=system, chipset, priv-app, or app",
NULL
}
};
for (size_t i = 0; i < ARRAY_LENGTH(infos); i++) {
BShellEnvRegitsterCmd(GetShellHandle(), &infos[i]);
}
}
......@@ -15,8 +15,6 @@
"mkdir /dev/memcg/system 0550 system system",
"start ueventd",
"start watchdog_service",
"mkdir /data",
"mount_fstab /vendor/etc/fstab.${ohos.boot.hardware}",
"chown system system /data",
"chmod 0771 /data",
"mkdir /data/service 0711 root root",
......@@ -64,11 +62,9 @@
"write /dev/blkio/background/blkio.weight 500",
"write /dev/blkio/blkio.group_idle 0",
"write /dev/blkio/background/blkio.group_idle 0",
"mount configfs none /config nodev noexec nosuid",
"chmod 0770 /config/sdcardfs",
"chown system package_info /config/sdcardfs",
"symlink /storage/self/primary /sdcard",
"mkdir /mnt/sandbox 0711 root root",
"write /proc/sys/kernel/panic_on_oops 1",
"write /proc/sys/kernel/hung_task_timeout_secs 0",
"write /proc/cpu/alignment 4",
......@@ -221,7 +217,6 @@
"mkdir /data/service/el2/0/hmdfs 0711 system system",
"mkdir /data/chipset/el1/0 0711 root root",
"mkdir /data/chipset/el2/0 0711 root root",
"mount tmpfs tmpfs /storage nodev noexec nosuid mode=0755,uid=0,gid=0",
"mkdir /storage/media 0711 root root",
"mkdir /data/bootchart 0755 shell shell",
"mkdir /data/app-staging 0750 system system",
......
......@@ -16,9 +16,6 @@
"mkdir /dev/memcg/system 0550 system system",
"start ueventd",
"start watchdog_service",
"mkdir /data",
"mount ext4 /dev/block/platform/soc/10100000.himci.eMMC/by-name/vendor /vendor wait rdonly barrier=1",
"mount ext4 /dev/block/platform/soc/10100000.himci.eMMC/by-name/userdata /data wait nosuid nodev noatime barrier=1,data=ordered,noauto_da_alloc",
"chown system system /data",
"chmod 0771 /data",
"mkdir /data/service 0711 root root",
......@@ -64,11 +61,9 @@
"write /dev/blkio/background/blkio.weight 500",
"write /dev/blkio/blkio.group_idle 0",
"write /dev/blkio/background/blkio.group_idle 0",
"mount configfs none /config nodev noexec nosuid",
"chmod 0770 /config/sdcardfs",
"chown system package_info /config/sdcardfs",
"symlink /storage/self/primary /sdcard",
"mkdir /mnt/sandbox 0711 root root",
"write /proc/sys/kernel/panic_on_oops 1",
"write /proc/sys/kernel/hung_task_timeout_secs 0",
"write /proc/cpu/alignment 4",
......
......@@ -37,3 +37,4 @@ const.build.characteristics=default
const.product.model=ohos
const.product.name="OpenHarmony 2.0 Canary"
persist.sys.usb.config=hdc
const.sandbox=enable
......@@ -43,6 +43,7 @@ void SystemExecuteRcs(void);
void ReadConfig(void);
void SignalInit(void);
int SetServiceEnterSandbox(const char *path);
#ifdef __cplusplus
#if __cplusplus
......
......@@ -280,8 +280,10 @@ int ServiceStart(Service *service)
}
int pid = fork();
if (pid == 0) {
INIT_CHECK_ONLY_ELOG(SetAccessToken(service) == SERVICE_SUCCESS,
"set access token failed for service %s", service->name);
INIT_CHECK_ONLY_ELOG(SetServiceEnterSandbox(service->pathArgs.argv[0]) == SERVICE_SUCCESS,
"Failed %s sandbox.", service->name);
INIT_CHECK_ONLY_ELOG(SetAccessToken(service) == SERVICE_SUCCESS, "access token failed %s", service->name);
// deal start job
if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]);
......@@ -290,8 +292,7 @@ int ServiceStart(Service *service)
ClearEnvironment();
if (!IsOnDemandService(service)) {
int ret = CreateServiceSocket(service);
INIT_ERROR_CHECK(ret >= 0, return SERVICE_FAILURE,
INIT_ERROR_CHECK(CreateServiceSocket(service) >= 0, return SERVICE_FAILURE,
"service %s exit! create socket failed!", service->name);
}
......
......@@ -82,3 +82,9 @@ void SystemRun(void)
{
LE_RunLoop(LE_GetDefaultLoop());
}
int SetServiceEnterSandbox(const char *path)
{
UNUSED(path);
return -1;
}
......@@ -47,6 +47,12 @@ void MountBasicFs(void)
if (mount("tmpfs", "/mnt", "tmpfs", MS_NOSUID, "mode=0755") != 0) {
INIT_LOGE("Mount tmpfs failed. %s", strerror(errno));
}
if (mount("tmpfs", "/storage", "tmpfs", MS_NOEXEC | MS_NODEV| MS_NOSUID, "mode=0755") != 0) {
INIT_LOGE("Mount storage failed. %s", strerror(errno));
}
if (mount("none", "/config", "configfs", MS_NOEXEC | MS_NODEV| MS_NOSUID, "mode=0755") != 0) {
INIT_LOGE("Mount configfs failed. %s", strerror(errno));
}
if (mkdir("/dev/pts", S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) {
INIT_LOGE("mkdir /dev/pts failed. %s", strerror(errno));
}
......
......@@ -38,11 +38,15 @@
#include "ueventd.h"
#include "ueventd_socket.h"
#include "fd_holder_internal.h"
#include "sandbox.h"
#include "sandbox_namespace.h"
#ifdef WITH_SELINUX
#include <policycoreutils.h>
#include <selinux/selinux.h>
#endif // WITH_SELINUX
static bool g_enableSandbox;
static int FdHolderSockInit(void)
{
int sock = -1;
......@@ -88,6 +92,28 @@ static int FdHolderSockInit(void)
return sock;
}
static void RegisterSandbox(const char *sandbox)
{
if (sandbox == NULL) {
INIT_LOGE("Invaild parameters.");
return;
}
InitDefaultNamespace();
if (!InitSandboxWithName(sandbox)) {
INIT_LOGE("Failed init sandbox with name %s.", sandbox);
}
// DumpSandboxByName(sandbox);
if (PrepareSandbox(sandbox) != 0) {
INIT_LOGE("Failed prepare sandbox %s.", sandbox);
DestroySandbox(sandbox);
}
if (EnterDefaultNamespace() < 0) {
INIT_LOGE("Fail set default namespace.");
}
CloseDefaultNamespace();
}
void SystemInit(void)
{
SignalInit();
......@@ -98,6 +124,8 @@ void SystemInit(void)
if (sock >= 0) {
RegisterFdHoldWatcher(sock);
}
RegisterSandbox("system");
RegisterSandbox("chipset");
}
static void EnableDevKmsg(void)
......@@ -267,6 +295,24 @@ static int SystemDump(int id, const char *name, int argc, const char **argv)
}
#endif
static void IsEnableSandbox(void)
{
const char *name = "const.sandbox";
char value[MAX_BUFFER_LEN] = {0};
unsigned int len = MAX_BUFFER_LEN;
if (SystemReadParam(name, value, &len) != 0) {
INIT_LOGE("Failed read param.");
g_enableSandbox = false;
}
if (strcmp(value, "enable") == 0) {
INIT_LOGI("Support sandbox.");
g_enableSandbox = true;
} else {
INIT_LOGI("Not support sandbox.");
g_enableSandbox = false;
}
}
void SystemConfig(void)
{
InitServiceSpace();
......@@ -293,7 +339,7 @@ void SystemConfig(void)
AddCmdExecutor("display", SystemDump);
(void)AddCompleteJob("param:ohos.servicectrl.display", "ohos.servicectrl.display=*", "display system");
#endif
IsEnableSandbox();
// execute init
PostTrigger(EVENT_TRIGGER_BOOT, "pre-init", strlen("pre-init"));
PostTrigger(EVENT_TRIGGER_BOOT, "init", strlen("init"));
......@@ -304,3 +350,33 @@ void SystemRun(void)
{
StartParamService();
}
int SetServiceEnterSandbox(const char *path)
{
if (g_enableSandbox == false) {
return -1;
}
INIT_ERROR_CHECK(path != NULL, return -1, "Service path is null.");
if (strstr(path, "/system/bin") != NULL) {
if (strcmp(path, "/system/bin/sh") == 0) {
INIT_LOGI("Console cannot enter sandbox.");
} else if (strcmp(path, "/system/bin/hdcd") == 0) {
INIT_LOGI("Hdcd cannot enter sandbox.");
} else if (strcmp(path, "/system/bin/appspawn") == 0) {
INIT_LOGI("Appspawn cannot enter sandbox.");
} else if (strcmp(path, "/system/bin/ueventd") == 0) {
INIT_LOGI("Ueventd cannot enter sandbox.");
} else if (strcmp(path, "/system/bin/hilogd") == 0) {
INIT_LOGI("Hilogd cannot enter sandbox.");
} else {
INIT_ERROR_CHECK(EnterSandbox("system") == 0, return -1,
"Service %s failed enter sandbox system.", path);
}
} else if (strstr(path, "/vendor/bin") != NULL) {
INIT_ERROR_CHECK(EnterSandbox("system") == 0, return -1,
"Service %s failed enter sandbox system.", path);
} else {
INIT_LOGE("Service path %s is not support sandbox", path);
}
return 0;
}
......@@ -40,6 +40,7 @@ if (defined(ohos_lite)) {
"system",
"updater",
]
relative_install_dir = "platform-vndk"
install_enable = true
part_name = "init"
subsystem_name = "startup"
......
......@@ -38,6 +38,8 @@ ohos_unittest("init_ut") {
"//base/startup/init_lite/interfaces/innerkits/fs_manager/fstab_mount.c",
"//base/startup/init_lite/interfaces/innerkits/plugin/init_plugin.c",
"//base/startup/init_lite/interfaces/innerkits/reboot/init_reboot_innerkits.c",
"//base/startup/init_lite/interfaces/innerkits/sandbox/sandbox.c",
"//base/startup/init_lite/interfaces/innerkits/sandbox/sandbox_namespace.c",
"//base/startup/init_lite/interfaces/innerkits/socket/init_socket.c",
"//base/startup/init_lite/services/begetctl/param_cmd.c",
"//base/startup/init_lite/services/begetctl/shell/shell_bas.c",
......@@ -168,6 +170,7 @@ ohos_unittest("init_ut") {
"//third_party/cJSON",
"//base/security/access_token/interfaces/innerkits/token_setproc/include",
"//base/security/access_token/interfaces/innerkits/nativetoken/include",
"//base/startup/init_lite/interfaces/innerkits/sandbox/include",
]
deps = [
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册