Merge branch 'master' of gitee.com:openharmony/startup_init into 0821_mem

Signed-off-by: 钟柠 <zhongning5@huawei.com>
This commit is contained in:
钟柠 2023-08-30 07:16:35 +00:00 committed by zhongning5
commit 0096b689bf
34 changed files with 483 additions and 412 deletions

View File

@ -121,11 +121,13 @@ int DoFormat(const char *devPath, const char *fsType)
} else if (strcmp(fsType, "f2fs") == 0) {
#ifdef __MUSL__
char *formatCmds[] = {
"/bin/mkfs.f2fs", "-d1", "-O", "encrypt", "-O", "quota", "-O", "verity", (char *)devPath, NULL
"/bin/mkfs.f2fs", "-d1", "-O", "encrypt", "-O", "quota", "-O", "verity", "-O", "project_quota,extra_attr",
"-O", "sb_checksum", (char *)devPath, NULL
};
#else
char *formatCmds[] = {
"/bin/make_f2fs", "-d1", "-O", "encrypt", "-O", "quota", "-O", "verity", (char *)devPath, NULL
"/bin/make_f2fs", "-d1", "-O", "encrypt", "-O", "quota", "-O", "verity", "-O", "project_quota,extra_attr",
"-O", "sb_checksum", (char *)devPath, NULL
};
#endif
int argc = ARRAY_LENGTH(formatCmds);

View File

@ -0,0 +1,69 @@
/*
* Copyright (c) 2023 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 INIT_ERROR_H
#define INIT_ERROR_H
#include "beget_ext.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
/* Expand this list if necessary. */
#define INIT_ERRNO_MAP(XX) \
XX(EPARAMETER, "Invalid parameter") \
XX(EFORMAT, "Format string fail") \
XX(ECFG, "cfg error") \
XX(EPATH, "Invalid path") \
XX(EFORK, "Fork fail") \
XX(ESANDBOX, "Create sandbox fail") \
XX(EACCESSTOKEN, "Set access token fail") \
XX(ESOCKET, "Create socket fail") \
XX(EFILE, "Create file fail") \
XX(ECONSOLE, "Open console fail") \
XX(EHOLDER, "Publish holder fail") \
XX(EBINDCORE, "Bind core fail") \
XX(EKEEPCAP, "Set keep capability fail") \
XX(EGIDSET, "Set gid fail") \
XX(ESECCOMP, "Set SECCOMP fail") \
XX(EUIDSET, "Set uid fail") \
XX(ECAP, "Set capability fail") \
XX(EWRITEPID, "Write pid fail") \
XX(ECONTENT, "Set sub content fail") \
XX(EPRIORITY, "Set priority fail") \
XX(EEXEC_CONTENT, "Set exec content fail") \
XX(EEXEC, "Exec fail")
typedef enum {
INIT_OK,
#define XX(code, _) INIT_ ## code,
INIT_ERRNO_MAP(XX)
#undef XX
} InitErrno;
struct InitErrMap {
int code;
const char *info;
} ;
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // INIT_UTILS_H

View File

@ -78,7 +78,7 @@ void FreeStringVector(char **vector, int count);
int InUpdaterMode(void);
int StringReplaceChr(char *strl, char oldChr, char newChr);
void OpenConsole(void);
int OpenConsole(void);
void TrimTail(char *str, char c);
char *TrimHead(char *str, char c);
@ -87,7 +87,6 @@ INIT_LOCAL_API uint32_t IntervalTime(struct timespec *startTime, struct timespec
INIT_LOCAL_API int StringToULL(const char *str, unsigned long long int *out);
INIT_LOCAL_API int StringToLL(const char *str, long long int *out);
void CloseStdio(void);
void RedirectStdio(int fd);
int GetServiceGroupIdByPid(pid_t pid, gid_t *gids, uint32_t gidSize);
int GetParameterFromCmdLine(const char *paramName, char *value, size_t valueLen);

View File

@ -22,6 +22,7 @@
#include "cJSON.h"
#include "init_cmds.h"
#include "init_error.h"
#include "init_service_file.h"
#include "init_service_socket.h"
#include "list.h"
@ -149,7 +150,6 @@ typedef struct Service_ {
ServiceArgs permAclsArgs;
Perms servPerm;
ServiceArgs pathArgs;
ServiceArgs extraArgs;
ServiceArgs writePidArgs;
CmdLines *restartArg;
ServiceSocket *socketCfg;
@ -161,12 +161,13 @@ typedef struct Service_ {
cpu_set_t *cpuSet;
struct ListNode extDataNode;
ConfigContext context;
InitErrno lastErrno;
} Service;
#pragma pack()
Service *GetServiceByPid(pid_t pid);
Service *GetServiceByName(const char *servName);
int ServiceStart(Service *service);
int ServiceStart(Service *service, ServiceArgs *pathArgs);
int ServiceStop(Service *service);
void ServiceReap(Service *service);
void ReapService(Service *service);
@ -175,7 +176,7 @@ void NotifyServiceChange(Service *service, int status);
int IsForbidden(const char *fieldStr);
int SetImportantValue(Service *curServ, const char *attrName, int value, int flag);
int InitServiceCaps(const cJSON *curArrItem, Service *curServ);
int ServiceExec(const Service *service);
int ServiceExec(Service *service, const ServiceArgs *pathArgs);
void CloseServiceFds(Service *service, bool needFree);
int UpdaterServiceFds(Service *service, int *fds, size_t fdCount);
int SetAccessToken(const Service *service);
@ -184,7 +185,10 @@ void ServiceStopTimer(Service *service);
void ServiceStartTimer(Service *service, uint64_t timeout);
void IsEnableSandbox(void);
void EnterServiceSandbox(Service *service);
void SetServiceEnterSandbox(const char *execPath, unsigned int attribute);
int SetServiceEnterSandbox(const Service *service, const char *execPath);
int CreateServiceFile(Service *service);
void CloseServiceFile(ServiceFile *fileOpt);
#ifdef __cplusplus
#if __cplusplus
}

View File

@ -41,9 +41,6 @@ typedef struct ServiceFile_ {
char fileName[0];
} ServiceFile;
void CreateServiceFile(ServiceFile *fileOpt);
void CloseServiceFile(ServiceFile *fileOpt);
#ifdef __cplusplus
#if __cplusplus
}

View File

@ -134,21 +134,21 @@ static void ServiceHookExecute(const char *serviceName, const char *info, int st
}
#endif
static int ServiceCheck(const Service *service)
static int ServiceSetGid(const Service *service)
{
if (service->servPerm.gIDCnt == 0) {
// use uid as gid
INIT_ERROR_CHECK(setgid(service->servPerm.uID) == 0, return SERVICE_FAILURE,
"SetPerms, setgid for %s failed. %d", service->name, errno);
"Service error %d %s, failed to set gid.", errno, service->name);
}
if (service->servPerm.gIDCnt > 0) {
INIT_ERROR_CHECK(setgid(service->servPerm.gIDArray[0]) == 0, return SERVICE_FAILURE,
"SetPerms, setgid for %s failed. %d", service->name, errno);
"Service error %d %s, failed to set gid.", errno, service->name);
}
if (service->servPerm.gIDCnt > 1) {
INIT_ERROR_CHECK(setgroups(service->servPerm.gIDCnt - 1, (const gid_t *)&service->servPerm.gIDArray[1]) == 0,
return SERVICE_FAILURE,
"SetPerms, setgroups failed. errno = %d, gIDCnt=%d", errno, service->servPerm.gIDCnt);
"Service error %d %s, failed to set gid.", errno, service->name);
}
return SERVICE_SUCCESS;
@ -156,20 +156,23 @@ static int ServiceCheck(const Service *service)
static int SetPerms(const Service *service)
{
INIT_CHECK_RETURN_VALUE(KeepCapability() == 0, SERVICE_FAILURE);
INIT_ERROR_CHECK(KeepCapability() == 0,
return INIT_EKEEPCAP,
"Service error %d %s, failed to set keep capability.", errno, service->name);
INIT_ERROR_CHECK(ServiceCheck(service) == SERVICE_SUCCESS, return SERVICE_FAILURE,
"set seccomp policy failed for service %s", service->name);
INIT_ERROR_CHECK(ServiceSetGid(service) == SERVICE_SUCCESS,
return INIT_EGIDSET,
"Service error %d %s, failed to set gid.", errno, service->name);
// set seccomp policy before setuid
INIT_ERROR_CHECK(SetSystemSeccompPolicy(service) == SERVICE_SUCCESS, return SERVICE_FAILURE,
"set seccomp policy failed for service %s", service->name);
INIT_ERROR_CHECK(SetSystemSeccompPolicy(service) == SERVICE_SUCCESS,
return INIT_ESECCOMP,
"Service error %d %s, failed to set system seccomp policy.", errno, service->name);
if (service->servPerm.uID != 0) {
if (setuid(service->servPerm.uID) != 0) {
INIT_LOGE("setuid of service: %s failed, uid = %d", service->name, service->servPerm.uID);
return SERVICE_FAILURE;
}
INIT_ERROR_CHECK(setuid(service->servPerm.uID) == 0,
return INIT_EUIDSET,
"Service error %d %s, failed to set uid.", errno, service->name);
}
struct __user_cap_header_struct capHeader;
@ -194,10 +197,15 @@ static int SetPerms(const Service *service)
"capset failed for service: %s, error: %d", service->name, errno);
for (unsigned int i = 0; i < service->servPerm.capsCnt; ++i) {
if (service->servPerm.caps[i] == FULL_CAP) {
return SetAllAmbientCapability();
int ret = SetAllAmbientCapability();
INIT_ERROR_CHECK(ret == 0,
return INIT_ECAP,
"Service error %d %s, failed to set ambient capability.", errno, service->name);
return 0;
}
INIT_ERROR_CHECK(SetAmbientCapability(service->servPerm.caps[i]) == 0, return SERVICE_FAILURE,
"SetAmbientCapability failed for service: %s", service->name);
INIT_ERROR_CHECK(SetAmbientCapability(service->servPerm.caps[i]) == 0,
return INIT_ECAP,
"Service error %d %s, failed to set ambient capability.", errno, service->name);
}
#ifndef OHOS_LITE
/*
@ -260,30 +268,33 @@ void CloseServiceFds(Service *service, bool needFree)
}
}
static void PublishHoldFds(Service *service)
static int PublishHoldFds(Service *service)
{
INIT_ERROR_CHECK(service != NULL, return, "Publish hold fds with invalid service");
char fdBuffer[MAX_FD_HOLDER_BUFFER] = {};
if (service->fdCount > 0 && service->fds != NULL) {
size_t pos = 0;
for (size_t i = 0; i < service->fdCount; i++) {
int fd = dup(service->fds[i]);
if (fd < 0) {
INIT_LOGE("Duplicate file descriptors of Service \' %s \' failed. err = %d", service->name, errno);
continue;
}
INIT_ERROR_CHECK(!(snprintf_s((char *)fdBuffer + pos, sizeof(fdBuffer) - pos, sizeof(fdBuffer) - 1,
"%d ", fd) < 0), return, "snprintf_s failed err=%d", errno);
pos = strlen(fdBuffer);
}
fdBuffer[pos - 1] = '\0'; // Remove last ' '
INIT_LOGI("fd buffer: [%s]", fdBuffer);
char envName[MAX_BUFFER_LEN] = {};
INIT_ERROR_CHECK(!(snprintf_s(envName, MAX_BUFFER_LEN, MAX_BUFFER_LEN - 1, ENV_FD_HOLD_PREFIX"%s",
service->name) < 0), return, "snprintf_s failed err=%d", errno);
INIT_CHECK_ONLY_ELOG(!(setenv(envName, fdBuffer, 1) < 0), "Failed to set env %s", envName);
INIT_LOGI("File descriptors of Service \' %s \' published", service->name);
INIT_ERROR_CHECK(service != NULL, return INIT_EPARAMETER, "Publish hold fds with invalid service");
if (service->fdCount == 0 || service->fds == NULL) {
return 0;
}
char fdBuffer[MAX_FD_HOLDER_BUFFER] = {};
char envName[MAX_BUFFER_LEN] = {};
int ret = snprintf_s(envName, MAX_BUFFER_LEN, MAX_BUFFER_LEN - 1, ENV_FD_HOLD_PREFIX"%s", service->name);
INIT_ERROR_CHECK(ret >= 0, return INIT_EFORMAT,
"Service error %d %s, failed to format string for publish", ret, service->name);
size_t pos = 0;
for (size_t i = 0; i < service->fdCount; i++) {
int fd = dup(service->fds[i]);
if (fd < 0) {
INIT_LOGW("Service warning %d %s, failed to dup fd for publish", errno, service->name);
continue;
}
ret = snprintf_s((char *)fdBuffer + pos, sizeof(fdBuffer) - pos, sizeof(fdBuffer) - 1, "%d ", fd);
INIT_ERROR_CHECK(ret >= 0, return INIT_EFORMAT,
"Service error %d %s, failed to format fd for publish", ret, service->name);
pos += ret;
}
fdBuffer[pos - 1] = '\0'; // Remove last ' '
INIT_LOGI("Service %s publish fd [%s]", service->name, fdBuffer);
return setenv(envName, fdBuffer, 1);
}
static int BindCpuCore(Service *service)
@ -315,45 +326,71 @@ static void ClearEnvironment(Service *service)
return;
}
static int InitServiceProperties(Service *service)
static int InitServiceProperties(Service *service, const ServiceArgs *pathArgs)
{
INIT_ERROR_CHECK(service != NULL, return -1, "Invalid parameter.");
SetServiceEnterSandbox(service->pathArgs.argv[0], service->attribute);
INIT_CHECK_ONLY_ELOG(SetAccessToken(service) == SERVICE_SUCCESS,
"Set service %s access token failed", service->name);
int ret = SetServiceEnterSandbox(service, pathArgs->argv[0]);
if (ret != 0) {
INIT_LOGW("Service warning %d %s, failed to enter sandbox.", ret, service->name);
service->lastErrno = INIT_ESANDBOX;
}
ret = SetAccessToken(service);
if (ret != 0) {
INIT_LOGW("Service warning %d %s, failed to set access token.", ret, service->name);
service->lastErrno = INIT_EACCESSTOKEN;
}
// deal start job
if (service->serviceJobs.jobsName[JOB_ON_START] != NULL) {
DoJobNow(service->serviceJobs.jobsName[JOB_ON_START]);
}
ClearEnvironment(service);
if (!IsOnDemandService(service)) {
INIT_ERROR_CHECK(CreateServiceSocket(service) >= 0, return -1,
"service %s exit! create socket failed!", service->name);
INIT_ERROR_CHECK(CreateServiceSocket(service) == 0,
service->lastErrno = INIT_ESOCKET;
return INIT_ESOCKET,
"Service error %d %s, failed to create service socket.", errno, service->name);
}
INIT_ERROR_CHECK(CreateServiceFile(service) == 0,
service->lastErrno = INIT_EFILE;
return INIT_EFILE,
"Service error %d %s, failed to create service file.", errno, service->name);
CreateServiceFile(service->fileCfg);
if ((service->attribute & SERVICE_ATTR_CONSOLE)) {
OpenConsole();
INIT_ERROR_CHECK(OpenConsole() == 0,
service->lastErrno = INIT_ECONSOLE;
return INIT_ECONSOLE,
"Service error %d %s, failed to open console.", errno, service->name);
}
PublishHoldFds(service);
INIT_ERROR_CHECK(PublishHoldFds(service) == 0,
service->lastErrno = INIT_EHOLDER;
return INIT_EHOLDER,
"Service error %d %s, failed to publish fd", errno, service->name);
INIT_CHECK_ONLY_ELOG(BindCpuCore(service) == SERVICE_SUCCESS,
"binding core number failed for service %s", service->name);
"Service warning %d %s, failed to publish fd", errno, service->name);
// permissions
INIT_ERROR_CHECK(SetPerms(service) == SERVICE_SUCCESS, return -1,
"service %s exit! set perms failed! err %d.", service->name, errno);
ret = SetPerms(service);
INIT_ERROR_CHECK(ret == SERVICE_SUCCESS,
service->lastErrno = ret;
return ret,
"Service error %d %s, failed to set permissions.", ret, service->name);
// write pid
INIT_ERROR_CHECK(WritePid(service) == SERVICE_SUCCESS, return -1,
"service %s exit! write pid failed!", service->name);
INIT_ERROR_CHECK(WritePid(service) == SERVICE_SUCCESS,
service->lastErrno = INIT_EWRITEPID;
return INIT_EWRITEPID,
"Service error %d %s, failed to write pid.", errno, service->name);
PluginExecCmdByName("setServiceContent", service->name);
return 0;
}
void EnterServiceSandbox(Service *service)
{
INIT_ERROR_CHECK(InitServiceProperties(service) == 0, return, "Failed init service property");
INIT_ERROR_CHECK(InitServiceProperties(service, &service->pathArgs) == 0, return, "Failed init service property");
if (service->importance != 0) {
if (setpriority(PRIO_PROCESS, 0, service->importance) != 0) {
INIT_LOGE("setpriority failed for %s, importance = %d, err=%d",
@ -390,12 +427,11 @@ static void AddUpdateList(ServiceArgs *args, char *updateList)
free(argvOrig);
}
void CheckModuleUpdate(ServiceArgs *args)
static void CheckModuleUpdate(ServiceArgs *args)
{
INIT_LOGI("CheckModuleUpdate start");
void *handle = dlopen("libmodule_update.z.so", RTLD_NOW);
INIT_ERROR_CHECK(handle != NULL, return, "dlopen module update lib failed with error:%s", dlerror());
INIT_LOGI("dlopen success");
typedef char* (*ExtFunc)(int, char **);
ExtFunc func = (ExtFunc)dlsym(handle, "CheckModuleUpdate");
if (func == NULL) {
@ -509,21 +545,23 @@ static int32_t WaitForDebugger(void)
}
#endif
int ServiceStart(Service *service)
int ServiceStart(Service *service, ServiceArgs *pathArgs)
{
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr.");
INIT_ERROR_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "Service %s already started", service->name);
INIT_ERROR_CHECK(service->pathArgs.count > 0,
INIT_ERROR_CHECK(service->pid <= 0, return SERVICE_SUCCESS, "Service info %s already started", service->name);
INIT_ERROR_CHECK(pathArgs != NULL && pathArgs->count > 0,
return SERVICE_FAILURE, "start service %s pathArgs is NULL.", service->name);
INIT_LOGI("Service info %s starting", service->name);
if (service->attribute & SERVICE_ATTR_INVALID) {
INIT_LOGE("start service %s invalid.", service->name);
return SERVICE_FAILURE;
}
struct stat pathStat = { 0 };
service->attribute &= (~(SERVICE_ATTR_NEED_RESTART | SERVICE_ATTR_NEED_STOP));
if (stat(service->pathArgs.argv[0], &pathStat) != 0) {
if (stat(pathArgs->argv[0], &pathStat) != 0) {
service->attribute |= SERVICE_ATTR_INVALID;
service->lastErrno = INIT_EPATH;
INIT_LOGE("start service %s invalid, please check %s.", service->name, service->pathArgs.argv[0]);
return SERVICE_FAILURE;
}
@ -536,18 +574,12 @@ int ServiceStart(Service *service)
int pid = fork();
if (pid == 0) {
// set selinux label by context
if (service->context.type != INIT_CONTEXT_MAIN) {
SetSubInitContext(&service->context, service->name);
if (service->context.type != INIT_CONTEXT_MAIN && SetSubInitContext(&service->context, service->name) != 0) {
service->lastErrno = INIT_ECONTENT;
}
if (service->attribute & SERVICE_ATTR_MODULE_UPDATE) {
ServiceArgs* args = NULL;
if (service->extraArgs.argv != NULL && service->extraArgs.count > 0) {
args = &service->extraArgs;
} else {
args = &service->pathArgs;
}
CheckModuleUpdate(args);
CheckModuleUpdate(pathArgs);
}
#ifdef IS_DEBUG_VERSION
// only the image is debuggable and need debug, then wait for debugger
@ -556,15 +588,18 @@ int ServiceStart(Service *service)
}
#endif
// fail must exit sub process
INIT_ERROR_CHECK(InitServiceProperties(service) == 0,
_exit(PROCESS_EXIT_CODE), "Failed init service property");
ServiceExec(service);
_exit(PROCESS_EXIT_CODE);
int ret = InitServiceProperties(service, pathArgs);
INIT_ERROR_CHECK(ret == 0,
_exit(service->lastErrno), "Service error %d %s, failed to set properties", ret, service->name);
(void)ServiceExec(service, pathArgs);
_exit(service->lastErrno);
} else if (pid < 0) {
INIT_LOGE("start service %s fork failed!", service->name);
INIT_LOGE("Service error %d %s, failed to fork.", errno, service->name);
service->lastErrno = INIT_EFORK;
return SERVICE_FAILURE;
}
INIT_LOGI("Service %s(pid %d) started", service->name, pid);
INIT_LOGI("Service info %s(pid %d) started", service->name, pid);
service->pid = pid;
NotifyServiceChange(service, SERVICE_STARTED);
#ifndef OHOS_LITE
@ -685,12 +720,12 @@ static void ServiceReapHookExecute(Service *service)
void ServiceReap(Service *service)
{
INIT_CHECK(service != NULL, return);
INIT_LOGI("Reap service %s, pid %d.", service->name, service->pid);
INIT_LOGI("Service info %s reap pid %d.", service->name, service->pid);
service->pid = -1;
NotifyServiceChange(service, SERVICE_STOPPED);
if (service->attribute & SERVICE_ATTR_INVALID) {
INIT_LOGE("Reap service %s invalid.", service->name);
INIT_LOGE("Service error %s invalid service.", service->name);
return;
}
@ -728,13 +763,12 @@ void ServiceReap(Service *service)
}
if (service->attribute & SERVICE_ATTR_CRITICAL) { // critical
if (!CalculateCrashTime(service, service->crashTime, service->crashCount)) {
INIT_LOGE("Critical service \" %s \" crashed %d times, rebooting system",
service->name, service->crashCount);
INIT_LOGE("Service error %s critical service crashed.", service->name, service->crashCount);
ExecReboot("panic");
}
} else if (!(service->attribute & SERVICE_ATTR_NEED_RESTART)) {
if (!CalculateCrashTime(service, service->crashTime, service->crashCount)) {
INIT_LOGE("Service name=%s, crash %d times, no more start.", service->name, service->crashCount);
INIT_LOGE("Service error %s crash %d times, no more start.", service->name, service->crashCount);
return;
}
}
@ -745,7 +779,7 @@ void ServiceReap(Service *service)
if (service->serviceJobs.jobsName[JOB_ON_RESTART] != NULL) {
DoJobNow(service->serviceJobs.jobsName[JOB_ON_RESTART]);
}
ret = ServiceStart(service);
ret = ServiceStart(service, &service->pathArgs);
INIT_CHECK_ONLY_ELOG(ret == SERVICE_SUCCESS, "reap service %s start failed!", service->name);
service->attribute &= (~SERVICE_ATTR_NEED_RESTART);
}
@ -839,7 +873,7 @@ static void ServiceTimerStartProcess(const TimerHandle handler, void *context)
// Before start the service, stop service timer.
// make sure it will not enter timer handler next time.
ServiceStopTimer(service);
int ret = ServiceStart(service);
int ret = ServiceStart(service, &service->pathArgs);
if (ret != SERVICE_SUCCESS) {
INIT_LOGE("Start service \' %s \' in timer failed", service->name);
}

View File

@ -53,11 +53,11 @@ int ParseInitCfg(const char *configFile, void *context)
UNUSED(context);
INIT_LOGV("Parse init configs from %s", configFile);
char *fileBuf = ReadFileToBuf(configFile);
INIT_ERROR_CHECK(fileBuf != NULL, return -1, "Failed to read file content %s", configFile);
INIT_ERROR_CHECK(fileBuf != NULL, return -1, "Cfg error, %s not found", configFile);
cJSON *fileRoot = cJSON_Parse(fileBuf);
INIT_ERROR_CHECK(fileRoot != NULL, free(fileBuf);
return -1, "Failed to parse json file %s", configFile);
return -1, "Cfg error, failed to parse json %s ", configFile);
ParseInitCfgContents(configFile, fileRoot);
cJSON_Delete(fileRoot);

View File

@ -69,22 +69,26 @@ static int SetFileEnv(int fd, const char *pathName)
return 0;
}
void CreateServiceFile(ServiceFile *fileOpt)
int CreateServiceFile(Service *service)
{
INIT_CHECK(fileOpt != NULL, return);
ServiceFile *tmpFile = fileOpt;
INIT_CHECK(service != NULL, return INIT_EPARAMETER);
ServiceFile *tmpFile = service->fileCfg;
int ret = 0;
while (tmpFile != NULL) {
int fd = CreateFile(tmpFile);
if (fd < 0) {
INIT_LOGE("Failed Create File err=%d ", errno);
ret++;
INIT_LOGE("Service error %d %s, failed to create file", errno, service->name, tmpFile->fileName);
tmpFile = tmpFile->next;
continue;
}
int ret = SetFileEnv(fd, tmpFile->fileName);
INIT_CHECK_ONLY_ELOG(ret >= 0, "Failed Set File Env");
if (SetFileEnv(fd, tmpFile->fileName) != 0) {
ret++;
INIT_LOGE("Service error %d %s, failed to set env for file", errno, service->name, tmpFile->fileName);
}
tmpFile = tmpFile->next;
}
return;
return ret > 0 ? INIT_EFILE : 0;
}
void CloseServiceFile(ServiceFile *fileOpt)

View File

@ -101,6 +101,7 @@ Service *AddService(const char *name)
service->cpuSet = NULL;
service->pid = -1;
service->context.type = INIT_CONTEXT_MAIN;
service->lastErrno = INIT_OK;
OH_ListInit(&service->extDataNode);
g_serviceSpace.serviceCount++;
INIT_LOGV("AddService %s", node->name);
@ -266,7 +267,7 @@ static int GetGid(cJSON *json, gid_t *gid, Service *curServ)
INIT_LOGW("Service %s with invalid gid configuration", curServ->name);
*gid = -1; // Invalid gid, set as -1
}
INIT_ERROR_CHECK(*gid != (gid_t)(-1), return SERVICE_FAILURE, "Failed to get gid for %s", curServ->name);
INIT_CHECK_RETURN_VALUE(*gid != (gid_t)(-1), SERVICE_FAILURE);
return SERVICE_SUCCESS;
}
@ -286,14 +287,15 @@ static int GetServiceGids(const cJSON *curArrItem, Service *curServ)
if (curServ->servPerm.gIDArray != NULL) {
free(curServ->servPerm.gIDArray);
}
curServ->servPerm.gIDArray = (gid_t *)malloc(sizeof(gid_t) * gidCount);
curServ->servPerm.gIDArray = (gid_t *)malloc(sizeof(gid_t) * (gidCount + 1));
INIT_ERROR_CHECK(curServ->servPerm.gIDArray != NULL, return SERVICE_FAILURE, "Failed to malloc err=%d", errno);
curServ->servPerm.gIDCnt = gidCount;
gid_t gid;
if (!cJSON_IsArray(arrItem)) {
int ret = GetGid(arrItem, &gid, curServ);
INIT_ERROR_CHECK(ret == 0, return SERVICE_FAILURE, "Parse service %s gid failed.", curServ->name);
INIT_ERROR_CHECK(ret == 0, return SERVICE_FAILURE,
"Service error %s, failed to get gid from %s.", curServ->name, cJSON_Print(arrItem));
curServ->servPerm.gIDArray[0] = gid;
return SERVICE_SUCCESS;
}
@ -302,11 +304,14 @@ static int GetServiceGids(const cJSON *curArrItem, Service *curServ)
cJSON *item = cJSON_GetArrayItem(arrItem, i);
int ret = GetGid(item, &gid, curServ);
if (ret != 0) {
INIT_LOGW("Parse service %s gid failed from item %s.", curServ->name, cJSON_Print(item));
INIT_LOGW("Service warning %s, failed to get gid from %s.", curServ->name, cJSON_Print(item));
continue;
}
curServ->servPerm.gIDArray[gidArrayIndex++] = gid;
}
if (gidArrayIndex == 0) {
curServ->servPerm.gIDArray[gidArrayIndex++] = curServ->servPerm.uID;
}
curServ->servPerm.gIDCnt = gidArrayIndex;
return SERVICE_SUCCESS;
}
@ -319,7 +324,7 @@ static int GetServiceAttr(const cJSON *curArrItem, Service *curServ, const char
return SERVICE_SUCCESS;
}
INIT_ERROR_CHECK(cJSON_IsNumber(filedJ), return SERVICE_FAILURE,
"%s is null or is not a number, service name is %s", attrName, curServ->name);
"Service error %s is null or is not a number %s", curServ->name, attrName);
curServ->attribute &= ~flag;
int value = (int)cJSON_GetNumberValue(filedJ);
if (processAttr == NULL) {
@ -934,7 +939,7 @@ static void ProcessConsoleEvent(const WatcherHandle handler, int fd, uint32_t *e
return;
}
if (ServiceStart(service) != SERVICE_SUCCESS) {
if (ServiceStart(service, &service->pathArgs) != SERVICE_SUCCESS) {
INIT_LOGE("Start console service failed");
}
return;
@ -1022,7 +1027,8 @@ void ParseAllServices(const cJSON *fileRoot, const ConfigContext *context)
}
int ret = ParseOneService(curItem, service);
if (ret != SERVICE_SUCCESS) {
ReleaseService(service);
INIT_LOGE("Service error %s parse config error.", service->name, cJSON_Print(curItem));
service->lastErrno = INIT_ECFG;
continue;
}
ret = ParseServiceSocket(curItem, service);
@ -1047,7 +1053,7 @@ void ParseAllServices(const cJSON *fileRoot, const ConfigContext *context)
}
}
static Service *GetServiceByExtServName(const char *fullServName)
static Service *GetServiceByExtServName(const char *fullServName, ServiceArgs *extraArgs)
{
INIT_ERROR_CHECK(fullServName != NULL, return NULL, "Failed get parameters");
Service *service = GetServiceByName(fullServName);
@ -1058,47 +1064,51 @@ static Service *GetServiceByExtServName(const char *fullServName)
char *dstPtr[MAX_PATH_ARGS_CNT] = {NULL};
int returnCount = SplitString(tmpServName, "|", dstPtr, MAX_PATH_ARGS_CNT);
if (returnCount == 0) {
INIT_LOGE("Service error %s start service bt ext parameter .", fullServName);
free(tmpServName);
return NULL;
}
INIT_LOGI("Service info %s start service bt ext parameter %s.", dstPtr[0], fullServName);
service = GetServiceByName(dstPtr[0]);
if (service == NULL) {
free(tmpServName);
return NULL;
}
service->extraArgs.count = service->pathArgs.count + returnCount - 1;
service->extraArgs.argv = (char **)calloc(service->extraArgs.count + 1, sizeof(char *));
INIT_ERROR_CHECK(service->extraArgs.argv != NULL, free(tmpServName);
extraArgs->count = service->pathArgs.count + returnCount - 1;
extraArgs->argv = (char **)calloc(extraArgs->count + 1, sizeof(char *));
INIT_ERROR_CHECK(extraArgs->argv != NULL, free(tmpServName);
return NULL, "Failed calloc err=%d", errno);
int argc;
for (argc = 0; argc < (service->pathArgs.count - 1); argc++) {
service->extraArgs.argv[argc] = strdup(service->pathArgs.argv[argc]);
extraArgs->argv[argc] = strdup(service->pathArgs.argv[argc]);
}
int extArgc;
for (extArgc = 0; extArgc < (returnCount - 1); extArgc++) {
service->extraArgs.argv[extArgc + argc] = strdup(dstPtr[extArgc + 1]);
extraArgs->argv[extArgc + argc] = strdup(dstPtr[extArgc + 1]);
}
service->extraArgs.argv[service->extraArgs.count] = NULL;
extraArgs->argv[extraArgs->count] = NULL;
free(tmpServName);
return service;
}
void StartServiceByName(const char *servName)
{
INIT_LOGI("Start service %s", servName);
ServiceArgs extraArgs = { 0 };
Service *service = GetServiceByName(servName);
if (service == NULL) {
service = GetServiceByExtServName(servName);
service = GetServiceByExtServName(servName, &extraArgs);
}
INIT_ERROR_CHECK(service != NULL, return, "Cannot find service %s.", servName);
if (ServiceStart(service) != SERVICE_SUCCESS) {
ServiceArgs *pathArgs = &service->pathArgs;
if (extraArgs.count != 0) {
pathArgs = &extraArgs;
}
if (ServiceStart(service, pathArgs) != SERVICE_SUCCESS) {
INIT_LOGE("Service %s start failed!", servName);
}
// After starting, clear the extra parameters.
FreeStringVector(service->extraArgs.argv, service->extraArgs.count);
service->extraArgs.argv = NULL;
service->extraArgs.count = 0;
FreeStringVector(extraArgs.argv, extraArgs.count);
return;
}

View File

@ -178,7 +178,7 @@ static void ProcessWatchEvent_(const WatcherHandle watcherHandle, int fd, uint32
}
INIT_LOGI("Socket information detected, fd:%d service name:%s", fd, service->name);
RemoveSocketWatcher(watcherHandle);
if (ServiceStart(service) != SERVICE_SUCCESS) {
if (ServiceStart(service, &service->pathArgs) != SERVICE_SUCCESS) {
INIT_LOGE("Service %s start failed!", service->name);
}
}

View File

@ -62,11 +62,11 @@ int SetImportantValue(Service *service, const char *attrName, int value, int fla
return SERVICE_SUCCESS;
}
int ServiceExec(const Service *service)
int ServiceExec(Service *service, const ServiceArgs *pathArgs)
{
INIT_ERROR_CHECK(service != NULL && service->pathArgs.count > 0,
INIT_ERROR_CHECK(pathArgs != NULL && pathArgs->count > 0,
return SERVICE_FAILURE, "Exec service failed! null ptr.");
if (execv(service->pathArgs.argv[0], service->pathArgs.argv) != 0) {
if (execv(pathArgs->argv[0], pathArgs->argv) != 0) {
INIT_LOGE("Service %s execv failed! err=%d.", service->name, errno);
return errno;
}
@ -88,9 +88,9 @@ void IsEnableSandbox(void)
return;
}
void SetServiceEnterSandbox(const char *path, unsigned int attribute)
int SetServiceEnterSandbox(const Service *service, const char *path)
{
UNUSED(path);
UNUSED(attribute);
return;
UNUSED(service);
return 0;
}

View File

@ -309,7 +309,7 @@ INIT_STATIC void InitPostHook(const HOOK_INFO *hookInfo, void *executionContext,
INIT_TIMING_STAT *stat = (INIT_TIMING_STAT *)executionContext;
clock_gettime(CLOCK_MONOTONIC, &(stat->endTime));
long long diff = InitDiffTime(stat);
INIT_LOGI("Executing hook [%d:%d] cost [%lld]us, return %d.",
INIT_LOGI("Executing hook [%d:%d] cost [%lld]us, result %d.",
hookInfo->stage, hookInfo->prio, diff, executionRetVal);
}
@ -407,7 +407,7 @@ void SystemConfig(void)
InitParseGroupCfg();
RegisterBootStateChange(BootStateChange);
INIT_LOGI("boot init finish.");
INIT_LOGI("boot stage: init finish.");
// load SELinux context and policy
// Do not move position!
PluginExecCmdByName("loadSelinuxPolicy", "");
@ -426,7 +426,7 @@ void SystemConfig(void)
HookMgrExecute(GetBootStageHookMgr(), INIT_PRE_CFG_LOAD, (void *)&timingStat, (void *)&options);
ReadConfig();
RecordInitBootEvent("init.ParseCfg");
INIT_LOGI("boot parse config file done.");
INIT_LOGI("boot stage: parse config file finish.");
HookMgrExecute(GetBootStageHookMgr(), INIT_POST_CFG_LOAD, (void *)&timingStat, (void *)&options);
IsEnableSandbox();

View File

@ -61,6 +61,7 @@ static void DumpServiceSocket(const Service *service)
printf("\tservice socket info \n");
ServiceSocket *sockopt = service->socketCfg;
while (sockopt != NULL) {
printf("\t\tsocket fd: %d \n", sockopt->sockFd);
printf("\t\tsocket name: %s \n", sockopt->name);
printf("\t\tsocket type: %u \n", sockopt->type);
printf("\t\tsocket uid: %u \n", sockopt->uid);
@ -79,6 +80,14 @@ void DumpServiceHookExecute(const char *name, const char *info)
static void DumpOneService(const Service *service)
{
static const struct InitErrMap initErrMaps[] = {
{INIT_OK, ""},
#define XX(code, info) {INIT_ ## code, info},
INIT_ERRNO_MAP(XX)
#undef XX
{INIT_OK, ""}
};
const InitArgInfo startModeMap[] = {
{"condition", START_MODE_CONDITION},
{"boot", START_MODE_BOOT},
@ -92,6 +101,11 @@ static void DumpOneService(const Service *service)
printf("\tservice name: [%s] \n", service->name);
printf("\tservice pid: [%d] \n", service->pid);
if (service->lastErrno < sizeof(initErrMaps)) {
printf("\tservice last error: %s(%d) \n", initErrMaps[service->lastErrno].info, service->lastErrno);
} else {
printf("\tservice last error: %d \n", service->lastErrno);
}
printf("\tservice context : [%s] \n", (service->context.type == INIT_CONTEXT_CHIPSET) ? "chipset" : "system");
printf("\tservice crashCnt: [%d] \n", service->crashCnt);
printf("\tservice attribute: [%u] \n", service->attribute);
@ -192,6 +206,8 @@ static void ProcessDumpServiceControlFd(uint16_t type, const char *serviceCmd)
if (strcmp(serviceCmd, "parameter_service") == 0) {
if (cmd != NULL && strcmp(cmd, "trigger") == 0) {
SystemDumpTriggers(0, printf);
} else {
SystemDumpParameters(0, 0, printf);
}
return;
}

View File

@ -83,34 +83,29 @@ int SetImportantValue(Service *service, const char *attrName, int value, int fla
return SERVICE_SUCCESS;
}
int ServiceExec(const Service *service)
int ServiceExec(Service *service, const ServiceArgs *pathArgs)
{
INIT_ERROR_CHECK(service != NULL && service->pathArgs.count > 0,
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "Exec service failed! null ptr.");
INIT_ERROR_CHECK(pathArgs != NULL && pathArgs->count > 0,
return SERVICE_FAILURE, "Exec service failed! null ptr.");
if (service->importance != 0) {
INIT_ERROR_CHECK(setpriority(PRIO_PROCESS, 0, service->importance) == 0, _exit(0x7f),
"setpriority failed for %s, importance = %d, err=%d", service->name, service->importance, errno);
INIT_ERROR_CHECK(setpriority(PRIO_PROCESS, 0, service->importance) == 0,
service->lastErrno = INIT_EPRIORITY;
return SERVICE_FAILURE,
"Service error %d %s, failed to set priority %d.", errno, service->name, service->importance);
}
OpenHidebug(service->name);
if (service->extraArgs.argv != NULL && service->extraArgs.count > 0) {
INIT_CHECK_ONLY_ELOG(execv(service->extraArgs.argv[0], service->extraArgs.argv) == 0,
"service %s execv failed! err %d.", service->name, errno);
} else {
INIT_CHECK_ONLY_ELOG(execv(service->pathArgs.argv[0], service->pathArgs.argv) == 0,
"service %s execv failed! err %d.", service->name, errno);
}
INIT_ERROR_CHECK(execv(pathArgs->argv[0], pathArgs->argv) == 0,
service->lastErrno = INIT_EEXEC;
return errno, "Service error %d %s, failed to execv.", errno, service->name);
return SERVICE_SUCCESS;
}
int SetAccessToken(const Service *service)
{
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "service is null");
int ret = SetSelfTokenID(service->tokenId);
if (ret != 0) {
INIT_LOGV("Set service %s token id %lld failed.", service->name, service->tokenId);
return SERVICE_FAILURE;
}
return SERVICE_SUCCESS;
return SetSelfTokenID(service->tokenId);
}
void GetAccessToken(void)
@ -156,23 +151,20 @@ void IsEnableSandbox(void)
}
}
void SetServiceEnterSandbox(const char *execPath, unsigned int attribute)
int SetServiceEnterSandbox(const Service *service, const char *execPath)
{
if ((service->attribute & SERVICE_ATTR_WITHOUT_SANDBOX) == SERVICE_ATTR_WITHOUT_SANDBOX) {
return 0;
}
if (g_enableSandbox == false) {
return;
return 0;
}
if ((attribute & SERVICE_ATTR_WITHOUT_SANDBOX) == SERVICE_ATTR_WITHOUT_SANDBOX) {
return;
}
INIT_ERROR_CHECK(execPath != NULL, return, "Service path is null.");
INIT_ERROR_CHECK(execPath != NULL, return INIT_EPARAMETER, "Service path is null.");
int ret = 0;
if (strncmp(execPath, "/system/bin/", strlen("/system/bin/")) == 0) {
INIT_INFO_CHECK(EnterSandbox("system") == 0, return,
"Service %s skip enter system sandbox.", execPath);
ret = EnterSandbox("system");
} else if (strncmp(execPath, "/vendor/bin/", strlen("/vendor/bin/")) == 0) {
INIT_INFO_CHECK(EnterSandbox("chipset") == 0, return,
"Service %s skip enter chipset sandbox.", execPath);
} else {
INIT_LOGI("Service %s does not enter sandbox", execPath);
ret = EnterSandbox("chipset");
}
return;
return ret;
}

View File

@ -26,36 +26,40 @@
static SignalHandle g_sigHandle = NULL;
static pid_t HandleSigChild(const struct signalfd_siginfo *siginfo)
{
int procStat = 0;
pid_t sigPID = waitpid(-1, &procStat, WNOHANG);
if (sigPID <= 0) {
return sigPID;
}
Service* service = GetServiceByPid(sigPID);
const char *serviceName = (service == NULL) ? "Unknown" : service->name;
// check child process exit status
if (WIFSIGNALED(procStat)) {
INIT_LOGE("Child process %s(pid %d) exit with signal : %d", serviceName, sigPID, WTERMSIG(procStat));
} else if (WIFEXITED(procStat)) {
INIT_LOGE("Child process %s(pid %d) exit with code : %d", serviceName, sigPID, WEXITSTATUS(procStat));
if (service != NULL) {
service->lastErrno = WEXITSTATUS(procStat);
}
}
CmdServiceProcessDelClient(sigPID);
StopSubInit(sigPID);
INIT_LOGW("Service warning %s, SIGCHLD received, pid:%d uid:%d status:%d.",
serviceName, sigPID, siginfo->ssi_uid, procStat);
CheckWaitPid(sigPID);
ServiceReap(service);
return sigPID;
}
INIT_STATIC void ProcessSignal(const struct signalfd_siginfo *siginfo)
{
switch (siginfo->ssi_signo) {
case SIGCHLD: {
pid_t sigPID;
int procStat = 0;
while (1) {
sigPID = waitpid(-1, &procStat, WNOHANG);
if (sigPID <= 0) {
break;
}
Service* service = GetServiceByPid(sigPID);
// check child process exit status
if (WIFSIGNALED(procStat)) {
INIT_LOGE("Child process %s(pid %d) exit with signal : %d",
service == NULL ? "Unknown" : service->name, sigPID, WTERMSIG(procStat));
} else if (WIFEXITED(procStat)) {
INIT_LOGE("Child process %s(pid %d) exit with code : %d",
service == NULL ? "Unknown" : service->name, sigPID, WEXITSTATUS(procStat));
} else {
INIT_LOGE("Child process %s(pid %d) exit with invalid status : %d",
service == NULL ? "Unknown" : service->name, sigPID, procStat);
}
CmdServiceProcessDelClient(sigPID);
StopSubInit(sigPID);
INIT_LOGI("SigHandler, SIGCHLD received, Service:%s pid:%d uid:%d status:%d.",
service == NULL ? "Unknown" : service->name,
sigPID, siginfo->ssi_uid, procStat);
CheckWaitPid(sigPID);
ServiceReap(service);
while (HandleSigChild(siginfo) > 0) {
;
}
break;
}

View File

@ -21,6 +21,7 @@ ohos_shared_library("selinuxadp") {
".",
"..",
"../init_hook",
"//base/startup/init/services/include",
"//base/startup/init/services/include/param",
"//third_party/selinux/libselinux/include/",
"//base/security/selinux_adapter/interfaces/policycoreutils/include/",

View File

@ -16,6 +16,7 @@
#include <errno.h>
#include "init_error.h"
#include "init_hook.h"
#include "init_module_engine.h"
#include "plugin_adapter.h"
@ -64,20 +65,21 @@ static int SetServiceContent(int id, const char *name, int argc, const char **ar
{
PLUGIN_CHECK(name != NULL && argc >= 1 && argv != NULL, return -1, "Invalid parameter");
ServiceExtData *data = GetServiceExtData(argv[0], HOOK_ID_SELINUX);
char *label = "u:r:limit_domain:s0";
if (data != NULL) {
if (setexeccon((char *)data->data) < 0) {
PLUGIN_LOGE("failed to set service %s's secon (%s).", argv[0], (char *)data->data);
#ifndef STARTUP_INIT_TEST
_exit(PROCESS_EXIT_CODE);
#endif
} else {
PLUGIN_LOGV("Set content %s to %s.", (char *)data->data, argv[0]);
}
label = (char *)data->data;
} else {
PLUGIN_CHECK(!(setexeccon("u:r:limit_domain:s0") < 0), _exit(PROCESS_EXIT_CODE),
"failed to set service %s's secon (%s).", argv[0], "u:r:limit_domain:s0");
PLUGIN_LOGE("Please set secon field in service %s's cfg file, limit_domain will be blocked", argv[0]);
}
if (setexeccon(label) < 0) {
PLUGIN_LOGE("Service error %d %s, failed to set secon %s.", errno, argv[0], label);
#ifndef STARTUP_INIT_TEST
_exit(INIT_EEXEC_CONTENT);
#endif
} else {
PLUGIN_LOGV("Service info %s, set secon %s.", argv[0], label);
}
return 0;
}

View File

@ -25,6 +25,7 @@
#include "param_utils.h"
#include "param_base.h"
#define MAX_MEMBER_IN_GROUP 128
#define MAX_BUF_SIZE 1024
#define INVALID_MODE 0550
#ifdef STARTUP_INIT_TEST
@ -124,30 +125,76 @@ static int FreeLocalSecurityLabel(ParamSecurityLabel *srcLabel)
return 0;
}
static int DacGetGroupMember(gid_t gid, uid_t *member, uint32_t *memberSize)
{
uint32_t inputLen = *memberSize;
*memberSize = 0;
struct group *data = getgrgid(gid);
if (data == NULL || data->gr_mem == NULL) {
return 0;
}
int i = 0;
int memIndex = 0;
while (data->gr_mem[i]) {
uid_t uid;
GetUserIdByName(&uid, data->gr_mem[i]);
if (INVALID_UID(uid)) {
i++;
continue;
}
if ((memIndex + 1) > inputLen) {
PARAM_LOGE("Not enough memory for uid member %u", gid);
break;
}
member[memIndex++] = uid;
i++;
}
uid_t uid = 0;
GetUserIdByName(&uid, data->gr_name);
if (!INVALID_UID(uid) && ((memIndex + 1) < inputLen)) {
member[memIndex++] = uid;
}
*memberSize = memIndex;
return 0;
}
static int LoadOneParam_(const uint32_t *context, const char *name, const char *value)
{
ParamAuditData auditData = {0};
auditData.dacData.gid = -1;
auditData.dacData.uid = -1;
auditData.name = name;
int ret = GetParamDacData(&auditData.dacData, value);
ParamAuditData *auditData = (ParamAuditData *)context;
auditData->dacData.gid = -1;
auditData->dacData.uid = -1;
auditData->name = name;
int ret = GetParamDacData(&auditData->dacData, value);
PARAM_CHECK(ret == 0, return -1, "Failed to get param info %d %s", ret, name);
if (INVALID_UID(auditData.dacData.gid) || INVALID_UID(auditData.dacData.uid)) {
PARAM_LOGW("Invalid dac for '%s' gid %d uid %d", name, auditData.dacData.gid, auditData.dacData.uid);
if (INVALID_UID(auditData->dacData.gid) || INVALID_UID(auditData->dacData.uid)) {
PARAM_LOGW("Invalid dac for '%s' gid %d uid %d", name, auditData->dacData.gid, auditData->dacData.uid);
}
AddSecurityLabel(&auditData);
// get uid from group
auditData->memberNum = MAX_MEMBER_IN_GROUP;
ret = DacGetGroupMember(auditData->dacData.gid, auditData->members, &auditData->memberNum);
if (ret != 0) {
auditData->memberNum = 1;
auditData->members[0] = auditData->dacData.gid;
}
AddSecurityLabel(auditData);
return 0;
}
static int LoadParamLabels(const char *fileName)
{
ParamAuditData *auditData = (ParamAuditData *)calloc(1,
sizeof(ParamAuditData) + sizeof(uid_t) * MAX_MEMBER_IN_GROUP);
if (auditData == NULL) {
PARAM_LOGE("Failed to alloc memory %s", fileName);
return 0;
}
uint32_t infoCount = 0;
FILE *fp = fopen(fileName, "r");
const uint32_t buffSize = PARAM_NAME_LEN_MAX + PARAM_CONST_VALUE_LEN_MAX + 10; // 10 size
char *buff = (char *)calloc(1, buffSize);
while (fp != NULL && buff != NULL && fgets(buff, buffSize, fp) != NULL) {
buff[buffSize - 1] = '\0';
int ret = SplitParamString(buff, NULL, 0, LoadOneParam_, NULL);
int ret = SplitParamString(buff, NULL, 0, LoadOneParam_, (const uint32_t *)auditData);
if (ret != 0) {
PARAM_LOGE("Failed to split string %s fileName %s", buff, fileName);
continue;
@ -161,6 +208,9 @@ static int LoadParamLabels(const char *fileName)
if (buff != NULL) {
free(buff);
}
if (auditData != NULL) {
free(auditData);
}
return 0;
}
@ -237,127 +287,3 @@ INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit)
}
return ret;
}
static void AddGroupUser(const char *userName, gid_t gid)
{
if (userName == NULL || strlen(userName) == 0) {
return;
}
uid_t uid = 0;
GetUserIdByName(&uid, userName);
PARAM_LOGV("Add group user '%s' gid %d uid %d", userName, gid, uid);
if (INVALID_UID(gid) || INVALID_UID(uid)) {
PARAM_LOGW("Invalid user for '%s' gid %d uid %d", userName, gid, uid);
return;
}
char buffer[USER_BUFFER_LEN] = {0};
int ret = PARAM_SPRINTF(buffer, sizeof(buffer), GROUP_FORMAT, gid, uid);
PARAM_CHECK(ret >= 0, return, "Failed to format name for %d.%d", gid, uid);
(void)AddParamEntry(WORKSPACE_INDEX_BASE, PARAM_TYPE_STRING, buffer, "1");
}
#ifdef PARAM_DECODE_GROUPID_FROM_FILE
static char *UserNameTrim(char *str)
{
if (str == NULL) {
return NULL;
}
size_t len = strlen(str);
if (str == NULL || len == 0) {
return NULL;
}
char *end = str + len - 1;
while (end >= str && (*end == ' ' || *end == '\t' || *end == '\n' || *end == '\r')) {
*end = '\0';
end--;
}
len = strlen(str);
char *head = str;
end = str + strlen(str);
while (head < end && (*head == ' ' || *head == '\t' || *head == '\n' || *head == '\r')) {
*head = '\0';
head++;
}
if (strlen(str) == 0) {
return NULL;
}
return head;
}
static void LoadGroupUser_(void)
{
// decode group file
FILE *fp = fopen(GROUP_FILE_PATH, "r");
const uint32_t buffSize = 1024; // 1024 max buffer for decode
char *buff = (char *)calloc(1, buffSize);
while (fp != NULL && buff != NULL && fgets(buff, buffSize, fp) != NULL) {
buff[buffSize - 1] = '\0';
// deviceprivate:x:1053:root,shell,system,samgr,hdf_devmgr,deviceinfo,dsoftbus,dms,account
char *buffer = UserNameTrim(buff);
PARAM_CHECK(buffer != NULL, continue, "Invalid buffer %s", buff);
PARAM_LOGV("LoadGroupUser_ '%s'", buffer);
// group name
char *groupName = strtok(buffer, ":");
groupName = UserNameTrim(groupName);
PARAM_CHECK(groupName != NULL, continue, "Invalid group name %s", buff);
gid_t gid = -1;
GetGroupIdByName(&gid, groupName);
// skip x
(void)strtok(NULL, ":");
char *strGid = strtok(NULL, ":");
char *userName = strGid + strlen(strGid) + 1;
userName = UserNameTrim(userName);
PARAM_LOGV("LoadGroupUser_ %s userName '%s'", groupName, userName);
if (userName == NULL) {
AddGroupUser(groupName, gid);
continue;
}
char *tmp = strtok(userName, ",");
while (tmp != NULL) {
PARAM_LOGV("LoadGroupUser_ %s userName '%s'", groupName, tmp);
AddGroupUser(UserNameTrim(tmp), gid);
userName = tmp + strlen(tmp) + 1;
tmp = strtok(NULL, ",");
}
// last username
if (userName != NULL) {
AddGroupUser(UserNameTrim(userName), gid);
}
}
if (fp != NULL) {
(void)fclose(fp);
}
if (buff != NULL) {
free(buff);
}
return;
}
#else
static void LoadGroupUser_(void)
{
struct group *data = NULL;
while ((data = getgrent()) != NULL) {
if (data->gr_name == NULL || data->gr_mem == NULL) {
continue;
}
if (data->gr_mem[0] == NULL) { // default user in group
AddGroupUser(data->gr_name, data->gr_gid);
continue;
}
int index = 0;
while (data->gr_mem[index]) { // user in this group
AddGroupUser(data->gr_mem[index], data->gr_gid);
index++;
}
}
endgrent();
}
#endif
INIT_LOCAL_API void LoadGroupUser(void)
{
PARAM_LOGV("LoadGroupUser ");
LoadGroupUser_();
}

View File

@ -208,6 +208,8 @@ static void HandleSelinuxLabelForPermission(const ParameterNode *paramNode, int
auditData.dacData.paramType = node->type;
auditData.selinuxIndex = labelIndex;
auditData.name = paramNode->paraName;
auditData.memberNum = 1;
auditData.members[0] = node->gid;
AddSecurityLabel(&auditData);
}

View File

@ -175,6 +175,8 @@ static int CreateWorkSpace(int onlyRead)
#else
ret = AddWorkSpace(WORKSPACE_NAME_NORMAL, WORKSPACE_INDEX_DAC, onlyRead, PARAM_WORKSPACE_MAX);
PARAM_CHECK(ret == 0, return -1, "Failed to add dac workspace");
ret = OpenWorkSpace(WORKSPACE_INDEX_DAC, onlyRead);
PARAM_CHECK(ret == 0, return -1, "Failed to open dac workspace");
paramSpace->maxLabelIndex = 1;
#endif
return ret;
@ -182,9 +184,8 @@ static int CreateWorkSpace(int onlyRead)
INIT_INNER_API int InitParamWorkSpace(int onlyRead, const PARAM_WORKSPACE_OPS *ops)
{
if (CheckNeedInit(onlyRead, ops) == 0) {
return 0;
}
PARAM_ONLY_CHECK(CheckNeedInit(onlyRead, ops) != 0, return 0);
paramMutexEnvInit();
if (!PARAM_TEST_FLAG(g_paramWorkSpace.flags, WORKSPACE_FLAGS_INIT)) {
g_paramWorkSpace.maxSpaceCount = PARAM_DEF_SELINUX_LABEL;
@ -205,8 +206,6 @@ INIT_INNER_API int InitParamWorkSpace(int onlyRead, const PARAM_WORKSPACE_OPS *o
ret = AllocSpaceMemory(g_paramWorkSpace.maxLabelIndex);
PARAM_CHECK(ret == 0, return -1, "Failed to alloc space size");
// load user info for dac
LoadGroupUser();
// add default dac policy
ParamAuditData auditData = {0};
auditData.name = "#";
@ -214,6 +213,8 @@ INIT_INNER_API int InitParamWorkSpace(int onlyRead, const PARAM_WORKSPACE_OPS *o
auditData.dacData.uid = DAC_DEFAULT_USER;
auditData.dacData.mode = DAC_DEFAULT_MODE; // 0774 default mode
auditData.dacData.paramType = PARAM_TYPE_STRING;
auditData.memberNum = 1;
auditData.members[0] = DAC_DEFAULT_GROUP;
#ifdef PARAM_SUPPORT_SELINUX
auditData.selinuxIndex = INVALID_SELINUX_INDEX;
#endif
@ -337,12 +338,9 @@ STATIC_INLINE int CheckAndExtendSpace(ParamWorkSpace *paramSpace, const char *na
INIT_LOCAL_API int OpenWorkSpace(uint32_t index, int readOnly)
{
ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL && paramSpace->workSpace != NULL,
return -1, "Invalid workspace index %u", index);
PARAM_CHECK(paramSpace != NULL && paramSpace->workSpace != NULL, return -1, "Invalid workspace index %u", index);
WorkSpace *workSpace = NULL;
if (index < paramSpace->maxSpaceCount) {
workSpace = paramSpace->workSpace[index];
}
PARAM_ONLY_CHECK(index >= paramSpace->maxSpaceCount, workSpace = paramSpace->workSpace[index]);
PARAM_CHECK(workSpace != NULL, return 0, "Invalid index %d", index);
int ret = 0;
uint32_t rwSpaceLock = 0;
@ -359,8 +357,7 @@ INIT_LOCAL_API int OpenWorkSpace(uint32_t index, int readOnly)
ATOMIC_STORE_EXPLICIT(&workSpace->rwSpaceLock, rwSpaceLock | WORKSPACE_STATUS_IN_PROCESS, MEMORY_ORDER_RELEASE);
if (workSpace->area == NULL) {
PARAM_LOGI("OpenWorkSpace %s index %d spaceSize: %u onlyRead %s",
workSpace->fileName, workSpace->spaceIndex,
PARAM_LOGI("OpenWorkSpace %s index %d spaceSize: %u onlyRead %s", workSpace->fileName, workSpace->spaceIndex,
workSpace->spaceSize, readOnly ? "true" : "false");
ret = InitWorkSpace(workSpace, readOnly, workSpace->spaceSize);
if (ret != 0) {
@ -413,14 +410,12 @@ STATIC_INLINE int ReadParamWithCheck(WorkSpace **workspace, const char *name, ui
return ret;
}
static int CheckUserInGroup(WorkSpace *space, gid_t groupId, uid_t uid)
static int CheckUserInGroup(WorkSpace *space, const ParamSecurityNode *node, uid_t uid)
{
char buffer[USER_BUFFER_LEN] = {0};
int ret = PARAM_SPRINTF(buffer, sizeof(buffer), GROUP_FORMAT, groupId, uid);
PARAM_CHECK(ret >= 0, return -1, "Failed to format name for "GROUP_FORMAT, groupId, uid);
ParamNode *node = GetParamNode(WORKSPACE_INDEX_BASE, buffer);
if (node != NULL) {
return 0;
for (uint32_t i = 0; i < node->memberNum; i++) {
if (node->members[i] == uid) {
return 0;
}
}
return -1;
}
@ -485,7 +480,7 @@ STATIC_INLINE int DacCheckParamPermission(const ParamLabelIndex *labelIndex,
return DAC_RESULT_PERMISSION;
}
// 4, check user in group
if (CheckUserInGroup(space, node->gid, srcLabel->cred.uid) == 0) {
if (CheckUserInGroup(space, node, srcLabel->cred.uid) == 0) {
localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> DAC_GROUP_START;
if ((node->mode & localMode) != 0) {
return DAC_RESULT_PERMISSION;

View File

@ -238,7 +238,7 @@ INIT_LOCAL_API uint32_t AddParamSecurityNode(WorkSpace *workSpace, const ParamAu
{
PARAM_CHECK(CheckWorkSpace(workSpace) == 0, return 0, "Invalid workSpace");
PARAM_CHECK(auditData != NULL, return 0, "Invalid auditData");
uint32_t realLen = sizeof(ParamSecurityNode);
uint32_t realLen = sizeof(ParamSecurityNode) + sizeof(uid_t) * auditData->memberNum;
PARAM_CHECK((workSpace->area->currOffset + realLen) < workSpace->area->dataSize, return 0,
"Failed to allocate currOffset %u, dataSize %u datalen %u",
workSpace->area->currOffset, workSpace->area->dataSize, realLen);
@ -252,6 +252,13 @@ INIT_LOCAL_API uint32_t AddParamSecurityNode(WorkSpace *workSpace, const ParamAu
#else
node->selinuxIndex = 0;
#endif
if (auditData->memberNum > 0) {
// copy member
int ret = PARAM_MEMCPY(node->members,
realLen - sizeof(ParamSecurityNode), auditData->members, auditData->memberNum * sizeof(uid_t));
PARAM_CHECK(ret == 0, return 0, "Failed to copy members");
}
node->memberNum = auditData->memberNum;
uint32_t offset = workSpace->area->currOffset;
workSpace->area->currOffset += realLen;
workSpace->area->securityNodeCount++;

View File

@ -87,6 +87,8 @@ typedef struct {
uint16_t mode;
uint8_t type;
uint8_t length;
uint32_t memberNum;
uid_t members[0];
} ParamSecurityNode;
typedef struct {
@ -134,7 +136,7 @@ typedef struct CachedParameter_ {
typedef void *CachedHandle;
typedef struct _SpaceSize{
typedef struct _SpaceSize {
uint32_t maxLabelIndex;
uint32_t spaceSize[0];
} WorkSpaceSize;

View File

@ -88,6 +88,8 @@ typedef struct {
char label[SELINUX_CONTENT_LEN];
uint32_t selinuxIndex;
#endif
uint32_t memberNum;
uid_t members[1];
} ParamAuditData;
struct WorkSpace_;
@ -127,7 +129,6 @@ INIT_LOCAL_API int RegisterSecuritySelinuxOps(ParamSecurityOps *ops, int isInit)
#endif
INIT_LOCAL_API ParamSecurityOps *GetParamSecurityOps(int type);
INIT_LOCAL_API void LoadGroupUser(void);
INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit);
INIT_LOCAL_API int RegisterSecurityOps(int onlyRead);

View File

@ -63,9 +63,9 @@ STATIC_INLINE ParamTrieNode *FindTrieNode_(
#endif
#define GetWorkSpaceSize(workSpace) \
(workSpace == NULL || workSpace->area == NULL || \
workSpace->area->spaceSizeOffset == 0 || \
workSpace->area->spaceSizeOffset >= workSpace->area->dataSize) ? NULL : \
((workSpace == NULL) || (workSpace->area == NULL) || \
(workSpace->area->spaceSizeOffset == 0) || \
(workSpace->area->spaceSizeOffset >= workSpace->area->dataSize)) ? NULL : \
(WorkSpaceSize*)(workSpace->area->data + workSpace->area->spaceSizeOffset)
#ifdef __cplusplus

View File

@ -95,7 +95,7 @@ int ParamEventSend(const ParamTaskPtr stream, uint64_t eventId, const char *cont
void *ParamGetTaskUserData(const ParamTaskPtr stream);
int FillParamMsgContent(const ParamMessage *request, uint32_t *start, int type, const char *value, uint32_t length);
ParamMsgContent *GetNextContent(const ParamMessage *reqest, uint32_t *offset);
ParamMsgContent *GetNextContent(const ParamMessage *request, uint32_t *offset);
ParamMessage *CreateParamMessage(int type, const char *name, uint32_t msgSize);
int ConnectServer(int fd, const char *servername);

View File

@ -81,7 +81,3 @@ INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit)
}
return ret;
}
INIT_LOCAL_API void LoadGroupUser(void)
{
}

View File

@ -141,12 +141,20 @@ static int DumpTrieDataNodeTraversal(const WorkSpace *workSpace, const ParamTrie
entry->commitId, entry->keyLength, entry->valueLength, entry->data);
}
}
if (current->labelIndex != 0 && verbose) {
ParamSecurityNode *label = (ParamSecurityNode *)GetTrieNode(workSpace, current->labelIndex);
if (label != NULL) {
PARAM_DUMP("\tparameter label dac %u %u %o selinuxIndex %u \n",
label->uid, label->gid, label->mode, label->selinuxIndex);
}
if (current->labelIndex == 0) {
return 0;
}
ParamSecurityNode *label = (ParamSecurityNode *)GetTrieNode(workSpace, current->labelIndex);
if (label == NULL) {
return 0;
}
PARAM_DUMP("\tparameter label dac %u %u 0%o \n", label->uid, label->gid, label->mode);
PARAM_DUMP("\tparameter label dac member [%u] ", label->memberNum);
for (uint32_t i = 0; i < label->memberNum; i++) {
PARAM_DUMP(" %u", label->members[i]);
}
if (label->memberNum > 0) {
PARAM_DUMP("\n");
}
return 0;
}

View File

@ -351,7 +351,7 @@ static int LoadOneParamAreaSize_(const uint32_t *context, const char *name, cons
WorkSpaceSize *spaceSize = GetWorkSpaceSize(GetWorkSpace(WORKSPACE_INDEX_SIZE));
PARAM_CHECK(spaceSize != NULL, return PARAM_CODE_ERROR, "Failed to get workspace size");
static char buffer[SELINUX_CONTENT_LEN] = {0};
int ret = snprintf(buffer, sizeof(buffer) - 1, "u:object_r:%s:s0", name);
int ret = snprintf_s(buffer, sizeof(buffer), sizeof(buffer) - 1, "u:object_r:%s:s0", name);
PARAM_CHECK(ret > 0, return PARAM_CODE_ERROR, "Failed to snprintf workspace name");
for (uint32_t i = WORKSPACE_INDEX_BASE + 1; i < spaceSize->maxLabelIndex; i++) {

View File

@ -78,13 +78,11 @@ uid_t DecodeUid(const char *name)
if (!StringToUint(name, &uid)) {
return uid;
} else {
INIT_LOGE("Failed to decode uid for %s", name);
return -1;
}
}
struct passwd *p = getpwnam(name);
if (p == NULL) {
INIT_LOGE("Failed to decode uid for %s", name);
return -1;
}
return p->pw_uid;
@ -103,7 +101,6 @@ gid_t DecodeGid(const char *name)
if (!StringToUint(name, &gid)) {
return gid;
} else {
INIT_LOGE("Failed to decode gid for %s", name);
return -1;
}
}
@ -134,7 +131,6 @@ char *ReadFileToBuf(const char *configFile)
do {
if (stat(configFile, &fileStat) != 0 ||
fileStat.st_size <= 0 || fileStat.st_size > MAX_JSON_FILE_LEN) {
INIT_LOGE("Unexpected config file \" %s \", check if it exist. if exist, check file size", configFile);
break;
}
fd = fopen(configFile, "r");
@ -496,7 +492,6 @@ int CheckAndCreatFile(const char *file, mode_t mode)
BEGET_LOGE("Failed create %s, err=%d", file, errno);
return -1;
} else {
BEGET_LOGI("Success create %s", file);
close(fd);
}
} else {
@ -588,17 +583,17 @@ int StringReplaceChr(char *strl, char oldChr, char newChr)
return 0;
}
void RedirectStdio(int fd)
{
#ifndef __LITEOS_M__
static void RedirectStdio(int fd)
{
const int stdError = 2;
dup2(fd, 0);
dup2(fd, 1);
dup2(fd, stdError); // Redirect fd to 0, 1, 2
#endif
}
#endif
void OpenConsole(void)
int OpenConsole(void)
{
#ifndef __LITEOS_M__
setsid();
@ -609,9 +604,11 @@ void OpenConsole(void)
RedirectStdio(fd);
close(fd);
} else {
INIT_LOGE("Open /dev/console failed. err = %d", errno);
return errno;
}
return;
return 0;
#else
return 0;
#endif
}

View File

@ -19,7 +19,9 @@
#include <sys/statvfs.h>
#include "init_file.h"
#include "init_service.h"
#include "init_service_file.h"
#include "init_service_manager.h"
#include "param_stub.h"
#include "securec.h"
@ -46,27 +48,22 @@ HWTEST_F(ServiceFileUnitTest, TestServiceFile, TestSize.Level1)
fileOpt->gid = 1000;
fileOpt->fd = -1;
fileOpt->perm = 0770;
if (strncpy_s(fileOpt->fileName, strlen(fileName) + 1, fileName, strlen(fileName)) != 0) {
free(fileOpt);
fileOpt = nullptr;
FAIL();
}
CreateServiceFile(fileOpt);
int ret = GetControlFile("/data/filetest");
int ret = strncpy_s(fileOpt->fileName, strlen(fileName) + 1, fileName, strlen(fileName));
EXPECT_EQ(ret, 0);
Service *service = AddService("test_service8");
ASSERT_NE(nullptr, service);
service->fileCfg = fileOpt;
CreateServiceFile(service);
ret = GetControlFile("/data/filetest");
EXPECT_NE(ret, -1);
if (strncpy_s(fileOpt->fileName, strlen(fileName) + 1, "fileName", strlen("fileName")) != 0) {
free(fileOpt);
fileOpt = nullptr;
FAIL();
}
ret = strncpy_s(fileOpt->fileName, strlen(fileName) + 1, "fileName", strlen("fileName"));
EXPECT_EQ(ret, 0);
fileOpt->fd = 100; // 100 is fd
CreateServiceFile(fileOpt);
CreateServiceFile(service);
CloseServiceFile(fileOpt);
if (strncpy_s(fileOpt->fileName, strlen(fileName) + 1, "/dev/filetest", strlen("/dev/filetest")) != 0) {
free(fileOpt);
fileOpt = nullptr;
FAIL();
}
ret = strncpy_s(fileOpt->fileName, strlen(fileName) + 1, "/dev/filetest", strlen("/dev/filetest"));
EXPECT_EQ(ret, 0);
char *wrongName = (char *)malloc(PATH_MAX);
ASSERT_NE(wrongName, nullptr);
EXPECT_EQ(memset_s(wrongName, PATH_MAX, 1, PATH_MAX), 0);
@ -78,13 +75,13 @@ HWTEST_F(ServiceFileUnitTest, TestServiceFile, TestSize.Level1)
GetControlFile("testPath");
EXPECT_EQ(setenv("OHOS_FILE_ENV_PREFIX_testPath1", "aaaaaaaa", 0), 0);
GetControlFile("testPath1");
free(wrongName);
fileOpt->fd = -1;
CreateServiceFile(fileOpt);
CreateServiceFile(service);
CloseServiceFile(fileOpt);
free(fileOpt);
free(wrongName);
fileOpt = nullptr;
wrongName = nullptr;
service->fileCfg = nullptr;
ReleaseService(service);
}
}

View File

@ -71,7 +71,7 @@ HWTEST_F(ServiceUnitTest, case01, TestSize.Level1)
int ret = ParseOneService(serviceItem, service);
EXPECT_EQ(ret, 0);
ret = ServiceStart(service);
ret = ServiceStart(service, &service->pathArgs);
EXPECT_EQ(ret, 0);
ret = ServiceStop(service);
@ -98,7 +98,7 @@ HWTEST_F(ServiceUnitTest, case02, TestSize.Level1)
int fds[1] = {-1}; // ServiceStop will release fds
UpdaterServiceFds(service, fds, 1);
service->attribute = SERVICE_ATTR_ONDEMAND;
ret = ServiceStart(service);
ret = ServiceStart(service, &service->pathArgs);
EXPECT_EQ(ret, 0);
CmdLines *cmdline = (CmdLines *)malloc(sizeof(CmdLines) + sizeof(CmdLine));
ASSERT_NE(nullptr, cmdline);
@ -138,11 +138,11 @@ HWTEST_F(ServiceUnitTest, TestServiceStartAbnormal, TestSize.Level1)
int ret = ParseOneService(serviceItem, service);
EXPECT_EQ(ret, 0);
ret = ServiceStart(service);
ret = ServiceStart(service, &service->pathArgs);
EXPECT_EQ(ret, 0);
service->attribute &= SERVICE_ATTR_INVALID;
ret = ServiceStart(service);
ret = ServiceStart(service, &service->pathArgs);
EXPECT_EQ(ret, 0);
service->pid = -1;
@ -373,7 +373,7 @@ HWTEST_F(ServiceUnitTest, TestServiceExec, TestSize.Level1)
service->servPerm.capsCnt = 1;
IsEnableSandbox();
EnterServiceSandbox(service);
int ret = ServiceExec(service);
int ret = ServiceExec(service, &service->pathArgs);
EXPECT_EQ(ret, 0);
const int invalidImportantValue = 20;

View File

@ -935,7 +935,7 @@ HWTEST_F(StartupInitUTest, cmdJobTest_001, TestSize.Level0)
StartServiceByName("service name does not exist");
StopAllServices(0, nullptr, 0, nullptr);
ServiceReap(nullptr);
EXPECT_NE(0, ServiceStart(nullptr));
EXPECT_NE(0, ServiceStart(nullptr, nullptr));
EXPECT_NE(0, ServiceStop(nullptr));
}

View File

@ -595,11 +595,13 @@ static __attribute__((constructor(101))) void ParamTestStubInit(void)
PARAM_LOGI("TestSetSelinuxOps \n");
#ifndef OHOS_LITE
TestBeforeInit();
#endif
SystemPrepare();
#ifndef __LITEOS_A__
SystemInit();
#endif
PARAM_LOGI("SystemConfig \n");
SystemConfig();
#endif
PrepareInitUnitTestEnv();
}

View File

@ -378,10 +378,14 @@ HWTEST_F(SysparaUnitTest, parameterTest0016, TestSize.Level0)
HWTEST_F(SysparaUnitTest, parameterTest0017, TestSize.Level0)
{
GetDistributionOSName();
GetDistributionOSVersion();
GetDistributionOSApiVersion();
GetDistributionOSReleaseType();
printf("distributionOS name =%s\n", GetDistributionOSName());
EXPECT_STRNE(GetDistributionOSName(), nullptr);
printf("distributionOS version =%s\n", GetDistributionOSVersion());
EXPECT_STRNE(GetDistributionOSVersion(), nullptr);
printf("distributionOS api version =%d\n", GetDistributionOSApiVersion());
EXPECT_GT(GetDistributionOSApiVersion(), 0);
printf("distributionOS name =%s\n", GetDistributionOSReleaseType());
EXPECT_STRNE(GetDistributionOSReleaseType(), nullptr);
}
#endif
} // namespace OHOS