diff --git a/interfaces/innerkits/BUILD.gn b/interfaces/innerkits/BUILD.gn index cfc746fc7cea872dd0e9c72e49ce4889f3d31d88..e4c8d9c2bdd1b4037e37e533aaced11f0ea47e1d 100755 --- a/interfaces/innerkits/BUILD.gn +++ b/interfaces/innerkits/BUILD.gn @@ -174,6 +174,7 @@ if (defined(ohos_lite)) { include_dirs = include_common deps = [ + "//base/customization/config_policy/frameworks/config_policy:configpolicy_util_for_init_static", "//base/startup/init/interfaces/innerkits/control_fd:libcontrolfd", "//base/startup/init/interfaces/innerkits/fd_holder:fdholder", "//base/startup/init/interfaces/innerkits/file:libfile", diff --git a/interfaces/innerkits/modulemgr/modulemgr.c b/interfaces/innerkits/modulemgr/modulemgr.c index 116b395fa138e4a08e8951a62f2f54d7adc50404..e60574fc2522dfb5cc4a75e87fc266175d2fd331 100644 --- a/interfaces/innerkits/modulemgr/modulemgr.c +++ b/interfaces/innerkits/modulemgr/modulemgr.c @@ -21,6 +21,7 @@ #include #include "beget_ext.h" +#include "config_policy_utils.h" #include "init_utils.h" #include "list.h" #include "securec.h" @@ -225,15 +226,22 @@ MODULE_MGR *ModuleMgrScan(const char *modulePath) BEGET_CHECK(moduleMgr != NULL, return NULL); if (modulePath[0] == '/') { - BEGET_CHECK(!(snprintf_s(path, sizeof(path), sizeof(path) - 1, "%s", modulePath) < 0), return NULL); + scanModules(moduleMgr, modulePath); + } else if (InUpdaterMode() == 1) { + BEGET_CHECK(snprintf_s(path, sizeof(path), sizeof(path) - 1, + "/%s/%s", MODULE_LIB_NAME, modulePath) > 0, return NULL); + scanModules(moduleMgr, path); } else { - const char *fmt = (InUpdaterMode() == 0) ? "/system/" MODULE_LIB_NAME : "/" MODULE_LIB_NAME; - BEGET_CHECK(!(snprintf_s(path, sizeof(path), sizeof(path) - 1, - "%s/%s", fmt, modulePath) < 0), return NULL); + BEGET_CHECK(snprintf_s(path, sizeof(path), sizeof(path) - 1, + "%s/%s", MODULE_LIB_NAME, modulePath) > 0, return NULL); + CfgFiles *files = GetCfgFiles(path); + for (int i = MAX_CFG_POLICY_DIRS_CNT - 1; files && i >= 0; i--) { + if (files->paths[i]) { + scanModules(moduleMgr, files->paths[i]); + } + } + FreeCfgFiles(files); } - - scanModules(moduleMgr, path); - return moduleMgr; } diff --git a/services/init/include/init_service.h b/services/init/include/init_service.h index e1ac68a37a134d9cb1ac864e29ea286afbc7e321..c41d80997638148e3dd70acbc3ce9a99a28fd4c1 100644 --- a/services/init/include/init_service.h +++ b/services/init/include/init_service.h @@ -48,7 +48,7 @@ extern "C" { #define SERVICE_ATTR_ONDEMAND 0x100 // ondemand, manage socket by init #define SERVICE_ATTR_TIMERSTART 0x200 // Mark a service will be started by timer #define SERVICE_ATTR_NEEDWAIT 0x400 // service should execute waitpid while stopping -#define SERVICE_ATTR_SANDBOX 0x800 // make service will enter sandbox +#define SERVICE_ATTR_WITHOUT_SANDBOX 0x800 // make service not enter sandbox #define MAX_SERVICE_NAME 32 #define MAX_APL_NAME 32 @@ -82,12 +82,13 @@ extern "C" { #define EnableServiceTimer(service) \ ((service)->attribute |= SERVICE_ATTR_TIMERSTART) -#define MarkServiceWithSandbox(service) \ - ((service)->attribute |= SERVICE_ATTR_SANDBOX) +#define MarkServiceWithoutSandbox(service) \ + ((service)->attribute |= SERVICE_ATTR_WITHOUT_SANDBOX) -#define UnMarkServiceWithSandbox(service) \ - ((service)->attribute &= ~SERVICE_ATTR_SANDBOX) +#define MarkServiceWithSandbox(service) \ + ((service)->attribute &= ~SERVICE_ATTR_WITHOUT_SANDBOX) +#pragma pack(4) typedef enum { START_MODE_CONDITION, START_MODE_BOOT, @@ -139,7 +140,7 @@ typedef struct Service_ { int endMode : 4; // preFork/ fork / exec / ready int status : 4; // ServiceStatus uint64_t tokenId; - char apl[MAX_APL_NAME + 1]; + char *apl; ServiceArgs capsArgs; ServiceArgs permArgs; ServiceArgs permAclsArgs; @@ -157,6 +158,7 @@ typedef struct Service_ { cpu_set_t cpuSet; struct ListNode extDataNode; } Service; +#pragma pack() Service *GetServiceByPid(pid_t pid); Service *GetServiceByName(const char *servName); diff --git a/services/init/init_capability.c b/services/init/init_capability.c index 2cdc8a9e17530cb8122856408767e509f91fe222..1d40f21b694d2b1e4c0f4114551f2730e242d162 100644 --- a/services/init/init_capability.c +++ b/services/init/init_capability.c @@ -88,8 +88,6 @@ int GetServiceCaps(const cJSON *curArrItem, Service *service) { INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "service is null ptr."); INIT_ERROR_CHECK(curArrItem != NULL, return SERVICE_FAILURE, "json is null ptr."); - service->servPerm.capsCnt = 0; - service->servPerm.caps = NULL; int capsCnt = 0; cJSON *filedJ = GetArrayItem(curArrItem, &capsCnt, "caps"); if (filedJ == NULL) { @@ -97,10 +95,14 @@ int GetServiceCaps(const cJSON *curArrItem, Service *service) } INIT_ERROR_CHECK(capsCnt <= MAX_CAPS_CNT_FOR_ONE_SERVICE, return SERVICE_FAILURE, "service=%s, too many caps[cnt %d] for one service", service->name, capsCnt); + service->servPerm.capsCnt = 0; + if (service->servPerm.caps != NULL) { + free(service->servPerm.caps); + service->servPerm.caps = NULL; + } service->servPerm.caps = (unsigned int *)calloc(1, sizeof(unsigned int) * capsCnt); INIT_ERROR_CHECK(service->servPerm.caps != NULL, return SERVICE_FAILURE, "Failed to malloc for service %s", service->name); - service->servPerm.capsCnt = 0; unsigned int caps = FULL_CAP; for (int i = 0; i < capsCnt; ++i) { // number form char *capStr = NULL; diff --git a/services/init/init_service_manager.c b/services/init/init_service_manager.c index 6b8d1a05bce86bb8c13d27c291e18f8604ed37ca..4acd6a5263de285e30e5153d0712398d91c086ea 100755 --- a/services/init/init_service_manager.c +++ b/services/init/init_service_manager.c @@ -140,6 +140,10 @@ void ReleaseService(Service *service) FreeServiceSocket(service->socketCfg); FreeServiceFile(service->fileCfg); + if(service->apl != NULL) { + free(service->apl); + service->apl = NULL; + } for (size_t i = 0; i < JOB_ON_MAX; i++) { if (service->serviceJobs.jobsName[i] != NULL) { free(service->serviceJobs.jobsName[i]); @@ -168,16 +172,6 @@ static char *GetStringValue(const cJSON *json, const char *name, size_t *strLen) return fieldStr; } -static int GetStringItem(const cJSON *json, const char *name, char *buffer, int buffLen) -{ - INIT_ERROR_CHECK(json != NULL, return SERVICE_FAILURE, "Invalid json for %s", name); - size_t strLen = 0; - char *fieldStr = GetStringValue(json, name, &strLen); - INIT_CHECK((fieldStr != NULL) && (strLen != 0) && (strLen <= (size_t)buffLen), - return SERVICE_FAILURE); - return strcpy_s(buffer, buffLen, fieldStr); -} - cJSON *GetArrayItem(const cJSON *fileRoot, int *arrSize, const char *arrName) { cJSON *arrItem = cJSON_GetObjectItemCaseSensitive(fileRoot, arrName); @@ -199,7 +193,9 @@ static int GetServiceArgs(const cJSON *argJson, const char *name, int maxCount, INIT_ERROR_CHECK(ret, return SERVICE_FAILURE, "Invalid type"); int count = cJSON_GetArraySize(obj); INIT_ERROR_CHECK((count > 0) && (count < maxCount), return SERVICE_FAILURE, "Array size = %d is wrong", count); - + if ((args->argv != NULL) && (args->count > 0)) { + FreeServiceArg(args); + } args->argv = (char **)malloc((count + 1) * sizeof(char *)); INIT_ERROR_CHECK(args->argv != NULL, return SERVICE_FAILURE, "Failed to malloc for argv"); for (int i = 0; i < count + 1; ++i) { @@ -257,7 +253,6 @@ static int GetServiceGids(const cJSON *curArrItem, Service *curServ) int gidCount; cJSON *arrItem = cJSON_GetObjectItemCaseSensitive(curArrItem, GID_STR_IN_CFG); if (!arrItem) { - curServ->servPerm.gIDCnt = 0; return SERVICE_SUCCESS; } else if (!cJSON_IsArray(arrItem)) { gidCount = 1; @@ -266,6 +261,9 @@ static int GetServiceGids(const cJSON *curArrItem, Service *curServ) } INIT_ERROR_CHECK((gidCount != 0) && (gidCount <= NGROUPS_MAX + 1), return SERVICE_FAILURE, "Invalid gid count %d", gidCount); + if (curServ->servPerm.gIDArray != NULL) { + free(curServ->servPerm.gIDArray); + } curServ->servPerm.gIDArray = (gid_t *)malloc(sizeof(gid_t) * gidCount); INIT_ERROR_CHECK(curServ->servPerm.gIDArray != NULL, return SERVICE_FAILURE, "Failed to malloc"); curServ->servPerm.gIDCnt = gidCount; @@ -300,10 +298,9 @@ static int GetServiceAttr(const cJSON *curArrItem, Service *curServ, const char } INIT_ERROR_CHECK(cJSON_IsNumber(filedJ), return SERVICE_FAILURE, "%s is null or is not a number, service name is %s", attrName, curServ->name); - + curServ->attribute &= ~flag; int value = (int)cJSON_GetNumberValue(filedJ); if (processAttr == NULL) { - curServ->attribute &= ~flag; if (value == 1) { curServ->attribute |= flag; } @@ -451,6 +448,9 @@ static int ParseServiceSocket(const cJSON *curArrItem, Service *curServ) int sockCnt = 0; cJSON *filedJ = GetArrayItem(curArrItem, &sockCnt, "socket"); INIT_CHECK(filedJ != NULL && sockCnt > 0, return SERVICE_FAILURE); + + CloseServiceSocket(curServ); + FreeServiceSocket(curServ->socketCfg); int ret = 0; curServ->socketCfg = NULL; for (int i = 0; i < sockCnt; ++i) { @@ -524,6 +524,7 @@ static int ParseServiceFile(const cJSON *curArrItem, Service *curServ) int fileCnt = 0; cJSON *filedJ = GetArrayItem(curArrItem, &fileCnt, "file"); INIT_CHECK(filedJ != NULL && fileCnt > 0, return SERVICE_FAILURE); + FreeServiceFile(curServ->fileCfg); int ret = 0; curServ->fileCfg = NULL; for (int i = 0; i < fileCnt; ++i) { @@ -545,6 +546,8 @@ static int GetServiceOnDemand(const cJSON *curArrItem, Service *curServ) INIT_ERROR_CHECK(cJSON_IsBool(item), return SERVICE_FAILURE, "Service : %s ondemand value only support bool.", curServ->name); + curServ->attribute &= ~SERVICE_ATTR_ONDEMAND; + INIT_INFO_CHECK(cJSON_IsTrue(item), return SERVICE_SUCCESS, "Service : %s ondemand value is false, it should be pulled up by init", curServ->name); if (curServ->attribute & SERVICE_ATTR_CRITICAL) { @@ -605,6 +608,10 @@ static int GetServiceJobs(Service *service, cJSON *json) for (int i = 0; i < (int)ARRAY_LENGTH(jobTypes); i++) { char *jobName = cJSON_GetStringValue(cJSON_GetObjectItem(json, jobTypes[i])); if (jobName != NULL) { + if (service->serviceJobs.jobsName[i] != NULL) { + DelGroupNode(NODE_TYPE_JOBS, service->serviceJobs.jobsName[i]); + free(service->serviceJobs.jobsName[i]); + } service->serviceJobs.jobsName[i] = strdup(jobName); // save job name for group job check AddGroupNode(NODE_TYPE_JOBS, jobName); @@ -695,7 +702,6 @@ static int GetCpuArgs(const cJSON *argJson, const char *name, Service *service) static int GetServiceSandbox(const cJSON *curItem, Service *service) { - MarkServiceWithSandbox(service); cJSON *item = cJSON_GetObjectItem(curItem, "sandbox"); if (item == NULL) { return SERVICE_SUCCESS; @@ -704,10 +710,10 @@ static int GetServiceSandbox(const cJSON *curItem, Service *service) 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); + if (isSandbox == 0) { + MarkServiceWithoutSandbox(service); } else { - UnMarkServiceWithSandbox(service); + MarkServiceWithSandbox(service); } return SERVICE_SUCCESS; @@ -791,7 +797,15 @@ static void ParseOneServiceArgs(const cJSON *curItem, Service *service) (void)GetServiceArgs(curItem, D_CAPS_STR_IN_CFG, MAX_WRITEPID_FILES, &service->capsArgs); (void)GetServiceArgs(curItem, "permission", MAX_WRITEPID_FILES, &service->permArgs); (void)GetServiceArgs(curItem, "permission_acls", MAX_WRITEPID_FILES, &service->permAclsArgs); - (void)GetStringItem(curItem, APL_STR_IN_CFG, service->apl, MAX_APL_NAME); + size_t strLen = 0; + char *fieldStr = GetStringValue(curItem, APL_STR_IN_CFG, &strLen); + if (fieldStr != NULL) { + if (service->apl != NULL) { + free(service->apl); + } + service->apl = strdup(fieldStr); + INIT_CHECK(service->apl != NULL, return); + } (void)GetCpuArgs(curItem, CPU_CORE_STR_IN_CFG, service); } @@ -967,26 +981,26 @@ void ParseAllServices(const cJSON *fileRoot) "Too many services[cnt %d] detected, should not exceed %d.", servArrSize, MAX_SERVICES_CNT_IN_FILE); - char serviceName[MAX_SERVICE_NAME] = {}; + size_t strLen = 0; for (int i = 0; i < servArrSize; ++i) { cJSON *curItem = cJSON_GetArrayItem(serviceArr, i); - int ret = GetStringItem(curItem, "name", serviceName, MAX_SERVICE_NAME); - if (ret != 0) { + char *fieldStr = GetStringValue(curItem, "name", &strLen); + if (fieldStr == NULL) { INIT_LOGE("Failed to get service name"); continue; } - Service *service = GetServiceByName(serviceName); + Service *service = GetServiceByName(fieldStr); if (service != NULL) { - INIT_LOGE("Service \' %s \' already exist", serviceName); + INIT_LOGE("Service \' %s \' already exist", fieldStr); continue; } - service = AddService(serviceName); + service = AddService(fieldStr); if (service == NULL) { - INIT_LOGE("Failed to create service name %s", serviceName); + INIT_LOGE("Failed to create service name %s", fieldStr); continue; } - - ret = ParseOneService(curItem, service); + service->pid = -1; + int ret = ParseOneService(curItem, service); if (ret != SERVICE_SUCCESS) { ReleaseService(service); service = NULL; @@ -1013,7 +1027,7 @@ void ParseAllServices(const cJSON *fileRoot) /* * Execute service parsing hooks */ - ParseServiceHookExecute(serviceName, curItem); + ParseServiceHookExecute(fieldStr, curItem); #endif ret = GetCmdLinesFromJson(cJSON_GetObjectItem(curItem, "onrestart"), &service->restartArg); @@ -1058,7 +1072,7 @@ static Service *GetServiceByExtServName(const char *fullServName) void StartServiceByName(const char *servName) { - INIT_LOGE("StartServiceByName Service %s", servName); + INIT_LOGI("StartServiceByName Service %s", servName); Service *service = GetServiceByName(servName); if (service == NULL) { service = GetServiceByExtServName(servName); diff --git a/services/init/standard/init.c b/services/init/standard/init.c index 1b8bf5b2b1eaec0340506b814f5e2df7bf0f50fa..17a6b4ed3345796fd58f7f43058d6e1744142020 100755 --- a/services/init/standard/init.c +++ b/services/init/standard/init.c @@ -374,7 +374,7 @@ void SetServiceEnterSandbox(const char *execPath, unsigned int attribute) if (g_enableSandbox == false) { return; } - if ((attribute & SERVICE_ATTR_SANDBOX) != SERVICE_ATTR_SANDBOX) { + if ((attribute & SERVICE_ATTR_WITHOUT_SANDBOX) == SERVICE_ATTR_WITHOUT_SANDBOX) { return; } INIT_ERROR_CHECK(execPath != NULL, return, "Service path is null."); diff --git a/services/init/standard/init_service.c b/services/init/standard/init_service.c index 3ecd08266b461afb52acaa3132f8e2bb55ac658c..4fc0a0f0936aab08478d3727f25d8bee076bfa5b 100644 --- a/services/init/standard/init_service.c +++ b/services/init/standard/init_service.c @@ -107,8 +107,9 @@ void GetAccessToken(void) if (service->capsArgs.count == 0) { service->capsArgs.argv = NULL; } - if (strlen(service->apl) == 0) { - (void)strncpy_s(service->apl, sizeof(service->apl), "system_basic", sizeof(service->apl) - 1); + const char *apl = "system_basic"; + if (service->apl != NULL) { + apl = service->apl; } NativeTokenInfoParams nativeTokenInfoParams = { service->capsArgs.count, @@ -118,8 +119,9 @@ void GetAccessToken(void) (const char **)service->permArgs.argv, (const char **)service->permAclsArgs.argv, service->name, - service->apl, + apl, }; + uint64_t tokenId = GetAccessTokenId(&nativeTokenInfoParams); INIT_CHECK_ONLY_ELOG(tokenId != 0, "Get totken id %lld of service \' %s \' failed", tokenId, service->name); diff --git a/services/modules/bootevent/bootevent.c b/services/modules/bootevent/bootevent.c index 19524b2ed38fddf142abb661f9423f2b09fdf1f5..f5f775385edbb8b6b6d03a2134c2349f84d2cfdf 100755 --- a/services/modules/bootevent/bootevent.c +++ b/services/modules/bootevent/bootevent.c @@ -137,6 +137,9 @@ static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx) if (bootEvents == NULL) { return; } + SERVICE_INFO_CTX ctx = {0}; + ctx.serviceName = serviceParseCtx->serviceName; + HookMgrExecute(GetBootStageHookMgr(), INIT_SERVICE_CLEAR, (void *)&ctx, NULL); // Single bootevent in config file if (!cJSON_IsArray(bootEvents)) { if (AddServiceBootEvent(serviceParseCtx->serviceName, diff --git a/services/modules/selinux/selinux_static.c b/services/modules/selinux/selinux_static.c index ebf0ef66239da0b759a76883a72f81e74d0f4ec2..ae1db26e13cfbb9755b4f0bb09f00f8951090f58 100755 --- a/services/modules/selinux/selinux_static.c +++ b/services/modules/selinux/selinux_static.c @@ -25,16 +25,17 @@ static int SelinuxHook(const HOOK_INFO *hookInfo, void *cookie) return 0; } -static void ServiceParseBootEventHook(SERVICE_PARSE_CTX *serviceParseCtx) +static void ServiceParseSelinuxHook(SERVICE_PARSE_CTX *serviceParseCtx) { char *fieldStr = cJSON_GetStringValue(cJSON_GetObjectItem(serviceParseCtx->serviceNode, SECON_STR_IN_CFG)); PLUGIN_CHECK(fieldStr != NULL, return, "No secon item in %s", serviceParseCtx->serviceName); PLUGIN_LOGV("Cfg %s for %s", fieldStr, serviceParseCtx->serviceName); + DelServiceExtData(serviceParseCtx->serviceName, HOOK_ID_SELINUX); AddServiceExtData(serviceParseCtx->serviceName, HOOK_ID_SELINUX, fieldStr, strlen(fieldStr) + 1); } MODULE_CONSTRUCTOR(void) { - InitAddServiceParseHook(ServiceParseBootEventHook); + InitAddServiceParseHook(ServiceParseSelinuxHook); InitAddGlobalInitHook(0, SelinuxHook); -} \ No newline at end of file +}