mirror of
https://gitee.com/openharmony/startup_init
synced 2025-02-12 07:11:14 +00:00
do check pid == 1
Signed-off-by: cheng_jinsong <chengjinsong2@huawei.com>
This commit is contained in:
parent
eb7f01f891
commit
b44932ec0f
@ -19,6 +19,11 @@
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
#include <signal.h>
|
||||
#undef _GNU_SOURCE
|
||||
#define _GNU_SOURCE
|
||||
#include <sched.h>
|
||||
|
||||
#include "begetctl.h"
|
||||
#include "param_manager.h"
|
||||
@ -32,6 +37,14 @@
|
||||
#include "selinux_parameter.h"
|
||||
#endif // PARAM_SUPPORT_SELINUX
|
||||
|
||||
typedef struct {
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
int cloneFlg;
|
||||
char *parameter;
|
||||
} ParamShellExecArgs;
|
||||
|
||||
#define STACK_SIZE (1024 * 1024 * 8)
|
||||
#define MASK_LENGTH_MAX 4
|
||||
pid_t g_shellPid = 0;
|
||||
static struct termios g_terminalState;
|
||||
@ -380,27 +393,60 @@ static int32_t BShellParamCmdPwd(BShellHandle shell, int32_t argc, char *argv[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
void GetUserInfo(uid_t *uid, gid_t *gid, char **parameter, int32_t argc, char *argv[])
|
||||
static void GetUserInfo(ParamShellExecArgs *execArg, int32_t argc, char *argv[])
|
||||
{
|
||||
int32_t i = 0;
|
||||
*parameter = NULL;
|
||||
execArg->parameter = NULL;
|
||||
while (i < argc) {
|
||||
if (strcmp(argv[i], "-p") == 0 && ((i + 1) < argc)) {
|
||||
*parameter = argv[i + 1];
|
||||
execArg->parameter = argv[i + 1];
|
||||
++i;
|
||||
} else if (strcmp(argv[i], "-u") == 0 && ((i + 1) < argc)) {
|
||||
*uid = DecodeUid(argv[i + 1]);
|
||||
*uid = (*uid == -1) ? 0 : *uid;
|
||||
execArg->uid = DecodeUid(argv[i + 1]);
|
||||
execArg->uid = (execArg->uid == -1) ? 0 : execArg->uid;
|
||||
++i;
|
||||
} else if (strcmp(argv[i], "-g") == 0 && ((i + 1) < argc)) {
|
||||
*gid = DecodeGid(argv[i + 1]);
|
||||
*gid = (*gid == -1) ? 0 : *gid;
|
||||
execArg->gid = DecodeGid(argv[i + 1]);
|
||||
execArg->gid = (execArg->gid == -1) ? 0 : execArg->gid;
|
||||
++i;
|
||||
} else if (strcmp(argv[i], "-c") == 0) {
|
||||
execArg->cloneFlg = 1;
|
||||
}
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
static int ExecFunc(void *arg)
|
||||
{
|
||||
ParamShellExecArgs *execArg = (ParamShellExecArgs *)arg;
|
||||
int ret = 0;
|
||||
setuid(execArg->uid);
|
||||
setgid(execArg->gid);
|
||||
BSH_LOGI("Exec shell %s \n", SHELL_NAME);
|
||||
if (execArg->parameter != NULL) { // 2 min argc
|
||||
char *args[] = {SHELL_NAME, execArg->parameter, NULL};
|
||||
ret = execv(CMD_PATH, args);
|
||||
} else {
|
||||
char *args[] = {SHELL_NAME, NULL};
|
||||
ret = execv(CMD_PATH, args);
|
||||
}
|
||||
if (ret != 0) {
|
||||
printf("error on exec %d \n", errno);
|
||||
exit(0);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static pid_t ForkChild(int (*childFunc)(void *arg), void *args)
|
||||
{
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
childFunc(args);
|
||||
exit(0);
|
||||
}
|
||||
return pid;
|
||||
}
|
||||
|
||||
static int32_t BShellParamCmdShell(BShellHandle shell, int32_t argc, char *argv[])
|
||||
{
|
||||
#ifndef STARTUP_INIT_TEST
|
||||
@ -410,36 +456,27 @@ static int32_t BShellParamCmdShell(BShellHandle shell, int32_t argc, char *argv[
|
||||
return BSH_SYSTEM_ERR;
|
||||
}
|
||||
g_isSetTerminal = 1;
|
||||
uid_t uid = 0;
|
||||
gid_t gid = 0;
|
||||
char *parameter = NULL;
|
||||
GetUserInfo(&uid, &gid, ¶meter, argc, argv);
|
||||
BSH_LOGV("BShellParamCmdShell %s %d %d argc %d", parameter, uid, gid, argc);
|
||||
if (parameter != NULL) {
|
||||
ret = SystemCheckParamExist(parameter);
|
||||
ParamShellExecArgs args = {0, 0, 0, NULL};
|
||||
GetUserInfo(&args, argc, argv);
|
||||
BSH_LOGV("BShellParamCmdShell %s %d %d argc %d", args.parameter, args.uid, args.gid, argc);
|
||||
if (args.parameter != NULL) {
|
||||
ret = SystemCheckParamExist(args.parameter);
|
||||
if (ret != 0) {
|
||||
BShellEnvOutput(shell, "Error: parameter \'%s\' not found\r\n", parameter);
|
||||
BShellEnvOutput(shell, "Error: parameter \'%s\' not found\r\n", args.parameter);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
SetInitLogLevel(INIT_INFO);
|
||||
pid_t pid = fork();
|
||||
if (pid == 0) {
|
||||
setuid(uid);
|
||||
setgid(gid);
|
||||
if (parameter != NULL) { // 2 min argc
|
||||
char *args[] = {SHELL_NAME, parameter, NULL};
|
||||
ret = execv(CMD_PATH, args);
|
||||
} else {
|
||||
char *args[] = {SHELL_NAME, NULL};
|
||||
ret = execv(CMD_PATH, args);
|
||||
}
|
||||
if (ret < 0) {
|
||||
printf("error on exec %d \n", errno);
|
||||
exit(0);
|
||||
}
|
||||
exit(0);
|
||||
} else if (pid > 0) {
|
||||
pid_t pid = 0;
|
||||
if (args.cloneFlg) {
|
||||
char *childStack = (char *)malloc(STACK_SIZE);
|
||||
BSH_CHECK(childStack != NULL, return -1, "malloc failed");
|
||||
pid = clone(ExecFunc, childStack + STACK_SIZE, CLONE_NEWPID | CLONE_NEWNS | SIGCHLD, (void *)&args);
|
||||
free(childStack);
|
||||
} else {
|
||||
pid = ForkChild(ExecFunc, (void *)&args);
|
||||
}
|
||||
if (pid > 0) {
|
||||
g_shellPid = pid;
|
||||
int status = 0;
|
||||
wait(&status);
|
||||
|
@ -56,7 +56,7 @@ static int InitSelinuxOpsForInit(SelinuxSpace *selinuxSpace)
|
||||
PARAM_CHECK(selinuxSpace->getParamLabel != NULL, return -1, "Failed to dlsym getParamLabel %s", dlerror());
|
||||
}
|
||||
if (selinuxSpace->initParamSelinux == NULL) {
|
||||
selinuxSpace->initParamSelinux = (int (*)())dlsym(handle, "InitParamSelinux");
|
||||
selinuxSpace->initParamSelinux = (int (*)(int))dlsym(handle, "InitParamSelinux");
|
||||
PARAM_CHECK(selinuxSpace->initParamSelinux != NULL, return -1, "Failed to dlsym initParamSelinux ");
|
||||
}
|
||||
if (selinuxSpace->getParamLabelIndex == NULL) {
|
||||
@ -74,7 +74,7 @@ static int InitSelinuxOpsForInit(SelinuxSpace *selinuxSpace)
|
||||
}
|
||||
|
||||
// init and open avc log
|
||||
int ret = selinuxSpace->initParamSelinux();
|
||||
int ret = selinuxSpace->initParamSelinux(1);
|
||||
if (selinuxSpace->setSelinuxLogCallback != NULL) {
|
||||
selinuxSpace->setSelinuxLogCallback();
|
||||
}
|
||||
@ -103,7 +103,7 @@ static int InitLocalSecurityLabel(ParamSecurityLabel *security, int isInit)
|
||||
selinuxSpace->destroyParamList = DestroyParamList;
|
||||
selinuxSpace->getParamLabelIndex = GetParamLabelIndex;
|
||||
// init
|
||||
selinuxSpace->initParamSelinux();
|
||||
selinuxSpace->initParamSelinux(isInit);
|
||||
}
|
||||
#endif
|
||||
PARAM_LOGV("Load selinux lib success.");
|
||||
|
@ -107,6 +107,14 @@ static int CheckNeedInit(int onlyRead, const PARAM_WORKSPACE_OPS *ops)
|
||||
#endif
|
||||
}
|
||||
if (PARAM_TEST_FLAG(g_paramWorkSpace.flags, WORKSPACE_FLAGS_INIT)) {
|
||||
PARAM_LOGV("Param workspace has been init");
|
||||
if (PARAM_TEST_FLAG(g_paramWorkSpace.flags, WORKSPACE_FLAGS_FOR_INIT)) {
|
||||
return 0; // init has been init workspace, do not init
|
||||
}
|
||||
if (onlyRead == 0) { // init not init workspace, do init it
|
||||
CloseParamWorkSpace();
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
if (onlyRead == 0) {
|
||||
@ -132,8 +140,10 @@ INIT_INNER_API int InitParamWorkSpace(int onlyRead, const PARAM_WORKSPACE_OPS *o
|
||||
}
|
||||
paramMutexEnvInit();
|
||||
g_paramWorkSpace.maxLabelIndex = PARAM_DEF_SELINUX_LABEL;
|
||||
g_paramWorkSpace.workSpace = (WorkSpace **)calloc(g_paramWorkSpace.maxLabelIndex, sizeof(WorkSpace *));
|
||||
PARAM_CHECK(g_paramWorkSpace.workSpace != NULL, return -1, "Failed to alloc memory for workSpace");
|
||||
if (!PARAM_TEST_FLAG(g_paramWorkSpace.flags, WORKSPACE_FLAGS_INIT)) {
|
||||
g_paramWorkSpace.workSpace = (WorkSpace **)calloc(g_paramWorkSpace.maxLabelIndex, sizeof(WorkSpace *));
|
||||
PARAM_CHECK(g_paramWorkSpace.workSpace != NULL, return -1, "Failed to alloc memory for workSpace");
|
||||
}
|
||||
PARAM_SET_FLAG(g_paramWorkSpace.flags, WORKSPACE_FLAGS_INIT);
|
||||
|
||||
int ret = RegisterSecurityOps(onlyRead);
|
||||
@ -166,6 +176,7 @@ INIT_INNER_API int InitParamWorkSpace(int onlyRead, const PARAM_WORKSPACE_OPS *o
|
||||
#endif
|
||||
ret = AddSecurityLabel(&auditData);
|
||||
PARAM_CHECK(ret == 0, return ret, "Failed to add default dac label");
|
||||
PARAM_SET_FLAG(g_paramWorkSpace.flags, WORKSPACE_FLAGS_FOR_INIT);
|
||||
} else {
|
||||
ret = OpenWorkSpace(WORKSPACE_INDEX_DAC, onlyRead);
|
||||
PARAM_CHECK(ret == 0, return -1, "Failed to open dac workspace");
|
||||
@ -237,9 +248,6 @@ int SystemReadParam(const char *name, char *value, uint32_t *len)
|
||||
|
||||
void InitParameterClient(void)
|
||||
{
|
||||
if (getpid() == 1) {
|
||||
return;
|
||||
}
|
||||
PARAM_WORKSPACE_OPS ops = {0};
|
||||
ops.updaterMode = 0;
|
||||
InitParamWorkSpace(1, &ops);
|
||||
@ -257,28 +265,27 @@ INIT_LOCAL_API int AddWorkSpace(const char *name, uint32_t labelIndex, int onlyR
|
||||
#endif
|
||||
int ret = CheckAndExtendSpace(paramSpace, name, labelIndex);
|
||||
PARAM_CHECK(ret == 0, return -1, "Not enough memory for %s", realName);
|
||||
if (paramSpace->workSpace[labelIndex] != NULL) {
|
||||
return 0;
|
||||
if (paramSpace->workSpace[labelIndex] == NULL) {
|
||||
const size_t size = strlen(realName) + 1;
|
||||
WorkSpace *workSpace = (WorkSpace *)malloc(sizeof(WorkSpace) + size);
|
||||
PARAM_CHECK(workSpace != NULL, return -1, "Failed to create workspace for %s", realName);
|
||||
workSpace->flags = 0;
|
||||
workSpace->spaceSize = spaceSize;
|
||||
workSpace->area = NULL;
|
||||
workSpace->spaceIndex = labelIndex;
|
||||
ATOMIC_INIT(&workSpace->rwSpaceLock, 0);
|
||||
PARAMSPACE_AREA_INIT_LOCK(workSpace);
|
||||
ret = ParamStrCpy(workSpace->fileName, size, realName);
|
||||
PARAM_CHECK(ret == 0, free(workSpace);
|
||||
return -1, "Failed to copy file name %s", realName);
|
||||
paramSpace->workSpace[labelIndex] = workSpace;
|
||||
}
|
||||
|
||||
const size_t size = strlen(realName) + 1;
|
||||
WorkSpace *workSpace = (WorkSpace *)malloc(sizeof(WorkSpace) + size);
|
||||
PARAM_CHECK(workSpace != NULL, return -1, "Failed to create workspace for %s", realName);
|
||||
workSpace->flags = 0;
|
||||
workSpace->spaceSize = spaceSize;
|
||||
workSpace->area = NULL;
|
||||
workSpace->spaceIndex = labelIndex;
|
||||
ATOMIC_INIT(&workSpace->rwSpaceLock, 0);
|
||||
PARAMSPACE_AREA_INIT_LOCK(workSpace);
|
||||
ret = ParamStrCpy(workSpace->fileName, size, realName);
|
||||
PARAM_CHECK(ret == 0, free(workSpace);
|
||||
return -1, "Failed to copy file name %s", realName);
|
||||
paramSpace->workSpace[labelIndex] = workSpace;
|
||||
if (!onlyRead) {
|
||||
PARAM_LOGI("AddWorkSpace %s index %d spaceSize: %u onlyRead %s",
|
||||
workSpace->fileName, workSpace->spaceIndex, workSpace->spaceSize, onlyRead ? "true" : "false");
|
||||
paramSpace->workSpace[labelIndex]->fileName, paramSpace->workSpace[labelIndex]->spaceIndex,
|
||||
paramSpace->workSpace[labelIndex]->spaceSize, onlyRead ? "true" : "false");
|
||||
ret = OpenWorkSpace(labelIndex, onlyRead);
|
||||
PARAM_CHECK(ret == 0, free(workSpace);
|
||||
PARAM_CHECK(ret == 0, free(paramSpace->workSpace[labelIndex]);
|
||||
paramSpace->workSpace[labelIndex] = NULL;
|
||||
return -1, "Failed to open workspace for name %s", realName);
|
||||
}
|
||||
@ -322,6 +329,7 @@ STATIC_INLINE ParamTrieNode *GetTrieNodeByHandle(ParamHandle handle)
|
||||
|
||||
int SystemGetParameterCommitId(ParamHandle handle, uint32_t *commitId)
|
||||
{
|
||||
PARAM_ONLY_CHECK(handle != (ParamHandle)-1, return PARAM_CODE_NOT_FOUND);
|
||||
PARAM_CHECK(handle != 0 && commitId != NULL, return -1, "The handle is null");
|
||||
ParamNode *entry = (ParamNode *)GetTrieNodeByHandle(handle);
|
||||
if (entry == NULL) {
|
||||
@ -343,6 +351,7 @@ long long GetSystemCommitId(void)
|
||||
|
||||
int SystemGetParameterValue(ParamHandle handle, char *value, unsigned int *len)
|
||||
{
|
||||
PARAM_ONLY_CHECK(handle != (ParamHandle)-1, return PARAM_CODE_NOT_FOUND);
|
||||
PARAM_CHECK(len != NULL && handle != 0, return -1, "The value is null");
|
||||
return ReadParamValue((ParamNode *)GetTrieNodeByHandle(handle), value, len);
|
||||
}
|
||||
@ -379,6 +388,7 @@ INIT_LOCAL_API int OpenWorkSpace(uint32_t index, int readOnly)
|
||||
workSpace = paramSpace->workSpace[index];
|
||||
}
|
||||
if (workSpace == NULL) {
|
||||
PARAM_LOGE("Invalid index %d", index);
|
||||
return 0;
|
||||
}
|
||||
int ret = 0;
|
||||
@ -448,11 +458,12 @@ static int GetParamLabelInfo(const char *name, ParamLabelIndex *labelIndex, Para
|
||||
if ((securityNode == NULL) || (securityNode->selinuxIndex == 0) ||
|
||||
(securityNode->selinuxIndex == INVALID_SELINUX_INDEX)) {
|
||||
labelIndex->workspace = GetWorkSpaceByName(name);
|
||||
PARAM_CHECK(labelIndex->workspace != NULL, return DAC_RESULT_FORBIDED, "Invalid workSpace for %s", name);
|
||||
} else if (securityNode->selinuxIndex < g_paramWorkSpace.maxLabelIndex) {
|
||||
labelIndex->workspace = g_paramWorkSpace.workSpace[securityNode->selinuxIndex];
|
||||
PARAM_CHECK(labelIndex->workspace != NULL, return DAC_RESULT_FORBIDED,
|
||||
"Invalid workSpace for %s %d", name, securityNode->selinuxIndex);
|
||||
}
|
||||
PARAM_CHECK(labelIndex->workspace != NULL, return DAC_RESULT_FORBIDED,
|
||||
"Invalid workSpace for %s %d", name, securityNode->selinuxIndex);
|
||||
labelIndex->selinuxLabelIndex = labelIndex->workspace->spaceIndex;
|
||||
return 0;
|
||||
}
|
||||
@ -629,8 +640,9 @@ STATIC_INLINE int CheckParamPermission_(const ParamLabelIndex *labelIndex,
|
||||
STATIC_INLINE int CheckParamPermission_(const ParamLabelIndex *labelIndex,
|
||||
const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
|
||||
{
|
||||
// for root, all permission, but for appspawn must to check
|
||||
if (srcLabel->cred.uid == 0 && srcLabel->cred.pid == 1) {
|
||||
// only for root and write, all permission, but for appspawn must to check
|
||||
// for clod start in new namespace, pid==1 and uid==root
|
||||
if (srcLabel->cred.uid == 0 && srcLabel->cred.pid == 1 && mode == DAC_WRITE) {
|
||||
return DAC_RESULT_PERMISSION;
|
||||
}
|
||||
int ret = DacCheckParamPermission(labelIndex, srcLabel, name, mode);
|
||||
@ -679,6 +691,7 @@ CachedHandle CachedParameterCreate(const char *name, const char *defValue)
|
||||
WorkSpace *workspace = NULL;
|
||||
int ret = ReadParamWithCheck(&workspace, name, DAC_READ, &node);
|
||||
PARAM_CHECK(ret == 0, return NULL, "Forbid to access parameter %s", name);
|
||||
PARAM_CHECK(workspace != NULL && workspace->area != NULL, return NULL, "Forbid to access parameter %s", name);
|
||||
|
||||
CachedParameter *param = (CachedParameter *)malloc(
|
||||
sizeof(CachedParameter) + PARAM_ALIGN(nameLen) + 1 + PARAM_VALUE_LEN_MAX);
|
||||
|
@ -298,7 +298,7 @@ INIT_LOCAL_API ParamTrieNode *FindTrieNode(WorkSpace *workSpace,
|
||||
const char *key, uint32_t keyLen, uint32_t *matchLabel)
|
||||
{
|
||||
PARAM_ONLY_CHECK(key != NULL && keyLen > 0, return NULL);
|
||||
|
||||
PARAM_CHECK(workSpace != NULL, return NULL, "Invalid workspace for %s", key);
|
||||
uint32_t tmpMatchLen = 0;
|
||||
ParamTrieNode *node = NULL;
|
||||
PARAMSPACE_AREA_RD_LOCK(workSpace);
|
||||
@ -342,6 +342,7 @@ INIT_LOCAL_API ParamNode *GetParamNode(uint32_t index, const char *name)
|
||||
INIT_LOCAL_API int AddParamEntry(uint32_t index, uint8_t type, const char *name, const char *value)
|
||||
{
|
||||
WorkSpace *workSpace = GetWorkSpace(WORKSPACE_INDEX_BASE);
|
||||
PARAM_CHECK(workSpace != NULL, return PARAM_CODE_ERROR, "Invalid workspace");
|
||||
ParamTrieNode *node = FindTrieNode(workSpace, name, strlen(name), NULL);
|
||||
if (node != NULL && node->dataIndex != 0) {
|
||||
return 0;
|
||||
|
@ -114,7 +114,7 @@ typedef struct SelinuxSpace_ {
|
||||
void (*setSelinuxLogCallback)(void);
|
||||
int (*setParamCheck)(const char *paraName, const char *destContext, const SrcInfo *info);
|
||||
const char *(*getParamLabel)(const char *paraName);
|
||||
int (*initParamSelinux)(void);
|
||||
int (*initParamSelinux)(int isInit);
|
||||
int (*readParamCheck)(const char *paraName);
|
||||
ParamContextsList *(*getParamList)(void);
|
||||
void (*destroyParamList)(ParamContextsList **list);
|
||||
|
@ -85,6 +85,7 @@ typedef enum {
|
||||
#define WORKSPACE_FLAGS_UPDATE 0x04
|
||||
#define WORKSPACE_FLAGS_LABEL_LOADED 0x08
|
||||
#define WORKSPACE_FLAGS_NEED_ACCESS 0x10
|
||||
#define WORKSPACE_FLAGS_FOR_INIT 0x20
|
||||
|
||||
#define PARAM_SET_FLAG(node, flag) ((node) |= (flag))
|
||||
#define PARAM_CLEAR_FLAG(node, flag) ((node) &= ~(flag))
|
||||
|
@ -36,9 +36,6 @@ static pthread_mutex_t g_clientMutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
|
||||
__attribute__((constructor)) static void ParameterInit(void)
|
||||
{
|
||||
if (getpid() == 1) {
|
||||
return;
|
||||
}
|
||||
ATOMIC_INIT(&g_requestId, 1);
|
||||
EnableInitLog(INIT_WARN);
|
||||
PARAM_WORKSPACE_OPS ops = {0};
|
||||
|
Loading…
x
Reference in New Issue
Block a user