提交 6023fe40 编写于 作者: C cheng_jinsong

Duplicate service attributes add and replace

Signed-off-by: Ncheng_jinsong <chengjinsong2@huawei.com>
上级 f1d3862a
......@@ -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",
......
......@@ -21,6 +21,7 @@
#include <linux/limits.h>
#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;
}
......
......@@ -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);
......
......@@ -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;
......
......@@ -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);
......
......@@ -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.");
......
......@@ -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);
......
......@@ -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,
......
......@@ -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
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册