提交 b44932ec 编写于 作者: C cheng_jinsong

do check pid == 1

Signed-off-by: Ncheng_jinsong <chengjinsong2@huawei.com>
上级 eb7f01f8
......@@ -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, &parameter, 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};
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册