diff --git a/interfaces/innerkits/sandbox/sandbox.c b/interfaces/innerkits/sandbox/sandbox.c index e8249137c18a001ffc558bc5d5187489ae029158..15aaf9c3b664eb1e0811bd64b84be40f3ab31ba9 100644 --- a/interfaces/innerkits/sandbox/sandbox.c +++ b/interfaces/innerkits/sandbox/sandbox.c @@ -594,12 +594,12 @@ void DestroySandbox(const char *name) int EnterSandbox(const char *name) { if (name == NULL) { - BEGET_LOGE("Destroy sandbox name is NULL."); + BEGET_LOGE("Sandbox name is NULL."); return -1; } struct SandboxMap *map = GetSandboxMapByName(name); if (map == NULL) { - BEGET_LOGE("Failed get sandbox map by name %s.", name); + BEGET_LOGE("Failed to get sandbox map by name %s.", name); return -1; } sandbox_t *sandbox = map->sandbox; @@ -608,16 +608,16 @@ int EnterSandbox(const char *name) return -1; } if (sandbox->isCreated == false) { - BEGET_LOGE("Sandbox has not created."); + BEGET_LOGE("Sandbox %s has not been created.", name); return -1; } if (sandbox->ns > 0) { if (SetNamespce(sandbox->ns, CLONE_NEWNS) < 0) { - BEGET_LOGE("Failed set namespace CLONE_NEWNS, err=%d.", errno); + BEGET_LOGE("Failed to enter mount namespace for sandbox \' %s \', err=%d.", name, errno); return -1; } } else { - BEGET_LOGE("System sandbox namespace fd is error."); + BEGET_LOGE("Sandbox \' %s \' namespace fd is invalid.", name); return -1; } return 0; diff --git a/services/etc/init.cfg b/services/etc/init.cfg index 12ce1e83fc23a799d9631e1b6ef7e76698b3d9a0..f0855f46fa45bc555ccee7312aaaa882633f0802 100755 --- a/services/etc/init.cfg +++ b/services/etc/init.cfg @@ -15,11 +15,14 @@ "mkdir /dev/memcg/system 0550 system system", "start ueventd", "start watchdog_service", - "sleep 2", + "mkdir /data", + "mount_fstab /vendor/etc/fstab.${ohos.boot.hardware}", "chown system system /data", "chmod 0771 /data", "mkdir /data/service 0711 root root", "mkdir /data/service/el0 0711 root root", + "mksandbox system", + "mksandbox chipset", "load_persist_params ", "chown access_token access_token /dev/access_token_id", "chmod 0666 /dev/access_token_id" @@ -455,6 +458,7 @@ }], "critical" : [ 0, 15, 5], "ondemand" : true, + "sandbox" : 0, "start-mode" : "condition" }, { "name" : "console", @@ -462,6 +466,7 @@ "start-mode" : "condition", "disabled" : 1, "console" : 1, + "sandbox" : 0, "uid" : "root", "gid" : ["shell", "log", "readproc"], "jobs" : { @@ -472,6 +477,7 @@ "start-mode" : "condition", "path" : ["/system/bin/watchdog_service", "10", "2"], "disabled" : 1, + "sandbox" : 0, "uid" : "root", "gid" : ["shell", "log", "readproc"] }, { diff --git a/services/etc/init.usb.cfg b/services/etc/init.usb.cfg index 8b5711a0aeb8452b2ba0936e3cfb6888539b98ff..885635b7c3f4160b5ea296d03eeb25ff816e5203 100755 --- a/services/etc/init.usb.cfg +++ b/services/etc/init.usb.cfg @@ -28,6 +28,7 @@ "uid" : "system", "gid" : "system" }], + "sandbox" : 0, "start-mode" : "condition", "disabled" : 1 } diff --git a/services/init/include/init.h b/services/init/include/init.h index caf3b71ab48d86711eb5d69bd2920246b8660d91..f3dcc22cec5eff97c12c1199bc353a0e89161533 100755 --- a/services/init/include/init.h +++ b/services/init/include/init.h @@ -43,7 +43,7 @@ void SystemExecuteRcs(void); void ReadConfig(void); void SignalInit(void); -int SetServiceEnterSandbox(const char *path); +void SetServiceEnterSandbox(const char *path, unsigned int attribute); #ifdef __cplusplus #if __cplusplus diff --git a/services/init/include/init_service.h b/services/init/include/init_service.h index 450f0a57af21366656cf2f331eb7e1a8f10e449b..f46b97d4a762fe0006e92a0df0d00ab3028a6c3c 100755 --- a/services/init/include/init_service.h +++ b/services/init/include/init_service.h @@ -51,6 +51,7 @@ extern "C" { #define SERVICE_ATTR_DYNAMIC 0x100 // dynamic service #define SERVICE_ATTR_ONDEMAND 0x200 // ondemand, manage socket by init #define SERVICE_ATTR_TIMERSTART 0x400 // Mark a service will be started by timer +#define SERVICE_ATTR_SANDBOX 0x800 // make service will enter sandbox #define MAX_SERVICE_NAME 32 #define MAX_APL_NAME 32 @@ -78,6 +79,12 @@ extern "C" { #define EnableServiceTimer(service) \ ((service)->attribute |= SERVICE_ATTR_TIMERSTART) +#define MarkServiceWithSandbox(service) \ + ((service)->attribute |= SERVICE_ATTR_SANDBOX) + +#define UnMarkServiceWithSandbox(service) \ + ((service)->attribute &= ~SERVICE_ATTR_SANDBOX) + typedef enum { START_MODE_CONDITION, START_MODE_BOOT, diff --git a/services/init/include/init_service_manager.h b/services/init/include/init_service_manager.h index 36a726dcce95b4ea142cfd93b4897b9de53d340d..19e868aeaa128e28162d2e72796b0f8500c16bb2 100755 --- a/services/init/include/init_service_manager.h +++ b/services/init/include/init_service_manager.h @@ -33,6 +33,7 @@ extern "C" { #define CRITICAL_STR_IN_CFG "critical" #define DISABLED_STR_IN_CFG "disabled" #define CONSOLE_STR_IN_CFG "console" +#define SANDBOX_STR_IN_CFG "sandbox" #define D_CAPS_STR_IN_CFG "d-caps" #define APL_STR_IN_CFG "apl" #define CPU_CORE_STR_IN_CFG "cpucore" diff --git a/services/init/init_common_service.c b/services/init/init_common_service.c index 80ea418e0d70511ba4fc242e0909836b8ea33123..79018cca7a6833aef24e971f383123c1fe2d8050 100755 --- a/services/init/init_common_service.c +++ b/services/init/init_common_service.c @@ -280,8 +280,7 @@ int ServiceStart(Service *service) } int pid = fork(); if (pid == 0) { - INIT_CHECK_ONLY_ELOG(SetServiceEnterSandbox(service->pathArgs.argv[0]) == SERVICE_SUCCESS, - "Failed %s sandbox.", service->name); + SetServiceEnterSandbox(service->pathArgs.argv[0], service->attribute); INIT_CHECK_ONLY_ELOG(SetAccessToken(service) == SERVICE_SUCCESS, "access token failed %s", service->name); // deal start job diff --git a/services/init/init_service_manager.c b/services/init/init_service_manager.c index ab955cd9a773b6dbd530a0c685f1ca1a3065234b..5f563a7bc9ea5f2fa0788478277f46e340085fa7 100755 --- a/services/init/init_service_manager.c +++ b/services/init/init_service_manager.c @@ -641,7 +641,7 @@ static int CheckServiceKeyName(const cJSON *curService) char *cfgServiceKeyList[] = { "name", "path", "uid", "gid", "once", "importance", "caps", "disabled", "writepid", "critical", "socket", "console", "dynamic", "file", "ondemand", - "d-caps", "apl", "jobs", "start-mode", "end-mode", "cpucore", "secon" + "d-caps", "apl", "jobs", "start-mode", "end-mode", "cpucore", "secon", "sandbox" }; INIT_CHECK_RETURN_VALUE(curService != NULL, SERVICE_FAILURE); cJSON *child = curService->child; @@ -788,6 +788,26 @@ static int GetCpuArgs(const cJSON *argJson, const char *name, Service *service) return SERVICE_SUCCESS; } +static int GetServiceSandbox(const cJSON *curItem, Service *service) +{ + MarkServiceWithSandbox(service); + cJSON *item = cJSON_GetObjectItem(curItem, "sandbox"); + if (item == NULL) { + return SERVICE_SUCCESS; + } + + INIT_ERROR_CHECK(cJSON_IsNumber(item), return SERVICE_FAILURE, + "Service : %s sandbox value only support number.", service->name); + int isSandbox = (int)cJSON_GetNumberValue(item); + if (isSandbox == 1) { + MarkServiceWithSandbox(service); + } else { + UnMarkServiceWithSandbox(service); + } + + return SERVICE_SUCCESS; +} + int ParseOneService(const cJSON *curItem, Service *service) { INIT_CHECK_RETURN_VALUE(curItem != NULL && service != NULL, SERVICE_FAILURE); @@ -822,6 +842,8 @@ int ParseOneService(const cJSON *curItem, Service *service) (void)GetServiceArgs(curItem, D_CAPS_STR_IN_CFG, MAX_WRITEPID_FILES, &service->capsArgs); (void)GetStringItem(curItem, APL_STR_IN_CFG, service->apl, MAX_APL_NAME); (void)GetCpuArgs(curItem, CPU_CORE_STR_IN_CFG, service); + ret = GetServiceSandbox(curItem, service); + INIT_ERROR_CHECK(ret == 0, return SERVICE_FAILURE, "Failed to get sandbox for service %s", service->name); ret = GetServiceCaps(curItem, service); INIT_ERROR_CHECK(ret == 0, return SERVICE_FAILURE, "Failed to get caps for service %s", service->name); ret = GetDynamicService(curItem, service); diff --git a/services/init/lite/init.c b/services/init/lite/init.c index b170efa081bb2acfcf6a119b6c0b1f33eeae05e7..2530754debd9885dc2052c5f52fede78b35146b7 100755 --- a/services/init/lite/init.c +++ b/services/init/lite/init.c @@ -83,8 +83,9 @@ void SystemRun(void) LE_RunLoop(LE_GetDefaultLoop()); } -int SetServiceEnterSandbox(const char *path) +void SetServiceEnterSandbox(const char *path, unsigned int attribute) { UNUSED(path); - return -1; + UNUSED(attribute); + return; } diff --git a/services/init/standard/init.c b/services/init/standard/init.c index d806b8119fcc3b432ee5fe316b3fd02e8b15850f..4135a10638cf639a5046942bf3845e1e0367b478 100755 --- a/services/init/standard/init.c +++ b/services/init/standard/init.c @@ -92,27 +92,6 @@ 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); - } - - 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(); @@ -123,8 +102,6 @@ void SystemInit(void) if (sock >= 0) { RegisterFdHoldWatcher(sock); } - RegisterSandbox("system"); - RegisterSandbox("chipset"); } static void EnableDevKmsg(void) @@ -304,10 +281,10 @@ static void IsEnableSandbox(void) g_enableSandbox = false; } if (strcmp(value, "enable") == 0) { - INIT_LOGI("Support sandbox."); + INIT_LOGI("Enable sandbox."); g_enableSandbox = true; } else { - INIT_LOGI("Not support sandbox."); + INIT_LOGI("Disable sandbox."); g_enableSandbox = false; } } @@ -350,32 +327,30 @@ void SystemRun(void) StartParamService(); } -int SetServiceEnterSandbox(const char *path) +void SetServiceEnterSandbox(const char *execPath, unsigned int attribute) { if (g_enableSandbox == false) { - return -1; + return; } - 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."); + if ((attribute & SERVICE_ATTR_SANDBOX) != SERVICE_ATTR_SANDBOX) { + return; + } + INIT_ERROR_CHECK(execPath != NULL, return, "Service path is null."); + if (strncmp(execPath, "/system/bin/", strlen("/system/bin/")) == 0) { + if (strcmp(execPath, "/system/bin/appspawn") == 0) { + INIT_LOGI("Appspawn skip enter sandbox."); + } else if (strcmp(execPath, "/system/bin/hilogd") == 0) { + INIT_LOGI("Hilogd skip enter sandbox."); } else { - INIT_ERROR_CHECK(EnterSandbox("system") == 0, return -1, - "Service %s failed enter sandbox system.", path); + INIT_ERROR_CHECK(EnterSandbox("system") == 0, return, + "Service %s failed enter sandbox system.", execPath); } - } else if (strstr(path, "/vendor/bin") != NULL) { - INIT_ERROR_CHECK(EnterSandbox("system") == 0, return -1, - "Service %s failed enter sandbox system.", path); + } else if (strncmp(execPath, "/vendor/bin/", strlen("/vendor/bin/")) == 0) { + // chipset sandbox will be implemented later. + INIT_ERROR_CHECK(EnterSandbox("system") == 0, return, + "Service %s failed enter sandbox system.", execPath); } else { - INIT_LOGE("Service path %s is not support sandbox", path); + INIT_LOGE("Service %s does not enter sandbox", execPath); } - return 0; + return; } diff --git a/services/init/standard/init_cmds.c b/services/init/standard/init_cmds.c index eda20e21873090711e75c244705a71e7515a86c4..cfbe00430fdf1b94e5e3f4a8567fc9378662fd72 100755 --- a/services/init/standard/init_cmds.c +++ b/services/init/standard/init_cmds.c @@ -37,6 +37,8 @@ #include "init_param.h" #include "init_service_manager.h" #include "init_utils.h" +#include "sandbox.h" +#include "sandbox_namespace.h" #include "securec.h" #ifdef WITH_SELINUX #include @@ -504,6 +506,34 @@ static void DoSwapon(const struct CmdArgs *ctx) INIT_LOGI("DoSwapon: end, ret = %d", ret); } +static void DoMkSandbox(const struct CmdArgs *ctx) +{ + INIT_LOGI("DoMkSandbox: start"); + if ((ctx == NULL) || (ctx->argc != 1)){ + INIT_LOGE("Call DoMkSandbox with invalid arguments"); + return; + } + + const char *sandbox = ctx->argv[0]; + if (sandbox == NULL) { + INIT_LOGE("Invaild sandbox name."); + return; + } + InitDefaultNamespace(); + if (!InitSandboxWithName(sandbox)) { + INIT_LOGE("Failed to init sandbox with name %s.", sandbox); + } + + if (PrepareSandbox(sandbox) != 0) { + INIT_LOGE("Failed to prepare sandbox %s.", sandbox); + DestroySandbox(sandbox); + } + if (EnterDefaultNamespace() < 0) { + INIT_LOGE("Failed to set default namespace."); + } + CloseDefaultNamespace(); +} + static const struct CmdTable g_cmdTable[] = { { "exec ", 1, 10, DoExec }, { "mknode ", 1, 5, DoMakeNode }, @@ -528,6 +558,7 @@ static const struct CmdTable g_cmdTable[] = { { "init_main_user ", 0, 1, DoInitMainUser }, { "mkswap", 1, 1, DoMkswap}, { "swapon", 1, 1, DoSwapon}, + { "mksandbox", 1, 1, DoMkSandbox}, }; const struct CmdTable *GetCmdTable(int *number)