未验证 提交 e93900e6 编写于 作者: O openharmony_ci 提交者: Gitee

!1592 系统优化:readparam性能优化

Merge pull request !1592 from cheng_jinsong/init-readpara
...@@ -35,6 +35,8 @@ declare_args() { ...@@ -35,6 +35,8 @@ declare_args() {
startup_init_feature_decode_group_file = false startup_init_feature_decode_group_file = false
startup_init_test_performance = true
startup_init_with_param_base = false startup_init_with_param_base = false
if (!use_musl) { if (!use_musl) {
startup_init_with_param_base = true startup_init_with_param_base = true
......
...@@ -161,6 +161,9 @@ if (defined(ohos_lite)) { ...@@ -161,6 +161,9 @@ if (defined(ohos_lite)) {
] ]
} }
if (startup_init_test_performance) {
defines += [ "PARAM_TEST_PERFORMANCE" ]
}
install_images = [ "system" ] install_images = [ "system" ]
install_enable = true install_enable = true
......
...@@ -358,11 +358,16 @@ static int32_t BShellParamCmdWait(BShellHandle shell, int32_t argc, char *argv[] ...@@ -358,11 +358,16 @@ static int32_t BShellParamCmdWait(BShellHandle shell, int32_t argc, char *argv[]
static int32_t BShellParamCmdDump(BShellHandle shell, int32_t argc, char *argv[]) static int32_t BShellParamCmdDump(BShellHandle shell, int32_t argc, char *argv[])
{ {
BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env"); BSH_CHECK(shell != NULL, return BSH_INVALID_PARAM, "Invalid shell env");
if (argc >= 2 && strcmp(argv[1], "verbose") == 0) { // 2 min arg if (argc >= 2) { // 2 min parameter
SystemDumpParameters(1, printf); if (strcmp(argv[1], "verbose") == 0) {
} else { SystemDumpParameters(1, -1, printf);
SystemDumpParameters(0, printf); return 0;
}
int index = StringToInt(argv[1], 0);
SystemDumpParameters(1, index, printf);
return 0;
} }
SystemDumpParameters(0, -1, printf);
return 0; return 0;
} }
......
...@@ -193,10 +193,12 @@ int SystemWatchParameter(const char *keyprefix, ParameterChangePtr change, void ...@@ -193,10 +193,12 @@ int SystemWatchParameter(const char *keyprefix, ParameterChangePtr change, void
int SystemCheckParamExist(const char *name); int SystemCheckParamExist(const char *name);
void SystemDumpParameters(int verbose, int (*dump)(const char *fmt, ...)); void SystemDumpParameters(int verbose, int index, int (*dump)(const char *fmt, ...));
int WatchParamCheck(const char *keyprefix); int WatchParamCheck(const char *keyprefix);
void ResetParamSecurityLabel(void);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -24,6 +24,7 @@ extern "C" { ...@@ -24,6 +24,7 @@ extern "C" {
#endif #endif
typedef uint32_t ParamHandle; typedef uint32_t ParamHandle;
typedef void *CachedHandle;
typedef struct { typedef struct {
uint8_t updaterMode; uint8_t updaterMode;
...@@ -72,6 +73,27 @@ int SystemGetParameterValue(ParamHandle handle, char *value, unsigned int *len); ...@@ -72,6 +73,27 @@ int SystemGetParameterValue(ParamHandle handle, char *value, unsigned int *len);
long long GetSystemCommitId(void); long long GetSystemCommitId(void);
/**
* 外部接口
* 保存相关的parameter信息,包括workspace,和各层的commit。
*
*/
CachedHandle CachedParameterCreate(const char *name, const char *defValue);
/**
* 外部接口
* 如果获取到value,返回对应的 paramValue的指针,否则返回上面定义的defValue
*
*/
const char *CachedParameterGet(CachedHandle handle);
/**
* 外部接口
* 释放handle内存
*
*/
void CachedParameterDestroy(CachedHandle handle);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -119,11 +119,8 @@ static void PrintLog(InitLogLevel logLevel, unsigned int domain, const char *tag ...@@ -119,11 +119,8 @@ static void PrintLog(InitLogLevel logLevel, unsigned int domain, const char *tag
#endif #endif
} }
INIT_LOCAL_API void InitLog(int logLevel, unsigned int domain, const char *tag, const char *fmt, va_list vargs) static void PrintLog_(int logLevel, unsigned int domain, const char *tag, const char *fmt, va_list vargs)
{ {
if ((int)g_logLevel > logLevel) {
return;
}
char tmpFmt[DEF_LOG_SIZE] = {0}; char tmpFmt[DEF_LOG_SIZE] = {0};
if (vsnprintf_s(tmpFmt, sizeof(tmpFmt), sizeof(tmpFmt) - 1, fmt, vargs) == -1) { if (vsnprintf_s(tmpFmt, sizeof(tmpFmt), sizeof(tmpFmt) - 1, fmt, vargs) == -1) {
tmpFmt[sizeof(tmpFmt) - 2] = '\n'; // 2 add \n to tail tmpFmt[sizeof(tmpFmt) - 2] = '\n'; // 2 add \n to tail
...@@ -132,6 +129,14 @@ INIT_LOCAL_API void InitLog(int logLevel, unsigned int domain, const char *tag, ...@@ -132,6 +129,14 @@ INIT_LOCAL_API void InitLog(int logLevel, unsigned int domain, const char *tag,
PrintLog((InitLogLevel)logLevel, domain, tag, tmpFmt); PrintLog((InitLogLevel)logLevel, domain, tag, tmpFmt);
} }
INIT_LOCAL_API void InitLog(int logLevel, unsigned int domain, const char *tag, const char *fmt, va_list vargs)
{
if ((int)g_logLevel > logLevel) {
return;
}
PrintLog_((InitLogLevel)logLevel, domain, tag, fmt, vargs);
}
INIT_PUBLIC_API void SetInitLogLevel(InitLogLevel level) INIT_PUBLIC_API void SetInitLogLevel(InitLogLevel level)
{ {
if (level <= INIT_FATAL) { if (level <= INIT_FATAL) {
......
...@@ -25,9 +25,7 @@ ...@@ -25,9 +25,7 @@
#include "param_utils.h" #include "param_utils.h"
#include "param_base.h" #include "param_base.h"
#define USER_BUFFER_LEN 64
#define MAX_BUF_SIZE 1024 #define MAX_BUF_SIZE 1024
#define GROUP_FORMAT "const.group"
#define INVALID_MODE 0550 #define INVALID_MODE 0550
#ifdef STARTUP_INIT_TEST #ifdef STARTUP_INIT_TEST
#define GROUP_FILE_PATH STARTUP_INIT_UT_PATH "/etc/group" #define GROUP_FILE_PATH STARTUP_INIT_UT_PATH "/etc/group"
...@@ -223,66 +221,6 @@ static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char ...@@ -223,66 +221,6 @@ static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char
return 0; return 0;
} }
static int CheckUserInGroup(WorkSpace *space, gid_t groupId, uid_t uid)
{
char buffer[USER_BUFFER_LEN] = {0};
uint32_t labelIndex = 0;
int ret = ParamSprintf(buffer, sizeof(buffer), "%s.%d.%d", GROUP_FORMAT, groupId, uid);
PARAM_CHECK(ret >= 0, return -1, "Failed to format name for %s.%d.%d", GROUP_FORMAT, groupId, uid);
(void)FindTrieNode(space, buffer, strlen(buffer), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(space, labelIndex);
PARAM_CHECK(node != NULL, return DAC_RESULT_FORBIDED, "Can not get security label %d", labelIndex);
PARAM_LOGV("CheckUserInGroup %s groupid %d uid %d", buffer, node->gid, node->uid);
if (node->gid == groupId && node->uid == uid) {
return 0;
}
return -1;
}
static int DacCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
{
#ifndef STARTUP_INIT_TEST
if (srcLabel->cred.uid == 0) {
return DAC_RESULT_PERMISSION;
}
#endif
int ret = DAC_RESULT_FORBIDED;
uint32_t labelIndex = 0;
// get dac label
WorkSpace *space = GetWorkSpace(WORKSPACE_NAME_DAC);
PARAM_CHECK(space != NULL, return DAC_RESULT_FORBIDED, "Failed to get dac space %s", name);
(void)FindTrieNode(space, name, strlen(name), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(space, labelIndex);
PARAM_CHECK(node != NULL, return DAC_RESULT_FORBIDED, "Can not get security label %d", labelIndex);
/**
* DAC group
* user:group:read|write|watch
*/
uint32_t localMode;
if (srcLabel->cred.uid == node->uid) {
localMode = mode & (DAC_READ | DAC_WRITE | DAC_WATCH);
} else if (srcLabel->cred.gid == node->gid) {
localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> DAC_GROUP_START;
} else if (CheckUserInGroup(space, node->gid, srcLabel->cred.uid) == 0) { // user in group
localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> DAC_GROUP_START;
} else {
localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> DAC_OTHER_START;
}
if ((node->mode & localMode) != 0) {
ret = DAC_RESULT_PERMISSION;
}
if (ret != DAC_RESULT_PERMISSION) {
PARAM_LOGW("Param '%s' label gid:%d uid:%d mode 0%o", name, srcLabel->cred.gid, srcLabel->cred.uid, localMode);
PARAM_LOGW("Cfg label %d gid:%d uid:%d mode 0%o ", labelIndex, node->gid, node->uid, node->mode);
#ifndef __MUSL__
#ifndef STARTUP_INIT_TEST
ret = DAC_RESULT_PERMISSION;
#endif
#endif
}
return ret;
}
INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit) INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit)
{ {
PARAM_CHECK(ops != NULL, return -1, "Invalid param"); PARAM_CHECK(ops != NULL, return -1, "Invalid param");
...@@ -290,7 +228,9 @@ INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit) ...@@ -290,7 +228,9 @@ INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit)
int ret = ParamStrCpy(ops->name, sizeof(ops->name), "dac"); int ret = ParamStrCpy(ops->name, sizeof(ops->name), "dac");
ops->securityInitLabel = InitLocalSecurityLabel; ops->securityInitLabel = InitLocalSecurityLabel;
ops->securityCheckFilePermission = CheckFilePermission; ops->securityCheckFilePermission = CheckFilePermission;
#ifdef STARTUP_INIT_TEST
ops->securityCheckParamPermission = DacCheckParamPermission; ops->securityCheckParamPermission = DacCheckParamPermission;
#endif
ops->securityFreeLabel = FreeLocalSecurityLabel; ops->securityFreeLabel = FreeLocalSecurityLabel;
if (isInit) { if (isInit) {
ops->securityGetLabel = DacGetParamSecurityLabel; ops->securityGetLabel = DacGetParamSecurityLabel;
...@@ -310,15 +250,10 @@ static void AddGroupUser(const char *userName, gid_t gid) ...@@ -310,15 +250,10 @@ static void AddGroupUser(const char *userName, gid_t gid)
PARAM_LOGW("Invalid user for '%s' gid %d uid %d", userName, gid, uid); PARAM_LOGW("Invalid user for '%s' gid %d uid %d", userName, gid, uid);
return; return;
} }
ParamAuditData auditData = {0};
char buffer[USER_BUFFER_LEN] = {0}; char buffer[USER_BUFFER_LEN] = {0};
int ret = ParamSprintf(buffer, sizeof(buffer), "%s.%u.%u", GROUP_FORMAT, gid, uid); int ret = ParamSprintf(buffer, sizeof(buffer), GROUP_FORMAT, gid, uid);
PARAM_CHECK(ret >= 0, return, "Failed to format name for %d.%d", gid, uid); PARAM_CHECK(ret >= 0, return, "Failed to format name for %d.%d", gid, uid);
auditData.name = buffer; (void)AddParamEntry(WORKSPACE_INDEX_BASE, PARAM_TYPE_STRING, buffer, "1");
auditData.dacData.uid = uid;
auditData.dacData.gid = gid;
auditData.dacData.mode = INVALID_MODE;
AddSecurityLabel(&auditData);
} }
#ifdef PARAM_DECODE_GROUPID_FROM_FILE #ifdef PARAM_DECODE_GROUPID_FROM_FILE
......
...@@ -27,17 +27,17 @@ ...@@ -27,17 +27,17 @@
#ifdef __aarch64__ #ifdef __aarch64__
#define CHECKER_LIB_NAME "/system/lib64/libparaperm_checker.z.so" #define CHECKER_LIB_NAME "/system/lib64/libparaperm_checker.z.so"
#define CHECKER_UPDATER_LIB_NAME "/lib64/libparaperm_checker.z.so" #define CHECKER_UPDATER_LIB "/lib64/libparaperm_checker.z.so"
#else #else
#define CHECKER_LIB_NAME "/system/lib/libparaperm_checker.z.so" #define CHECKER_LIB_NAME "/system/lib/libparaperm_checker.z.so"
#define CHECKER_UPDATER_LIB_NAME "/lib/libparaperm_checker.z.so" #define CHECKER_UPDATER_LIB "/lib/libparaperm_checker.z.so"
#endif #endif
typedef int (*SelinuxSetParamCheck)(const char *paraName, const char *destContext, const SrcInfo *info); typedef int (*SelinuxSetParamCheck)(const char *paraName, const char *destContext, const SrcInfo *info);
static int InitSelinuxOpsForInit(SelinuxSpace *selinuxSpace) static int InitSelinuxOpsForInit(SelinuxSpace *selinuxSpace)
{ {
if (selinuxSpace->selinuxHandle == NULL) { if (selinuxSpace->selinuxHandle == NULL) {
const char *libname = (GetParamWorkSpace()->ops.updaterMode == 1) ? CHECKER_UPDATER_LIB_NAME : CHECKER_LIB_NAME; const char *libname = (GetParamWorkSpace()->ops.updaterMode == 1) ? CHECKER_UPDATER_LIB : CHECKER_LIB_NAME;
selinuxSpace->selinuxHandle = dlopen(libname, RTLD_LAZY); selinuxSpace->selinuxHandle = dlopen(libname, RTLD_LAZY);
PARAM_CHECK(selinuxSpace->selinuxHandle != NULL, PARAM_CHECK(selinuxSpace->selinuxHandle != NULL,
return 0, "Failed to dlsym selinuxHandle, %s", dlerror()); return 0, "Failed to dlsym selinuxHandle, %s", dlerror());
...@@ -59,8 +59,9 @@ static int InitSelinuxOpsForInit(SelinuxSpace *selinuxSpace) ...@@ -59,8 +59,9 @@ static int InitSelinuxOpsForInit(SelinuxSpace *selinuxSpace)
selinuxSpace->initParamSelinux = (int (*)())dlsym(handle, "InitParamSelinux"); selinuxSpace->initParamSelinux = (int (*)())dlsym(handle, "InitParamSelinux");
PARAM_CHECK(selinuxSpace->initParamSelinux != NULL, return -1, "Failed to dlsym initParamSelinux "); PARAM_CHECK(selinuxSpace->initParamSelinux != NULL, return -1, "Failed to dlsym initParamSelinux ");
} }
if (selinuxSpace->readParamCheck == NULL) { if (selinuxSpace->getParamLabelIndex == NULL) {
selinuxSpace->readParamCheck = (int (*)(const char *))dlsym(handle, "ReadParamCheck"); selinuxSpace->getParamLabelIndex = (int (*)(const char *))dlsym(handle, "GetParamLabelIndex");
PARAM_CHECK(selinuxSpace->getParamLabelIndex != NULL, return -1, "Failed to dlsym getParamLabelIndex ");
} }
if (selinuxSpace->setSelinuxLogCallback == NULL) { if (selinuxSpace->setSelinuxLogCallback == NULL) {
selinuxSpace->setSelinuxLogCallback = (void (*)())dlsym(handle, "SetInitSelinuxLog"); selinuxSpace->setSelinuxLogCallback = (void (*)())dlsym(handle, "SetInitSelinuxLog");
...@@ -100,11 +101,12 @@ static int InitLocalSecurityLabel(ParamSecurityLabel *security, int isInit) ...@@ -100,11 +101,12 @@ static int InitLocalSecurityLabel(ParamSecurityLabel *security, int isInit)
selinuxSpace->getParamList = GetParamList; selinuxSpace->getParamList = GetParamList;
selinuxSpace->getParamLabel = GetParamLabel; selinuxSpace->getParamLabel = GetParamLabel;
selinuxSpace->destroyParamList = DestroyParamList; selinuxSpace->destroyParamList = DestroyParamList;
selinuxSpace->getParamLabelIndex = GetParamLabelIndex;
// init // init
selinuxSpace->initParamSelinux(); selinuxSpace->initParamSelinux();
} }
#endif #endif
PARAM_LOGI("Load selinux lib success."); PARAM_LOGV("Load selinux lib success.");
return 0; return 0;
} }
...@@ -149,7 +151,7 @@ static uint32_t GetWorkSpaceSize(const char *content) ...@@ -149,7 +151,7 @@ static uint32_t GetWorkSpaceSize(const char *content)
return PARAM_WORKSPACE_MIN; return PARAM_WORKSPACE_MIN;
#endif #endif
} }
ParamNode *node = GetParamNode(WORKSPACE_NAME_DAC, name); ParamNode *node = GetParamNode(WORKSPACE_INDEX_BASE, name);
if (node == NULL) { if (node == NULL) {
#ifdef STARTUP_INIT_TEST #ifdef STARTUP_INIT_TEST
return PARAM_WORKSPACE_DEF; return PARAM_WORKSPACE_DEF;
...@@ -167,50 +169,79 @@ static uint32_t GetWorkSpaceSize(const char *content) ...@@ -167,50 +169,79 @@ static uint32_t GetWorkSpaceSize(const char *content)
return PARAM_WORKSPACE_MIN; return PARAM_WORKSPACE_MIN;
} }
static int SelinuxGetAllLabel(int readOnly) static void HandleSelinuxLabelForInit(const ParameterNode *paramNode, int readOnly)
{
uint32_t labelIndex = paramNode->index + WORKSPACE_INDEX_BASE;
int ret = AddWorkSpace(paramNode->paraContext, labelIndex, readOnly, GetWorkSpaceSize(paramNode->paraContext));
if (ret != 0) {
PARAM_LOGE("Forbid to add selinux workspace %s %s", paramNode->paraName, paramNode->paraContext);
return;
}
// set selinux label
SetSelinuxFileCon(paramNode->paraName, paramNode->paraContext);
}
static int SelinuxGetAllLabel(int readOnly,
void (*handleSelinuxLabel)(const ParameterNode *paramNode, int readOnly))
{ {
SelinuxSpace *selinuxSpace = &GetParamWorkSpace()->selinuxSpace; SelinuxSpace *selinuxSpace = &GetParamWorkSpace()->selinuxSpace;
PARAM_CHECK(selinuxSpace->getParamList != NULL, return DAC_RESULT_FORBIDED, "Invalid getParamList"); PARAM_CHECK(selinuxSpace->getParamList != NULL, return DAC_RESULT_FORBIDED, "Invalid getParamList");
ParamContextsList *head = selinuxSpace->getParamList(); ParamContextsList *node = selinuxSpace->getParamList();
ParamContextsList *node = head;
int count = 0; int count = 0;
while (node != NULL) { while (node != NULL) {
PARAM_LOGV("SelinuxGetAllLabel name %s content %s", node->info.paraName, node->info.paraContext); PARAM_LOGV("SelinuxGetAllLabel index %d name %s content %s",
node->info.index, node->info.paraName, node->info.paraContext);
if (node->info.paraContext == NULL || node->info.paraName == NULL) { if (node->info.paraContext == NULL || node->info.paraName == NULL) {
node = node->next; node = node->next;
continue; continue;
} }
int ret = AddWorkSpace(node->info.paraContext, readOnly, GetWorkSpaceSize(node->info.paraContext)); handleSelinuxLabel(&node->info, readOnly);
if (ret != 0) {
PARAM_LOGE("Forbid to add selinux workspace %s %s", node->info.paraName, node->info.paraContext);
node = node->next;
continue;
}
count++; count++;
if (readOnly != 0) {
node = node->next;
continue;
}
// set selinux label
SetSelinuxFileCon(node->info.paraName, node->info.paraContext);
node = node->next; node = node->next;
} }
ParameterNode tmpNode = {WORKSPACE_NAME_DEF_SELINUX, WORKSPACE_NAME_DEF_SELINUX, 0};
int ret = AddWorkSpace(WORKSPACE_NAME_DEF_SELINUX, readOnly, GetWorkSpaceSize(WORKSPACE_NAME_DEF_SELINUX)); handleSelinuxLabel(&tmpNode, readOnly);
PARAM_CHECK(ret == 0, return -1,
"Failed to add selinux workspace %s", WORKSPACE_NAME_DEF_SELINUX);
if (readOnly == 0) {
SetSelinuxFileCon(WORKSPACE_NAME_DEF_SELINUX, WORKSPACE_NAME_DEF_SELINUX);
}
PARAM_LOGV("Selinux get all label counts %d.", count); PARAM_LOGV("Selinux get all label counts %d.", count);
return 0; return 0;
} }
static void HandleSelinuxLabelForPermission(const ParameterNode *paramNode, int readOnly)
{
uint32_t labelIndex = paramNode->index + WORKSPACE_INDEX_BASE;
if (labelIndex == WORKSPACE_INDEX_BASE) {
return;
}
if (*(paramNode->paraName + strlen(paramNode->paraName) - 1) != '.') {
return;
}
// save selinux index
ParamWorkSpace *paramWorkspace = GetParamWorkSpace();
PARAM_CHECK(paramWorkspace != NULL && paramWorkspace->workSpace != NULL, return, "Invalid workspace");
WorkSpace *space = paramWorkspace->workSpace[WORKSPACE_INDEX_DAC];
PARAM_CHECK(space != NULL && space->area != NULL, return, "Failed to get dac space %s", paramNode->paraName);
uint32_t index = 0;
(void)FindTrieNode(space, paramNode->paraName, strlen(paramNode->paraName), &index);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(space, index);
PARAM_CHECK(node != NULL, return, "Can not get security label for %s", paramNode->paraName);
PARAM_LOGV("HandleSelinuxLabelForPermission %s selinuxIndex [ %u %u] dac %u %s ",
paramNode->paraName, labelIndex, node->selinuxIndex, index, paramNode->paraContext);
ParamAuditData auditData = {0};
auditData.dacData.gid = node->gid;
auditData.dacData.uid = node->uid;
auditData.dacData.mode = node->mode;
auditData.dacData.paramType = node->type;
auditData.selinuxIndex = labelIndex;
auditData.name = paramNode->paraName;
AddSecurityLabel(&auditData);
}
static int SelinuxGetParamSecurityLabel(const char *path) static int SelinuxGetParamSecurityLabel(const char *path)
{ {
UNUSED(path); UNUSED(path);
return SelinuxGetAllLabel(0); if (path == NULL) {
return SelinuxGetAllLabel(0, HandleSelinuxLabelForInit);
}
return SelinuxGetAllLabel(0, HandleSelinuxLabelForPermission);
} }
static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char *fileName, int flags) static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char *fileName, int flags)
...@@ -221,75 +252,24 @@ static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char ...@@ -221,75 +252,24 @@ static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char
return 0; return 0;
} }
static const char *GetSelinuxContent(const char *name) static void HandleSelinuxLabel(const ParameterNode *node, int readOnly)
{ {
SelinuxSpace *selinuxSpace = &GetParamWorkSpace()->selinuxSpace; PARAM_LOGV("HandleSelinuxLabel %s %s", node->paraName, node->paraContext);
const char *content = WORKSPACE_NAME_DEF_SELINUX; uint32_t index = node->index + WORKSPACE_INDEX_BASE;
if (selinuxSpace->getParamLabel != NULL) { int ret = AddWorkSpace(node->paraContext, index, readOnly, GetWorkSpaceSize(node->paraContext));
content = selinuxSpace->getParamLabel(name);
}
return content;
}
static int CheckContentPermission(const char *name, const char *label)
{
PARAM_CHECK(name != NULL && label != NULL, return DAC_RESULT_FORBIDED, "The label is null");
int ret = DAC_RESULT_FORBIDED;
char buffer[FILENAME_LEN_MAX] = {0};
int size = ParamSprintf(buffer, sizeof(buffer), "%s/%s", PARAM_STORAGE_PATH, label);
PARAM_CHECK(size > 0, return -1, "Failed to format file name %s", label);
buffer[size] = '\0';
if (access(buffer, R_OK) == 0) {
ret = AddWorkSpace(label, 1, PARAM_WORKSPACE_MAX);
}
if (ret != 0) { if (ret != 0) {
PARAM_LOGE("SelinuxReadParamCheck name %s label %s ", name, label); PARAM_LOGE("Forbid to add selinux workspace %s %s", node->paraName, node->paraContext);
return DAC_RESULT_FORBIDED;
}
return DAC_RESULT_PERMISSION;
}
static int SelinuxReadParamCheck(const char *name)
{
const char *label = GetSelinuxContent(name);
if (label == NULL) {
return CheckContentPermission(name, WORKSPACE_NAME_DEF_SELINUX);
}
return CheckContentPermission(name, label);
}
static int SelinuxCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
{
SelinuxSpace *selinuxSpace = &GetParamWorkSpace()->selinuxSpace;
int ret = DAC_RESULT_FORBIDED;
// check
SrcInfo info;
info.uc.pid = srcLabel->cred.pid;
info.uc.uid = srcLabel->cred.uid;
info.uc.gid = srcLabel->cred.gid;
info.sockFd = srcLabel->sockFd;
if (mode == DAC_WRITE) {
PARAM_CHECK(selinuxSpace->setParamCheck != NULL, return ret, "Invalid setParamCheck");
const char *context = GetSelinuxContent(name);
ret = selinuxSpace->setParamCheck(name, context, &info);
} else {
#ifndef STARTUP_INIT_TEST
ret = SelinuxReadParamCheck(name);
#else
ret = selinuxSpace->readParamCheck(name);
#endif
} }
if (ret != 0) { if (readOnly == 2) { // 2 mean need to open workspace
PARAM_LOGW("Selinux check name %s in %s info [%d %d %d] result %d", ret = OpenWorkSpace(index, 1);
name, GetSelinuxContent(name), info.uc.pid, info.uc.uid, info.uc.gid, ret); if (ret != 0) {
ret = DAC_RESULT_FORBIDED; PARAM_LOGE("Failed to open selinux workspace %s %s index %u", node->paraName, node->paraContext, index);
} else { }
ret = DAC_RESULT_PERMISSION;
} }
return ret;
} }
static int UpdaterCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode) static int UpdaterCheckParamPermission(const ParamLabelIndex *labelIndex,
const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
{ {
return DAC_RESULT_PERMISSION; return DAC_RESULT_PERMISSION;
} }
...@@ -297,13 +277,15 @@ static int UpdaterCheckParamPermission(const ParamSecurityLabel *srcLabel, const ...@@ -297,13 +277,15 @@ static int UpdaterCheckParamPermission(const ParamSecurityLabel *srcLabel, const
static int OpenPermissionWorkSpace(const char *path) static int OpenPermissionWorkSpace(const char *path)
{ {
static int loadLabels = 0; static int loadLabels = 0;
UNUSED(path);
int ret = 0; int ret = 0;
if (loadLabels == 0) { if (path == NULL) {
// open workspace by readonly ret = SelinuxGetAllLabel(1, HandleSelinuxLabel);
ret = SelinuxGetAllLabel(1); } else if (strcmp(path, "open") == 0) {
if (loadLabels == 0) {
ret = SelinuxGetAllLabel(2, HandleSelinuxLabel); // 2 mean need to open workspace
}
loadLabels = 1;
} }
loadLabels = 1;
return ret; return ret;
} }
...@@ -318,7 +300,9 @@ INIT_LOCAL_API int RegisterSecuritySelinuxOps(ParamSecurityOps *ops, int isInit) ...@@ -318,7 +300,9 @@ INIT_LOCAL_API int RegisterSecuritySelinuxOps(ParamSecurityOps *ops, int isInit)
if (GetParamWorkSpace()->ops.updaterMode == 1) { if (GetParamWorkSpace()->ops.updaterMode == 1) {
ops->securityCheckParamPermission = UpdaterCheckParamPermission; ops->securityCheckParamPermission = UpdaterCheckParamPermission;
} else { } else {
#ifdef STARTUP_INIT_TEST
ops->securityCheckParamPermission = SelinuxCheckParamPermission; ops->securityCheckParamPermission = SelinuxCheckParamPermission;
#endif
} }
ops->securityFreeLabel = FreeLocalSecurityLabel; ops->securityFreeLabel = FreeLocalSecurityLabel;
if (isInit != 0) { if (isInit != 0) {
......
...@@ -115,6 +115,10 @@ if (defined(ohos_lite)) { ...@@ -115,6 +115,10 @@ if (defined(ohos_lite)) {
if (use_musl) { if (use_musl) {
defines += [ "__MUSL__" ] defines += [ "__MUSL__" ]
} }
if (startup_init_test_performance) {
defines += [ "PARAM_TEST_PERFORMANCE" ]
}
if (!startup_init_with_param_base) { if (!startup_init_with_param_base) {
ldflags = [ "-nostdlib" ] ldflags = [ "-nostdlib" ]
configs -= inherited_configs configs -= inherited_configs
......
此差异已折叠。
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#ifndef BASE_STARTUP_PARAM_BASE_H #ifndef BASE_STARTUP_PARAM_BASE_H
#define BASE_STARTUP_PARAM_BASE_H #define BASE_STARTUP_PARAM_BASE_H
#include "sys_param.h" #include "sys_param.h"
#include "param_osadp.h"
#include "beget_ext.h" #include "beget_ext.h"
#ifndef PARAM_BASE #ifndef PARAM_BASE
#include "securec.h" #include "securec.h"
...@@ -32,6 +33,19 @@ INIT_LOCAL_API int ParamSprintf(char *buffer, size_t buffSize, const char *forma ...@@ -32,6 +33,19 @@ INIT_LOCAL_API int ParamSprintf(char *buffer, size_t buffSize, const char *forma
INIT_LOCAL_API int ParamMemcpy(void *dest, size_t destMax, const void *src, size_t count); INIT_LOCAL_API int ParamMemcpy(void *dest, size_t destMax, const void *src, size_t count);
INIT_LOCAL_API int ParamStrCpy(char *strDest, size_t destMax, const char *strSrc); INIT_LOCAL_API int ParamStrCpy(char *strDest, size_t destMax, const char *strSrc);
typedef struct CachedParameter_ {
struct WorkSpace_ *workspace;
long long spaceCommitId;
uint32_t dataCommitId;
uint32_t dataIndex;
uint32_t bufferLen;
uint32_t nameLen;
char *paramValue;
char data[0];
} CachedParameter;
#ifdef PARAM_TEST_PERFORMANCE
void TestParameterReaderPerformance(void);
#endif
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
此差异已折叠。
/*
* Copyright (c) 2022 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 BASE_STARTUP_PARAM_INCLUDE_H
#define BASE_STARTUP_PARAM_INCLUDE_H
#include <stdio.h>
#include "param_osadp.h"
#include "param_trie.h"
#ifdef __cplusplus
#if __cplusplus
extern "C" {
#endif
#endif
STATIC_INLINE void GetNextKey(const char **remainingKey, char **subKey, uint32_t *subKeyLen, const char *end)
{
*subKey = strchr(*remainingKey, '.');
if (*subKey != NULL) {
*subKeyLen = *subKey - *remainingKey;
} else {
*subKeyLen = end - *remainingKey;
}
}
STATIC_INLINE ParamTrieNode *FindSubTrie(const WorkSpace *workSpace,
ParamTrieNode *current, const char *key, uint32_t keyLen, uint32_t *matchLabel)
{
ParamTrieNode *subTrie = current;
int ret = 0;
while (subTrie != NULL) {
if (subTrie->length > keyLen) {
ret = -1;
} else if (subTrie->length < keyLen) {
ret = 1;
} else {
ret = memcmp(subTrie->key, key, keyLen);
if (ret == 0) {
*matchLabel = (subTrie->labelIndex != 0) ? subTrie->labelIndex : *matchLabel;
return subTrie;
}
}
uint32_t offset = 0;
if (ret < 0) {
offset = subTrie->left;
} else {
offset = subTrie->right;
}
if (offset == 0 || offset > workSpace->area->dataSize) {
return NULL;
}
subTrie = (ParamTrieNode *)(workSpace->area->data + offset);
}
return NULL;
}
STATIC_INLINE ParamTrieNode *FindTrieNode_(
const WorkSpace *workSpace, const char *key, uint32_t keyLen, uint32_t *matchLabel)
{
const char *remainingKey = key;
ParamTrieNode *current = GetTrieRoot(workSpace);
PARAM_CHECK(current != NULL, return NULL, "Invalid current param %s", key);
*matchLabel = current->labelIndex;
const char *end = key + keyLen;
while (1) {
uint32_t subKeyLen = 0;
char *subKey = NULL;
GetNextKey(&remainingKey, &subKey, &subKeyLen, end);
if (!subKeyLen) {
return NULL;
}
if (current->child != 0) {
ParamTrieNode *next = GetTrieNode(workSpace, current->child);
current = FindSubTrie(workSpace, next, remainingKey, subKeyLen, matchLabel);
} else {
current = FindSubTrie(workSpace, current, remainingKey, subKeyLen, matchLabel);
}
if (current == NULL) {
return NULL;
} else if (current->labelIndex != 0) {
*matchLabel = current->labelIndex;
}
if (subKey == NULL || strcmp(subKey, ".") == 0) {
break;
}
remainingKey = subKey + 1;
}
return current;
}
#ifdef __cplusplus
#if __cplusplus
}
#endif
#endif
#endif // BASE_STARTUP_PARAM_INCLUDE_H
\ No newline at end of file
/* /*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -22,6 +22,8 @@ ...@@ -22,6 +22,8 @@
#include "param_manager.h" #include "param_manager.h"
#include "param_osadp.h" #include "param_osadp.h"
#include "param_utils.h" #include "param_utils.h"
#include "param_include.h"
static uint32_t AllocateParamTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLen);
static int GetRealFileName(WorkSpace *workSpace, char *buffer, uint32_t size) static int GetRealFileName(WorkSpace *workSpace, char *buffer, uint32_t size)
{ {
...@@ -33,14 +35,9 @@ static int GetRealFileName(WorkSpace *workSpace, char *buffer, uint32_t size) ...@@ -33,14 +35,9 @@ static int GetRealFileName(WorkSpace *workSpace, char *buffer, uint32_t size)
static int InitWorkSpace_(WorkSpace *workSpace, uint32_t spaceSize, int readOnly) static int InitWorkSpace_(WorkSpace *workSpace, uint32_t spaceSize, int readOnly)
{ {
static uint32_t startIndex = 0;
PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid workSpace"); PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid workSpace");
PARAM_CHECK(sizeof(ParamTrieHeader) < spaceSize, PARAM_CHECK(sizeof(ParamTrieHeader) < spaceSize,
return PARAM_CODE_INVALID_PARAM, "Invalid spaceSize %u", spaceSize); return PARAM_CODE_INVALID_PARAM, "Invalid spaceSize %u", spaceSize);
PARAM_CHECK(workSpace->allocTrieNode != NULL,
return PARAM_CODE_INVALID_PARAM, "Invalid allocTrieNode %s", workSpace->fileName);
PARAM_CHECK(workSpace->compareTrieNode != NULL,
return PARAM_CODE_INVALID_PARAM, "Invalid compareTrieNode %s", workSpace->fileName);
char buffer[FILENAME_LEN_MAX] = {0}; char buffer[FILENAME_LEN_MAX] = {0};
int ret = GetRealFileName(workSpace, buffer, sizeof(buffer)); int ret = GetRealFileName(workSpace, buffer, sizeof(buffer));
...@@ -54,11 +51,9 @@ static int InitWorkSpace_(WorkSpace *workSpace, uint32_t spaceSize, int readOnly ...@@ -54,11 +51,9 @@ static int InitWorkSpace_(WorkSpace *workSpace, uint32_t spaceSize, int readOnly
workSpace->area->trieNodeCount = 0; workSpace->area->trieNodeCount = 0;
workSpace->area->paramNodeCount = 0; workSpace->area->paramNodeCount = 0;
workSpace->area->securityNodeCount = 0; workSpace->area->securityNodeCount = 0;
workSpace->area->startIndex = startIndex;
startIndex += spaceSize;
workSpace->area->dataSize = spaceSize - sizeof(ParamTrieHeader); workSpace->area->dataSize = spaceSize - sizeof(ParamTrieHeader);
workSpace->area->currOffset = 0; workSpace->area->currOffset = 0;
uint32_t offset = workSpace->allocTrieNode(workSpace, "#", 1); uint32_t offset = AllocateParamTrieNode(workSpace, "#", 1);
workSpace->area->firstNode = offset; workSpace->area->firstNode = offset;
} else { } else {
workSpace->area = (ParamTrieHeader *)areaAddr; workSpace->area = (ParamTrieHeader *)areaAddr;
...@@ -73,7 +68,8 @@ static uint32_t AllocateParamTrieNode(WorkSpace *workSpace, const char *key, uin ...@@ -73,7 +68,8 @@ static uint32_t AllocateParamTrieNode(WorkSpace *workSpace, const char *key, uin
uint32_t len = keyLen + sizeof(ParamTrieNode) + 1; uint32_t len = keyLen + sizeof(ParamTrieNode) + 1;
len = PARAM_ALIGN(len); len = PARAM_ALIGN(len);
PARAM_CHECK((workSpace->area->currOffset + len) < workSpace->area->dataSize, return 0, PARAM_CHECK((workSpace->area->currOffset + len) < workSpace->area->dataSize, return 0,
"Failed to allocate currOffset %d, dataSize %d", workSpace->area->currOffset, workSpace->area->dataSize); "Failed to allocate currOffset %d, dataSize %d space %s",
workSpace->area->currOffset, workSpace->area->dataSize, workSpace->fileName);
ParamTrieNode *node = (ParamTrieNode *)(workSpace->area->data + workSpace->area->currOffset); ParamTrieNode *node = (ParamTrieNode *)(workSpace->area->data + workSpace->area->currOffset);
node->length = keyLen; node->length = keyLen;
int ret = ParamMemcpy(node->key, keyLen, key, keyLen); int ret = ParamMemcpy(node->key, keyLen, key, keyLen);
...@@ -90,28 +86,14 @@ static uint32_t AllocateParamTrieNode(WorkSpace *workSpace, const char *key, uin ...@@ -90,28 +86,14 @@ static uint32_t AllocateParamTrieNode(WorkSpace *workSpace, const char *key, uin
return offset; return offset;
} }
static int CompareParamTrieNode(const ParamTrieNode *node, const char *key, uint32_t keyLen)
{
if (node->length > keyLen) {
return -1;
} else if (node->length < keyLen) {
return 1;
}
return strncmp(node->key, key, keyLen);
}
INIT_LOCAL_API int InitWorkSpace(WorkSpace *workSpace, int onlyRead, uint32_t spaceSize) INIT_LOCAL_API int InitWorkSpace(WorkSpace *workSpace, int onlyRead, uint32_t spaceSize)
{ {
PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_NAME, "Invalid workSpace"); PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_NAME, "Invalid workSpace");
if (PARAM_TEST_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT)) { if (PARAM_TEST_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT)) {
return 0; return 0;
} }
workSpace->compareTrieNode = CompareParamTrieNode;
workSpace->allocTrieNode = AllocateParamTrieNode;
workSpace->area = NULL;
int ret = InitWorkSpace_(workSpace, spaceSize, onlyRead); int ret = InitWorkSpace_(workSpace, spaceSize, onlyRead);
PARAM_ONLY_CHECK(ret == 0, return ret); PARAM_ONLY_CHECK(ret == 0, return ret);
PARAMSPACE_AREA_INIT_LOCK(workSpace);
PARAM_SET_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT); PARAM_SET_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT);
PARAM_LOGV("InitWorkSpace %s for %s", workSpace->fileName, (onlyRead == 0) ? "init" : "other"); PARAM_LOGV("InitWorkSpace %s for %s", workSpace->fileName, (onlyRead == 0) ? "init" : "other");
return ret; return ret;
...@@ -122,17 +104,14 @@ INIT_LOCAL_API void CloseWorkSpace(WorkSpace *workSpace) ...@@ -122,17 +104,14 @@ INIT_LOCAL_API void CloseWorkSpace(WorkSpace *workSpace)
PARAM_CHECK(workSpace != NULL, return, "The workspace is null"); PARAM_CHECK(workSpace != NULL, return, "The workspace is null");
PARAM_LOGV("CloseWorkSpace %s", workSpace->fileName); PARAM_LOGV("CloseWorkSpace %s", workSpace->fileName);
if (!PARAM_TEST_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT)) { if (!PARAM_TEST_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT)) {
free(workSpace);
return; return;
} }
OH_ListRemove(&workSpace->node);
PARAM_CHECK(workSpace->area != NULL, return, "The workspace area is null"); PARAM_CHECK(workSpace->area != NULL, return, "The workspace area is null");
#ifdef WORKSPACE_AREA_NEED_MUTEX #ifdef WORKSPACE_AREA_NEED_MUTEX
ParamRWMutexDelete(&workSpace->rwlock); ParamRWMutexDelete(&workSpace->rwlock);
#endif #endif
FreeSharedMem(&workSpace->memHandle, workSpace->area, workSpace->area->dataSize); FreeSharedMem(&workSpace->memHandle, workSpace->area, workSpace->area->dataSize);
workSpace->area = NULL; workSpace->area = NULL;
free(workSpace);
} }
static int CheckWorkSpace(const WorkSpace *workSpace) static int CheckWorkSpace(const WorkSpace *workSpace)
...@@ -141,24 +120,17 @@ static int CheckWorkSpace(const WorkSpace *workSpace) ...@@ -141,24 +120,17 @@ static int CheckWorkSpace(const WorkSpace *workSpace)
if (!PARAM_TEST_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT)) { if (!PARAM_TEST_FLAG(workSpace->flags, WORKSPACE_FLAGS_INIT)) {
return -1; return -1;
} }
PARAM_CHECK(workSpace->allocTrieNode != NULL, return -1, "Invalid allocTrieNode");
PARAM_CHECK(workSpace->compareTrieNode != NULL, return -1, "Invalid compareTrieNode");
return 0; return 0;
} }
static ParamTrieNode *GetTrieRoot(const WorkSpace *workSpace) static int CompareParamTrieNode(const ParamTrieNode *node, const char *key, uint32_t keyLen)
{
return (ParamTrieNode *)(workSpace->area->data + workSpace->area->firstNode);
}
static void GetNextKey(const char **remainingKey, char **subKey, uint32_t *subKeyLen)
{ {
*subKey = strchr(*remainingKey, '.'); if (node->length > keyLen) {
if (*subKey != NULL) { return -1;
*subKeyLen = *subKey - *remainingKey; } else if (node->length < keyLen) {
} else { return 1;
*subKeyLen = strlen(*remainingKey);
} }
return memcmp(node->key, key, keyLen);
} }
static ParamTrieNode *AddToSubTrie(WorkSpace *workSpace, ParamTrieNode *current, const char *key, uint32_t keyLen) static ParamTrieNode *AddToSubTrie(WorkSpace *workSpace, ParamTrieNode *current, const char *key, uint32_t keyLen)
...@@ -167,14 +139,14 @@ static ParamTrieNode *AddToSubTrie(WorkSpace *workSpace, ParamTrieNode *current, ...@@ -167,14 +139,14 @@ static ParamTrieNode *AddToSubTrie(WorkSpace *workSpace, ParamTrieNode *current,
return NULL; return NULL;
} }
ParamTrieNode *subTrie = NULL; ParamTrieNode *subTrie = NULL;
int ret = workSpace->compareTrieNode(current, key, keyLen); int ret = CompareParamTrieNode(current, key, keyLen);
if (ret == 0) { if (ret == 0) {
return current; return current;
} }
if (ret < 0) { if (ret < 0) {
subTrie = GetTrieNode(workSpace, current->left); subTrie = GetTrieNode(workSpace, current->left);
if (subTrie == NULL) { if (subTrie == NULL) {
uint32_t offset = workSpace->allocTrieNode(workSpace, key, keyLen); uint32_t offset = AllocateParamTrieNode(workSpace, key, keyLen);
PARAM_CHECK(offset != 0, return NULL, PARAM_CHECK(offset != 0, return NULL,
"Failed to allocate key '%s' in space '%s'", key, workSpace->fileName); "Failed to allocate key '%s' in space '%s'", key, workSpace->fileName);
SaveIndex(&current->left, offset); SaveIndex(&current->left, offset);
...@@ -183,7 +155,7 @@ static ParamTrieNode *AddToSubTrie(WorkSpace *workSpace, ParamTrieNode *current, ...@@ -183,7 +155,7 @@ static ParamTrieNode *AddToSubTrie(WorkSpace *workSpace, ParamTrieNode *current,
} else { } else {
subTrie = GetTrieNode(workSpace, current->right); subTrie = GetTrieNode(workSpace, current->right);
if (subTrie == NULL) { if (subTrie == NULL) {
uint32_t offset = workSpace->allocTrieNode(workSpace, key, keyLen); uint32_t offset = AllocateParamTrieNode(workSpace, key, keyLen);
PARAM_CHECK(offset != 0, return NULL, PARAM_CHECK(offset != 0, return NULL,
"Failed to allocate key '%s' in space '%s'", key, workSpace->fileName); "Failed to allocate key '%s' in space '%s'", key, workSpace->fileName);
SaveIndex(&current->right, offset); SaveIndex(&current->right, offset);
...@@ -203,7 +175,7 @@ ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLe ...@@ -203,7 +175,7 @@ ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLe
while (1) { while (1) {
uint32_t subKeyLen = 0; uint32_t subKeyLen = 0;
char *subKey = NULL; char *subKey = NULL;
GetNextKey(&remainingKey, &subKey, &subKeyLen); GetNextKey(&remainingKey, &subKey, &subKeyLen, key + keyLen);
if (!subKeyLen) { if (!subKeyLen) {
return NULL; return NULL;
} }
...@@ -211,7 +183,7 @@ ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLe ...@@ -211,7 +183,7 @@ ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLe
ParamTrieNode *next = GetTrieNode(workSpace, current->child); ParamTrieNode *next = GetTrieNode(workSpace, current->child);
current = AddToSubTrie(workSpace, next, remainingKey, subKeyLen); current = AddToSubTrie(workSpace, next, remainingKey, subKeyLen);
} else { } else {
uint32_t dataOffset = workSpace->allocTrieNode(workSpace, remainingKey, subKeyLen); uint32_t dataOffset = AllocateParamTrieNode(workSpace, remainingKey, subKeyLen);
PARAM_CHECK(dataOffset != 0, return NULL, PARAM_CHECK(dataOffset != 0, return NULL,
"Failed to allocate key '%s' in space '%s'", key, workSpace->fileName); "Failed to allocate key '%s' in space '%s'", key, workSpace->fileName);
SaveIndex(&current->child, dataOffset); SaveIndex(&current->child, dataOffset);
...@@ -228,72 +200,6 @@ ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLe ...@@ -228,72 +200,6 @@ ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLe
return current; return current;
} }
static ParamTrieNode *FindSubTrie(const WorkSpace *workSpace,
ParamTrieNode *current, const char *key, uint32_t keyLen, uint32_t *matchLabel)
{
if (current == NULL) {
return NULL;
}
ParamTrieNode *subTrie = NULL;
int ret = workSpace->compareTrieNode(current, key, keyLen);
if (ret == 0) {
if (matchLabel != NULL && current->labelIndex != 0) {
*matchLabel = current->labelIndex;
}
return current;
}
if (ret < 0) {
subTrie = (ParamTrieNode *)GetTrieNode(workSpace, current->left);
if (subTrie == NULL) {
return NULL;
}
} else {
subTrie = (ParamTrieNode *)GetTrieNode(workSpace, current->right);
if (subTrie == NULL) {
return NULL;
}
}
return FindSubTrie(workSpace, subTrie, key, keyLen, matchLabel);
}
static ParamTrieNode *FindTrieNode_(const WorkSpace *workSpace, const char *key, uint32_t keyLen, uint32_t *matchLabel)
{
const char *remainingKey = key;
ParamTrieNode *current = GetTrieRoot(workSpace);
PARAM_CHECK(current != NULL, return NULL, "Invalid current param %s", key);
if (matchLabel != NULL) {
*matchLabel = current->labelIndex;
}
int ret = workSpace->compareTrieNode(current, key, keyLen);
if (ret == 0) {
return current;
}
while (1) {
uint32_t subKeyLen = 0;
char *subKey = NULL;
GetNextKey(&remainingKey, &subKey, &subKeyLen);
if (!subKeyLen) {
return NULL;
}
if (current->child != 0) {
ParamTrieNode *next = GetTrieNode(workSpace, current->child);
current = FindSubTrie(workSpace, next, remainingKey, subKeyLen, matchLabel);
} else {
current = FindSubTrie(workSpace, current, remainingKey, subKeyLen, matchLabel);
}
if (current == NULL) {
return NULL;
} else if (matchLabel != NULL && current->labelIndex != 0) {
*matchLabel = current->labelIndex;
}
if (subKey == NULL || strcmp(subKey, ".") == 0) {
break;
}
remainingKey = subKey + 1;
}
return current;
}
static int TraversalSubTrieNode(const WorkSpace *workSpace, static int TraversalSubTrieNode(const WorkSpace *workSpace,
const ParamTrieNode *current, TraversalTrieNodePtr walkFunc, const void *cookie) const ParamTrieNode *current, TraversalTrieNodePtr walkFunc, const void *cookie)
{ {
...@@ -340,6 +246,11 @@ INIT_LOCAL_API uint32_t AddParamSecurityNode(WorkSpace *workSpace, const ParamAu ...@@ -340,6 +246,11 @@ INIT_LOCAL_API uint32_t AddParamSecurityNode(WorkSpace *workSpace, const ParamAu
node->gid = auditData->dacData.gid; node->gid = auditData->dacData.gid;
node->mode = auditData->dacData.mode; node->mode = auditData->dacData.mode;
node->type = auditData->dacData.paramType & PARAM_TYPE_MASK; node->type = auditData->dacData.paramType & PARAM_TYPE_MASK;
#ifdef PARAM_SUPPORT_SELINUX
node->selinuxIndex = auditData->selinuxIndex;
#else
node->selinuxIndex = 0;
#endif
uint32_t offset = workSpace->area->currOffset; uint32_t offset = workSpace->area->currOffset;
workSpace->area->currOffset += realLen; workSpace->area->currOffset += realLen;
workSpace->area->securityNodeCount++; workSpace->area->securityNodeCount++;
...@@ -378,31 +289,24 @@ INIT_LOCAL_API uint32_t AddParamNode(WorkSpace *workSpace, uint8_t type, ...@@ -378,31 +289,24 @@ INIT_LOCAL_API uint32_t AddParamNode(WorkSpace *workSpace, uint8_t type,
return offset; return offset;
} }
INIT_LOCAL_API ParamTrieNode *GetTrieNode(const WorkSpace *workSpace, uint32_t offset)
{
PARAM_CHECK(CheckWorkSpace(workSpace) == 0, return NULL, "Invalid workSpace");
if (offset == 0 || offset > workSpace->area->dataSize) {
return NULL;
}
return (ParamTrieNode *)(workSpace->area->data + offset);
}
INIT_LOCAL_API void SaveIndex(uint32_t *index, uint32_t offset) INIT_LOCAL_API void SaveIndex(uint32_t *index, uint32_t offset)
{ {
PARAM_CHECK(index != NULL, return, "Invalid index");
*index = offset; *index = offset;
} }
INIT_LOCAL_API ParamTrieNode *FindTrieNode(WorkSpace *workSpace, INIT_LOCAL_API ParamTrieNode *FindTrieNode(WorkSpace *workSpace,
const char *key, uint32_t keyLen, uint32_t *matchLabel) const char *key, uint32_t keyLen, uint32_t *matchLabel)
{ {
PARAM_CHECK(key != NULL && keyLen > 0, return NULL, "Invalid key "); PARAM_ONLY_CHECK(key != NULL && keyLen > 0, return NULL);
PARAM_CHECK(CheckWorkSpace(workSpace) == 0, return NULL, "Invalid workSpace %s", key);
uint32_t tmpMatchLen = 0;
ParamTrieNode *node = NULL; ParamTrieNode *node = NULL;
PARAMSPACE_AREA_RD_LOCK(workSpace); PARAMSPACE_AREA_RD_LOCK(workSpace);
node = FindTrieNode_(workSpace, key, keyLen, matchLabel); node = FindTrieNode_(workSpace, key, keyLen, &tmpMatchLen);
PARAMSPACE_AREA_RW_UNLOCK(workSpace); PARAMSPACE_AREA_RW_UNLOCK(workSpace);
if (matchLabel != NULL) {
*matchLabel = tmpMatchLen;
}
if (node != NULL && node->dataIndex != 0) { if (node != NULL && node->dataIndex != 0) {
ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, node->dataIndex); ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, node->dataIndex);
if (entry != NULL && entry->keyLength == keyLen) { if (entry != NULL && entry->keyLength == keyLen) {
...@@ -424,13 +328,69 @@ INIT_LOCAL_API uint32_t GetParamMaxLen(uint8_t type) ...@@ -424,13 +328,69 @@ INIT_LOCAL_API uint32_t GetParamMaxLen(uint8_t type)
return typeLengths[type]; return typeLengths[type];
} }
INIT_LOCAL_API ParamNode *GetParamNode(const char *spaceName, const char *name) INIT_LOCAL_API ParamNode *GetParamNode(uint32_t index, const char *name)
{ {
uint32_t labelIndex = 0; uint32_t labelIndex = 0;
WorkSpace *space = GetWorkSpace(spaceName); WorkSpace *space = GetWorkSpace(index);
ParamTrieNode *entry = FindTrieNode(space, name, strlen(name), &labelIndex); ParamTrieNode *entry = FindTrieNode(space, name, strlen(name), &labelIndex);
if (entry == NULL || entry->dataIndex == 0) { if (entry == NULL || entry->dataIndex == 0) {
return NULL; return NULL;
} }
return (ParamNode *)GetTrieNode(space, entry->dataIndex); return (ParamNode *)GetTrieNode(space, entry->dataIndex);
}
INIT_LOCAL_API int AddParamEntry(uint32_t index, uint8_t type, const char *name, const char *value)
{
WorkSpace *workSpace = GetWorkSpace(WORKSPACE_INDEX_BASE);
ParamTrieNode *node = AddTrieNode(workSpace, name, strlen(name));
PARAM_CHECK(node != NULL, return PARAM_CODE_REACHED_MAX, "Failed to add node");
ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, node->dataIndex);
if (entry == NULL) {
uint32_t offset = AddParamNode(workSpace, type, name, strlen(name), value, strlen(value));
PARAM_CHECK(offset > 0, return PARAM_CODE_REACHED_MAX, "Failed to allocate name %s", name);
SaveIndex(&node->dataIndex, offset);
}
return 0;
}
INIT_LOCAL_API int AddSecurityLabel(const ParamAuditData *auditData)
{
PARAM_CHECK(auditData != NULL && auditData->name != NULL, return -1, "Invalid auditData");
WorkSpace *workSpace = GetWorkSpace(WORKSPACE_INDEX_DAC);
PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid workSpace");
ParamTrieNode *node = GetTrieRoot(workSpace);
if ((node == NULL) || (CompareParamTrieNode(node, auditData->name, strlen(auditData->name)) != 0)) {
node = FindTrieNode(workSpace, auditData->name, strlen(auditData->name), NULL);
if (node == NULL) {
node = AddTrieNode(workSpace, auditData->name, strlen(auditData->name));
}
PARAM_CHECK(node != NULL, return PARAM_CODE_REACHED_MAX, "Failed to add node %s", auditData->name);
}
uint32_t offset = node->labelIndex;
if (node->labelIndex == 0) { // can not support update for label
offset = AddParamSecurityNode(workSpace, auditData);
PARAM_CHECK(offset != 0, return PARAM_CODE_REACHED_MAX, "Failed to add label");
SaveIndex(&node->labelIndex, offset);
} else {
ParamSecurityNode *label = (ParamSecurityNode *)GetTrieNode(workSpace, node->labelIndex);
PARAM_CHECK(label != NULL, return -1, "Failed to get trie node");
#ifdef PARAM_SUPPORT_SELINUX
if (auditData->selinuxIndex != 0) {
label->selinuxIndex = auditData->selinuxIndex;
} else
#endif
{
#ifdef STARTUP_INIT_TEST
label->mode = auditData->dacData.mode;
label->uid = auditData->dacData.uid;
label->gid = auditData->dacData.gid;
label->type = auditData->dacData.paramType & PARAM_TYPE_MASK;
#endif
PARAM_LOGV("Repeat to add label for name %s", auditData->name);
}
}
PARAM_LOGV("AddSecurityLabel label %d gid %d uid %d mode %o type:%d name: %s", offset,
auditData->dacData.gid, auditData->dacData.uid, auditData->dacData.mode,
auditData->dacData.paramType, auditData->name);
return 0;
} }
\ No newline at end of file
...@@ -34,6 +34,16 @@ extern "C" { ...@@ -34,6 +34,16 @@ extern "C" {
#endif #endif
#endif #endif
#define PARAM_MAX_SELINUX_LABEL 256
#ifdef PARAM_SUPPORT_SELINUX
#define PARAM_DEF_SELINUX_LABEL 64
#else
#define PARAM_DEF_SELINUX_LABEL 1
#endif
#define WORKSPACE_INDEX_DAC 0
#define WORKSPACE_INDEX_BASE 1
#define WORKSPACE_NAME_DAC "param_sec_dac" #define WORKSPACE_NAME_DAC "param_sec_dac"
#define WORKSPACE_NAME_DEF_SELINUX "u:object_r:default_param:s0" #define WORKSPACE_NAME_DEF_SELINUX "u:object_r:default_param:s0"
#ifndef PARAM_SUPPORT_SELINUX #ifndef PARAM_SUPPORT_SELINUX
...@@ -55,15 +65,14 @@ typedef struct { ...@@ -55,15 +65,14 @@ typedef struct {
uint32_t flags; uint32_t flags;
ParamSecurityLabel securityLabel; ParamSecurityLabel securityLabel;
ParamSecurityOps paramSecurityOps[PARAM_SECURITY_MAX]; ParamSecurityOps paramSecurityOps[PARAM_SECURITY_MAX];
HashMapHandle workSpaceHashHandle;
ListHead workSpaceList;
#ifdef PARAMWORKSPACE_NEED_MUTEX
ParamRWMutex rwlock;
#endif
PARAM_WORKSPACE_OPS ops; PARAM_WORKSPACE_OPS ops;
#ifdef PARAM_SUPPORT_SELINUX #ifdef PARAM_SUPPORT_SELINUX
SelinuxSpace selinuxSpace; SelinuxSpace selinuxSpace;
#endif #endif
int (*checkParamPermission)(const ParamLabelIndex *labelIndex,
const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode);
uint32_t maxLabelIndex;
WorkSpace **workSpace;
} ParamWorkSpace; } ParamWorkSpace;
typedef struct { typedef struct {
...@@ -94,12 +103,23 @@ typedef struct { ...@@ -94,12 +103,23 @@ typedef struct {
char *prefix; char *prefix;
} ParamTraversalContext; } ParamTraversalContext;
INIT_LOCAL_API int AddWorkSpace(const char *name, int onlyRead, uint32_t spacesize); #define PARAM_HANDLE(workSpace, index) (ParamHandle)((workSpace)->spaceIndex << 24 | (index))
INIT_LOCAL_API WorkSpace *GetFirstWorkSpace(void); #define PARAM_GET_HANDLE_INFO(handle, label, index) \
do { \
(label) = (((handle) >> 24) & 0x000000ff); \
(index) = (handle) & 0x00ffffff; \
if (((index) & 0x03) != 0) { \
(index) = 0; \
} \
} while (0)
INIT_LOCAL_API int AddWorkSpace(const char *name, uint32_t labelIndex, int onlyRead, uint32_t spacesize);
INIT_LOCAL_API int OpenWorkSpace(uint32_t index, int readOnly);
INIT_LOCAL_API WorkSpace *GetNextWorkSpace(WorkSpace *curr); INIT_LOCAL_API WorkSpace *GetNextWorkSpace(WorkSpace *curr);
INIT_LOCAL_API WorkSpace *GetWorkSpace(const char *name); INIT_LOCAL_API WorkSpace *GetWorkSpace(uint32_t labelIndex);
INIT_LOCAL_API ParamTrieNode *GetTrieNodeByHandle(ParamHandle handle); INIT_LOCAL_API uint32_t GetWorkSpaceIndex(const char *name);
INIT_LOCAL_API int ReadParamWithCheck(const char *name, uint32_t op, ParamHandle *handle);
INIT_LOCAL_API int CheckParamValue(const ParamTrieNode *node, const char *name, const char *value, uint8_t paramType); INIT_LOCAL_API int CheckParamValue(const ParamTrieNode *node, const char *name, const char *value, uint8_t paramType);
INIT_LOCAL_API int CheckParamName(const char *name, int paramInfo); INIT_LOCAL_API int CheckParamName(const char *name, int paramInfo);
INIT_LOCAL_API uint8_t GetParamValueType(const char *name); INIT_LOCAL_API uint8_t GetParamValueType(const char *name);
...@@ -116,12 +136,9 @@ INIT_LOCAL_API int InitPersistParamWorkSpace(void); ...@@ -116,12 +136,9 @@ INIT_LOCAL_API int InitPersistParamWorkSpace(void);
INIT_LOCAL_API void ClosePersistParamWorkSpace(void); INIT_LOCAL_API void ClosePersistParamWorkSpace(void);
INIT_LOCAL_API int WritePersistParam(const char *name, const char *value); INIT_LOCAL_API int WritePersistParam(const char *name, const char *value);
INIT_LOCAL_API uint32_t ReadCommitId(ParamNode *entry);
INIT_LOCAL_API int ReadParamName(ParamHandle handle, char *name, uint32_t length);
INIT_LOCAL_API int ReadParamValue(ParamHandle handle, char *value, uint32_t *length);
INIT_LOCAL_API int CheckParameterSet(const char *name, const char *value, INIT_LOCAL_API int CheckParameterSet(const char *name, const char *value,
const ParamSecurityLabel *srcLabel, int *ctrlService); const ParamSecurityLabel *srcLabel, int *ctrlService);
INIT_LOCAL_API ParamHandle GetParamHandle(const WorkSpace *workSpace, uint32_t index, const char *name);
INIT_LOCAL_API int CheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode); INIT_LOCAL_API int CheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode);
INIT_LOCAL_API int SysCheckParamExist(const char *name); INIT_LOCAL_API int SysCheckParamExist(const char *name);
......
...@@ -44,6 +44,12 @@ extern "C" { ...@@ -44,6 +44,12 @@ extern "C" {
#endif #endif
#endif #endif
#ifdef STARTUP_INIT_TEST
#define STATIC_INLINE
#else
#define STATIC_INLINE static __attribute__((always_inline))
#endif
#define PARAM_WORKSPACE_INVALID ((uint32_t)-1) #define PARAM_WORKSPACE_INVALID ((uint32_t)-1)
#define PARAM_WORKSPACE_MIN (1024) #define PARAM_WORKSPACE_MIN (1024)
/* /*
...@@ -54,32 +60,38 @@ extern "C" { ...@@ -54,32 +60,38 @@ extern "C" {
data size data size
strlen(xxxx.xxxx.xxxx.xxxx) + 96 strlen(xxxx.xxxx.xxxx.xxxx) + 96
*/ */
#if (defined __LITEOS_A__ || defined __LITEOS_M__) #define DAC_DEFAULT_GROUP 0
#define DAC_DEFAULT_MODE 0777 #define DAC_DEFAULT_USER 0
#ifdef STARTUP_INIT_TEST #ifdef STARTUP_INIT_TEST
#define PARAM_WORKSPACE_MAX (1024 * 50) #define DAC_DEFAULT_MODE 0777
#define PARAM_WORKSPACE_DEF (1024 * 80)
#define PARAM_WORKSPACE_MAX (1024 * 80)
#define PARAM_WORKSPACE_SMALL PARAM_WORKSPACE_DEF
#else #else
#ifdef __LITEOS_M__
#define DAC_DEFAULT_MODE 0777
#ifndef PARAM_WORKSPACE_MAX #ifndef PARAM_WORKSPACE_MAX
#define PARAM_WORKSPACE_MAX (1024 * 5) #define PARAM_WORKSPACE_MAX (1024 * 5)
#endif #endif
#endif
#define PARAM_WORKSPACE_SMALL PARAM_WORKSPACE_MAX #define PARAM_WORKSPACE_SMALL PARAM_WORKSPACE_MAX
#define PARAM_WORKSPACE_DEF PARAM_WORKSPACE_MAX #define PARAM_WORKSPACE_DEF PARAM_WORKSPACE_MAX
#define DAC_DEFAULT_GROUP 0 #else // __LITEOS_M__
#define DAC_DEFAULT_USER 0
#else #ifdef __LITEOS_A__
#define PARAM_WORKSPACE_MAX (80 * 1024)
#define PARAM_WORKSPACE_SMALL (1024 * 20)
#ifdef STARTUP_INIT_TEST
#define DAC_DEFAULT_MODE 0777 #define DAC_DEFAULT_MODE 0777
#define PARAM_WORKSPACE_DEF (1024 * 50) #define PARAM_WORKSPACE_MAX (1024 * 10)
#else #define PARAM_WORKSPACE_SMALL PARAM_WORKSPACE_MAX
#define PARAM_WORKSPACE_DEF PARAM_WORKSPACE_MAX
#else // __LITEOS_A__
#define DAC_DEFAULT_MODE 0774 #define DAC_DEFAULT_MODE 0774
#define PARAM_WORKSPACE_MAX (80 * 1024)
#define PARAM_WORKSPACE_SMALL (1024 * 10)
#define PARAM_WORKSPACE_DEF (1024 * 30) #define PARAM_WORKSPACE_DEF (1024 * 30)
#endif #endif // __LITEOS_A__
#define DAC_DEFAULT_GROUP 0 #endif // __LITEOS_M__
#define DAC_DEFAULT_USER 0 #endif // STARTUP_INIT_TEST
#endif
// support futex // support futex
#ifndef __NR_futex #ifndef __NR_futex
...@@ -171,18 +183,6 @@ INIT_LOCAL_API int ParamMutexDelete(ParamMutex *mutex); ...@@ -171,18 +183,6 @@ INIT_LOCAL_API int ParamMutexDelete(ParamMutex *mutex);
#define PARAMSPACE_AREA_RW_UNLOCK(rwlock) (void)(rwlock) #define PARAMSPACE_AREA_RW_UNLOCK(rwlock) (void)(rwlock)
#endif #endif
#ifdef PARAMWORKSPACE_NEED_MUTEX
#define WORKSPACE_INIT_LOCK(workspace) ParamRWMutexCreate(&(workspace).rwlock)
#define WORKSPACE_RW_LOCK(workspace) ParamRWMutexWRLock(&(workspace).rwlock)
#define WORKSPACE_RD_LOCK(workspace) ParamRWMutexRDLock(&(workspace).rwlock)
#define WORKSPACE_RW_UNLOCK(workspace) ParamRWMutexUnlock(&(workspace).rwlock)
#else
#define WORKSPACE_INIT_LOCK(workspace) (void)(workspace)
#define WORKSPACE_RW_LOCK(workspace) (void)(workspace)
#define WORKSPACE_RD_LOCK(workspace) (void)(workspace)
#define WORKSPACE_RW_UNLOCK(workspace) (void)(workspace)
#endif
typedef struct { typedef struct {
int shmid; int shmid;
} MemHandle; } MemHandle;
......
...@@ -48,6 +48,11 @@ extern "C" { ...@@ -48,6 +48,11 @@ extern "C" {
#define DAC_RESULT_PERMISSION 0 #define DAC_RESULT_PERMISSION 0
#define USER_BUFFER_LEN 64
#define GROUP_FORMAT "const.%u_%u"
#define INVALID_SELINUX_INDEX ((uint32_t)-1)
typedef struct UserCred { typedef struct UserCred {
pid_t pid; pid_t pid;
uid_t uid; uid_t uid;
...@@ -81,15 +86,24 @@ typedef struct { ...@@ -81,15 +86,24 @@ typedef struct {
const char *name; const char *name;
#ifdef PARAM_SUPPORT_SELINUX #ifdef PARAM_SUPPORT_SELINUX
char label[SELINUX_CONTENT_LEN]; char label[SELINUX_CONTENT_LEN];
uint32_t selinuxIndex;
#endif #endif
} ParamAuditData; } ParamAuditData;
struct WorkSpace_;
typedef struct ParamLabelIndex_ {
uint32_t selinuxLabelIndex;
uint32_t dacLabelIndex;
struct WorkSpace_ *workspace;
} ParamLabelIndex;
typedef struct { typedef struct {
char name[10]; char name[10];
int (*securityInitLabel)(ParamSecurityLabel *label, int isInit); int (*securityInitLabel)(ParamSecurityLabel *label, int isInit);
int (*securityGetLabel)(const char *path); int (*securityGetLabel)(const char *path);
int (*securityCheckFilePermission)(const ParamSecurityLabel *label, const char *fileName, int flags); int (*securityCheckFilePermission)(const ParamSecurityLabel *label, const char *fileName, int flags);
int (*securityCheckParamPermission)(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode); int (*securityCheckParamPermission)(const ParamLabelIndex *labelIndex,
const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode);
int (*securityFreeLabel)(ParamSecurityLabel *srcLabel); int (*securityFreeLabel)(ParamSecurityLabel *srcLabel);
} ParamSecurityOps; } ParamSecurityOps;
...@@ -104,8 +118,10 @@ typedef struct SelinuxSpace_ { ...@@ -104,8 +118,10 @@ typedef struct SelinuxSpace_ {
int (*readParamCheck)(const char *paraName); int (*readParamCheck)(const char *paraName);
ParamContextsList *(*getParamList)(void); ParamContextsList *(*getParamList)(void);
void (*destroyParamList)(ParamContextsList **list); void (*destroyParamList)(ParamContextsList **list);
int (*getParamLabelIndex)(const char *paraName);
#endif #endif
} SelinuxSpace; } SelinuxSpace;
#ifdef PARAM_SUPPORT_SELINUX #ifdef PARAM_SUPPORT_SELINUX
INIT_LOCAL_API int RegisterSecuritySelinuxOps(ParamSecurityOps *ops, int isInit); INIT_LOCAL_API int RegisterSecuritySelinuxOps(ParamSecurityOps *ops, int isInit);
#endif #endif
...@@ -115,6 +131,12 @@ INIT_LOCAL_API void LoadGroupUser(void); ...@@ -115,6 +131,12 @@ INIT_LOCAL_API void LoadGroupUser(void);
INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit); INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit);
INIT_LOCAL_API int RegisterSecurityOps(int onlyRead); INIT_LOCAL_API int RegisterSecurityOps(int onlyRead);
#ifdef STARTUP_INIT_TEST
STATIC_INLINE int DacCheckParamPermission(const ParamLabelIndex *labelIndex,
const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode);
STATIC_INLINE int SelinuxCheckParamPermission(const ParamLabelIndex *labelIndex,
const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode);
#endif
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -29,12 +29,6 @@ extern "C" { ...@@ -29,12 +29,6 @@ extern "C" {
#endif #endif
#endif #endif
#ifdef PARAM_SUPPORT_SELINUX
#define HASH_BUTT 32
#else
#define HASH_BUTT 1
#endif
typedef struct { typedef struct {
uint32_t left; uint32_t left;
uint32_t right; uint32_t right;
...@@ -66,10 +60,10 @@ typedef struct { ...@@ -66,10 +60,10 @@ typedef struct {
typedef struct { typedef struct {
uid_t uid; uid_t uid;
gid_t gid; gid_t gid;
uint32_t selinuxIndex;
uint16_t mode; uint16_t mode;
uint8_t type; uint8_t type;
uint8_t length; uint8_t length;
char data[0];
} ParamSecurityNode; } ParamSecurityNode;
typedef struct { typedef struct {
...@@ -78,32 +72,32 @@ typedef struct { ...@@ -78,32 +72,32 @@ typedef struct {
uint32_t trieNodeCount; uint32_t trieNodeCount;
uint32_t paramNodeCount; uint32_t paramNodeCount;
uint32_t securityNodeCount; uint32_t securityNodeCount;
uint32_t startIndex;
uint32_t currOffset; uint32_t currOffset;
uint32_t firstNode; uint32_t firstNode;
uint32_t dataSize; uint32_t dataSize;
char data[0]; char data[0];
} ParamTrieHeader; } ParamTrieHeader;
struct WorkSpace_;
typedef struct WorkSpace_ { typedef struct WorkSpace_ {
unsigned int flags; unsigned int flags;
HashNode hashNode;
ListNode node;
uint32_t (*allocTrieNode)(struct WorkSpace_ *workSpace, const char *key, uint32_t keyLen);
int (*compareTrieNode)(const ParamTrieNode *node, const char *key2, uint32_t key2Len);
MemHandle memHandle; MemHandle memHandle;
ParamTrieHeader *area; ParamTrieHeader *area;
#ifdef WORKSPACE_AREA_NEED_MUTEX
ParamRWMutex rwlock; ParamRWMutex rwlock;
#endif ATOMIC_UINT32 rwSpaceLock;
uint32_t spaceSize;
uint32_t spaceIndex;
char fileName[0]; char fileName[0];
} WorkSpace; } WorkSpace;
INIT_LOCAL_API int InitWorkSpace(WorkSpace *workSpace, int onlyRead, uint32_t spaceSize); INIT_LOCAL_API int InitWorkSpace(WorkSpace *workSpace, int onlyRead, uint32_t spaceSize);
INIT_LOCAL_API void CloseWorkSpace(WorkSpace *workSpace); INIT_LOCAL_API void CloseWorkSpace(WorkSpace *workSpace);
INIT_LOCAL_API ParamTrieNode *GetTrieNode(const WorkSpace *workSpace, uint32_t offset); #define GetTrieNode(workSpace, offset) (ParamTrieNode *)(((offset) == 0 || (offset) > (workSpace)->area->dataSize) ? \
NULL : (workSpace)->area->data + (offset))
#define GetTrieRoot(workSpace) \
(ParamTrieNode *)(((workSpace)->area == NULL) ? NULL : (workSpace)->area->data + (workSpace)->area->firstNode)
INIT_LOCAL_API void SaveIndex(uint32_t *index, uint32_t offset); INIT_LOCAL_API void SaveIndex(uint32_t *index, uint32_t offset);
INIT_LOCAL_API ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLen); INIT_LOCAL_API ParamTrieNode *AddTrieNode(WorkSpace *workSpace, const char *key, uint32_t keyLen);
...@@ -119,7 +113,13 @@ INIT_LOCAL_API uint32_t AddParamNode(WorkSpace *workSpace, uint8_t type, ...@@ -119,7 +113,13 @@ INIT_LOCAL_API uint32_t AddParamNode(WorkSpace *workSpace, uint8_t type,
const char *key, uint32_t keyLen, const char *value, uint32_t valueLen); const char *key, uint32_t keyLen, const char *value, uint32_t valueLen);
INIT_LOCAL_API uint32_t GetParamMaxLen(uint8_t type); INIT_LOCAL_API uint32_t GetParamMaxLen(uint8_t type);
INIT_LOCAL_API ParamNode *GetParamNode(const char *spaceName, const char *name); 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);
#ifdef STARTUP_INIT_TEST
STATIC_INLINE ParamTrieNode *FindTrieNode_(
const WorkSpace *workSpace, const char *key, uint32_t keyLen, uint32_t *matchLabel);
#endif
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -95,6 +95,7 @@ typedef struct cmdLineInfo { ...@@ -95,6 +95,7 @@ typedef struct cmdLineInfo {
#define WORKSPACE_FLAGS_LOADED 0x02 #define WORKSPACE_FLAGS_LOADED 0x02
#define WORKSPACE_FLAGS_UPDATE 0x04 #define WORKSPACE_FLAGS_UPDATE 0x04
#define WORKSPACE_FLAGS_LABEL_LOADED 0x08 #define WORKSPACE_FLAGS_LABEL_LOADED 0x08
#define WORKSPACE_FLAGS_NEED_ACCESS 0x10
#define PARAM_SET_FLAG(node, flag) ((node) |= (flag)) #define PARAM_SET_FLAG(node, flag) ((node) |= (flag))
#define PARAM_CLEAR_FLAG(node, flag) ((node) &= ~(flag)) #define PARAM_CLEAR_FLAG(node, flag) ((node) &= ~(flag))
......
...@@ -140,7 +140,10 @@ if (defined(ohos_lite)) { ...@@ -140,7 +140,10 @@ if (defined(ohos_lite)) {
"//third_party/selinux/libselinux/include/", "//third_party/selinux/libselinux/include/",
"//base/security/selinux/interfaces/policycoreutils/include/", "//base/security/selinux/interfaces/policycoreutils/include/",
] ]
defines += [ "PARAM_SUPPORT_SELINUX" ] defines += [
"PARAM_SUPPORT_SELINUX",
"PARAMWORKSPACE_NEED_MUTEX",
]
} }
part_name = "init" part_name = "init"
subsystem_name = "startup" subsystem_name = "startup"
......
...@@ -83,7 +83,7 @@ INIT_LOCAL_API void *GetSharedMem(const char *fileName, MemHandle *handle, uint3 ...@@ -83,7 +83,7 @@ INIT_LOCAL_API void *GetSharedMem(const char *fileName, MemHandle *handle, uint3
PARAM_CHECK(fileName != NULL, return NULL, "Invalid filename or handle"); PARAM_CHECK(fileName != NULL, return NULL, "Invalid filename or handle");
int mode = readOnly ? O_RDONLY : O_CREAT | O_RDWR | O_TRUNC; int mode = readOnly ? O_RDONLY : O_CREAT | O_RDWR | O_TRUNC;
int fd = open(fileName, mode, S_IRWXU | S_IRWXG | S_IROTH); int fd = open(fileName, mode, S_IRWXU | S_IRWXG | S_IROTH);
PARAM_CHECK(fd >= 0, return NULL, "Open file %s mode %x fail error %d", fileName, mode, errno); PARAM_ONLY_CHECK(fd >= 0, return NULL);
int prot = PROT_READ; int prot = PROT_READ;
if (!readOnly) { if (!readOnly) {
...@@ -92,7 +92,7 @@ INIT_LOCAL_API void *GetSharedMem(const char *fileName, MemHandle *handle, uint3 ...@@ -92,7 +92,7 @@ INIT_LOCAL_API void *GetSharedMem(const char *fileName, MemHandle *handle, uint3
} }
void *areaAddr = (void *)mmap(NULL, spaceSize, prot, MAP_SHARED, fd, 0); void *areaAddr = (void *)mmap(NULL, spaceSize, prot, MAP_SHARED, fd, 0);
PARAM_CHECK(areaAddr != MAP_FAILED && areaAddr != NULL, close(fd); PARAM_CHECK(areaAddr != MAP_FAILED && areaAddr != NULL, close(fd);
return NULL, "Failed to map memory error %d spaceSize %d", errno, spaceSize); return NULL, "Failed to map memory error %d fileName %s ", errno, fileName);
close(fd); close(fd);
return areaAddr; return areaAddr;
} }
......
...@@ -39,7 +39,7 @@ __attribute__((constructor)) static void ParameterInit(void) ...@@ -39,7 +39,7 @@ __attribute__((constructor)) static void ParameterInit(void)
if (getpid() == 1) { if (getpid() == 1) {
return; return;
} }
EnableInitLog(INIT_ERROR); EnableInitLog(INIT_WARN);
PARAM_WORKSPACE_OPS ops = {0}; PARAM_WORKSPACE_OPS ops = {0};
ops.updaterMode = 0; ops.updaterMode = 0;
ops.logFunc = InitLog; ops.logFunc = InitLog;
...@@ -194,11 +194,8 @@ int SystemWaitParameter(const char *name, const char *value, int32_t timeout) ...@@ -194,11 +194,8 @@ int SystemWaitParameter(const char *name, const char *value, int32_t timeout)
PARAM_CHECK(name != NULL, return -1, "Invalid name"); PARAM_CHECK(name != NULL, return -1, "Invalid name");
int ret = CheckParamName(name, 0); int ret = CheckParamName(name, 0);
PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", name); PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", name);
ParamHandle handle = 0; ret = CheckParamPermission(GetParamSecurityLabel(), name, DAC_READ);
ret = ReadParamWithCheck(name, DAC_READ, &handle); PARAM_CHECK(ret == 0, return ret, "Forbid to wait parameter %s", name);
if (ret != PARAM_CODE_NOT_FOUND && ret != 0 && ret != PARAM_CODE_NODE_EXIST) {
PARAM_CHECK(ret == 0, return ret, "Forbid to wait parameter %s", name);
}
if (timeout <= 0) { if (timeout <= 0) {
timeout = DEFAULT_PARAM_WAIT_TIMEOUT; timeout = DEFAULT_PARAM_WAIT_TIMEOUT;
} }
...@@ -249,10 +246,7 @@ int WatchParamCheck(const char *keyprefix) ...@@ -249,10 +246,7 @@ int WatchParamCheck(const char *keyprefix)
PARAM_CHECK(keyprefix != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid keyprefix"); PARAM_CHECK(keyprefix != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid keyprefix");
int ret = CheckParamName(keyprefix, 0); int ret = CheckParamName(keyprefix, 0);
PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", keyprefix); PARAM_CHECK(ret == 0, return ret, "Illegal param name %s", keyprefix);
ParamHandle handle = 0; ret = CheckParamPermission(GetParamSecurityLabel(), keyprefix, DAC_WATCH);
ret = ReadParamWithCheck(keyprefix, DAC_WATCH, &handle); PARAM_CHECK(ret == 0, return ret, "Forbid to watcher parameter %s", keyprefix);
if (ret != PARAM_CODE_NOT_FOUND && ret != 0 && ret != PARAM_CODE_NODE_EXIST) {
PARAM_CHECK(ret == 0, return ret, "Forbid to watch parameter %s", keyprefix);
}
return 0; return 0;
} }
...@@ -61,7 +61,7 @@ static void TimerCallback(const ParamTaskPtr timer, void *context) ...@@ -61,7 +61,7 @@ static void TimerCallback(const ParamTaskPtr timer, void *context)
static void CheckAndSendTrigger(uint32_t dataIndex, const char *name, const char *value) static void CheckAndSendTrigger(uint32_t dataIndex, const char *name, const char *value)
{ {
ParamNode *entry = (ParamNode *)GetTrieNode(GetWorkSpace(name), dataIndex); ParamNode *entry = (ParamNode *)GetTrieNode(GetWorkSpace(GetWorkSpaceIndex(name)), dataIndex);
PARAM_CHECK(entry != NULL, return, "Failed to get data %s ", name); PARAM_CHECK(entry != NULL, return, "Failed to get data %s ", name);
uint32_t trigger = 1; uint32_t trigger = 1;
if ((ATOMIC_LOAD_EXPLICIT(&entry->commitId, memory_order_relaxed) & PARAM_FLAGS_TRIGGED) != PARAM_FLAGS_TRIGGED) { if ((ATOMIC_LOAD_EXPLICIT(&entry->commitId, memory_order_relaxed) & PARAM_FLAGS_TRIGGED) != PARAM_FLAGS_TRIGGED) {
...@@ -278,7 +278,6 @@ static int HandleParamWaitAdd(const ParamTaskPtr worker, const ParamMessage *msg ...@@ -278,7 +278,6 @@ static int HandleParamWaitAdd(const ParamTaskPtr worker, const ParamMessage *msg
ParamTaskClose(g_paramService.timer); ParamTaskClose(g_paramService.timer);
g_paramService.timer = NULL; g_paramService.timer = NULL;
return 0, "Failed to set timer %s", msg->key); return 0, "Failed to set timer %s", msg->key);
PARAM_LOGI("Start timer %p", g_paramService.timer);
} }
return 0; return 0;
} }
...@@ -360,17 +359,13 @@ PARAM_STATIC int OnIncomingConnect(LoopHandle loop, TaskHandle server) ...@@ -360,17 +359,13 @@ PARAM_STATIC int OnIncomingConnect(LoopHandle loop, TaskHandle server)
return 0; return 0;
} }
static void LoadSelinuxLabel(void) static void LoadSelinuxLabel(const char *op)
{ {
ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL, return, "Invalid paramSpace");
PARAM_WORKSPACE_CHECK(paramSpace, return, "Invalid space");
// load security label // load security label
#ifdef PARAM_SUPPORT_SELINUX #ifdef PARAM_SUPPORT_SELINUX
ParamSecurityOps *ops = GetParamSecurityOps(PARAM_SECURITY_SELINUX); ParamSecurityOps *ops = GetParamSecurityOps(PARAM_SECURITY_SELINUX);
if (ops != NULL && ops->securityGetLabel != NULL) { if (ops != NULL && ops->securityGetLabel != NULL) {
ops->securityGetLabel(NULL); ops->securityGetLabel(op);
} }
#endif #endif
} }
...@@ -415,7 +410,7 @@ void LoadSpecialParam(void) ...@@ -415,7 +410,7 @@ void LoadSpecialParam(void)
// read param area size from cfg and save to dac // read param area size from cfg and save to dac
LoadParamAreaSize(); LoadParamAreaSize();
// read selinux label // read selinux label
LoadSelinuxLabel(); LoadSelinuxLabel(NULL);
// from cmdline // from cmdline
LoadParamFromCmdLine(); LoadParamFromCmdLine();
// from build // from build
...@@ -424,6 +419,8 @@ void LoadSpecialParam(void) ...@@ -424,6 +419,8 @@ void LoadSpecialParam(void)
int StartParamService(void) int StartParamService(void)
{ {
// read selinux label
LoadSelinuxLabel("permission");
return ParamServiceStart(); return ParamServiceStart();
} }
......
...@@ -115,10 +115,6 @@ static_library("param_client_lite") { ...@@ -115,10 +115,6 @@ static_library("param_client_lite") {
defines = param_build_defines defines = param_build_defines
public_configs = [ ":exported_header_files" ] public_configs = [ ":exported_header_files" ]
if (use_musl) {
defines += [ "PARAM_BASE" ]
}
if (ohos_kernel_type == "liteos_a") { if (ohos_kernel_type == "liteos_a") {
sources += sources +=
[ "//base/startup/init/services/param/adapter/param_persistadp.c" ] [ "//base/startup/init/services/param/adapter/param_persistadp.c" ]
......
...@@ -68,11 +68,8 @@ int SystemWaitParameter(const char *name, const char *value, int32_t timeout) ...@@ -68,11 +68,8 @@ int SystemWaitParameter(const char *name, const char *value, int32_t timeout)
PARAM_CHECK(name != NULL && value != NULL, return -1, "Invalid name or value %s", name); PARAM_CHECK(name != NULL && value != NULL, return -1, "Invalid name or value %s", name);
long long globalCommit = 0; long long globalCommit = 0;
// first check permission // first check permission
ParamHandle handle = 0; int ret = CheckParamPermission(GetParamSecurityLabel(), name, DAC_READ);
int ret = ReadParamWithCheck(name, DAC_READ, &handle); PARAM_CHECK(ret == 0, return ret, "Forbid to wait parameter %s", name);
if (ret != PARAM_CODE_NOT_FOUND && ret != 0 && ret != PARAM_CODE_NODE_EXIST) {
PARAM_CHECK(ret == 0, return ret, "Forbid to wait parameters %s", name);
}
uint32_t diff = 0; uint32_t diff = 0;
time_t startTime; time_t startTime;
if (timeout <= 0) { if (timeout <= 0) {
......
...@@ -52,8 +52,10 @@ static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char ...@@ -52,8 +52,10 @@ static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char
return 0; return 0;
} }
static int DacCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode) static int LiteDacCheckParamPermission(uint32_t index,
const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
{ {
UNUSED(index);
UNUSED(srcLabel); UNUSED(srcLabel);
UNUSED(name); UNUSED(name);
UNUSED(mode); UNUSED(mode);
...@@ -72,7 +74,7 @@ INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit) ...@@ -72,7 +74,7 @@ INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit)
ops->securityGetLabel = NULL; ops->securityGetLabel = NULL;
ops->securityInitLabel = InitLocalSecurityLabel; ops->securityInitLabel = InitLocalSecurityLabel;
ops->securityCheckFilePermission = CheckFilePermission; ops->securityCheckFilePermission = CheckFilePermission;
ops->securityCheckParamPermission = DacCheckParamPermission; ops->securityCheckParamPermission = LiteDacCheckParamPermission;
ops->securityFreeLabel = FreeLocalSecurityLabel; ops->securityFreeLabel = FreeLocalSecurityLabel;
if (isInit) { if (isInit) {
ops->securityGetLabel = DacGetParamSecurityLabel; ops->securityGetLabel = DacGetParamSecurityLabel;
......
/* /*
* Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Copyright (c) 2022 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. * you may not use this file except in compliance with the License.
* You may obtain a copy of the License at * You may obtain a copy of the License at
...@@ -25,13 +25,15 @@ ...@@ -25,13 +25,15 @@
#include "securec.h" #include "securec.h"
static DUMP_PRINTF g_printf = printf; static DUMP_PRINTF g_printf = printf;
static int ReadParamName(ParamHandle handle, char *name, uint32_t length);
ParamNode *SystemCheckMatchParamWait(const char *name, const char *value) ParamNode *SystemCheckMatchParamWait(const char *name, const char *value)
{ {
ParamWorkSpace *paramSpace = GetParamWorkSpace(); ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL, return NULL, "Invalid paramSpace"); PARAM_CHECK(paramSpace != NULL, return NULL, "Invalid paramSpace");
PARAM_WORKSPACE_CHECK(paramSpace, return NULL, "Invalid space"); PARAM_WORKSPACE_CHECK(paramSpace, return NULL, "Invalid space");
WorkSpace *workspace = GetWorkSpace(name); WorkSpace *workspace = GetWorkSpace(GetWorkSpaceIndex(name));
PARAM_CHECK(workspace != NULL, return NULL, "Failed to get workspace %s", name); PARAM_CHECK(workspace != NULL, return NULL, "Failed to get workspace %s", name);
PARAM_LOGV("SystemCheckMatchParamWait name %s", name); PARAM_LOGV("SystemCheckMatchParamWait name %s", name);
uint32_t nameLength = strlen(name); uint32_t nameLength = strlen(name);
...@@ -75,7 +77,7 @@ static int ProcessParamTraversal(const WorkSpace *workSpace, const ParamTrieNode ...@@ -75,7 +77,7 @@ static int ProcessParamTraversal(const WorkSpace *workSpace, const ParamTrieNode
if ((strcmp("#", context->prefix) != 0) && (strncmp(entry->data, context->prefix, strlen(context->prefix)) != 0)) { if ((strcmp("#", context->prefix) != 0) && (strncmp(entry->data, context->prefix, strlen(context->prefix)) != 0)) {
return 0; return 0;
} }
uint32_t index = GetParamHandle(workSpace, current->dataIndex, entry->data); uint32_t index = PARAM_HANDLE(workSpace, current->dataIndex);
context->traversalParamPtr(index, context->context); context->traversalParamPtr(index, context->context);
return 0; return 0;
} }
...@@ -90,21 +92,17 @@ int SystemTraversalParameter(const char *prefix, TraversalParamPtr traversalPara ...@@ -90,21 +92,17 @@ int SystemTraversalParameter(const char *prefix, TraversalParamPtr traversalPara
#ifdef PARAM_SUPPORT_SELINUX // load security label #ifdef PARAM_SUPPORT_SELINUX // load security label
ParamSecurityOps *ops = GetParamSecurityOps(PARAM_SECURITY_SELINUX); ParamSecurityOps *ops = GetParamSecurityOps(PARAM_SECURITY_SELINUX);
if (ops != NULL && ops->securityGetLabel != NULL) { if (ops != NULL && ops->securityGetLabel != NULL) {
ops->securityGetLabel(NULL); ops->securityGetLabel("open");
} }
#endif #endif
ParamTraversalContext context = {traversalParameter, cookie, "#"}; ParamTraversalContext context = {traversalParameter, cookie, "#"};
if (!(prefix == NULL || strlen(prefix) == 0)) { if (!(prefix == NULL || strlen(prefix) == 0)) {
ParamHandle handle = 0; int ret = CheckParamPermission(GetParamSecurityLabel(), prefix, DAC_READ);
// only check for valid parameter PARAM_CHECK(ret == 0, return ret, "Forbid to traversal parameters %s", prefix);
int ret = ReadParamWithCheck(prefix, DAC_READ, &handle);
if (ret != PARAM_CODE_NOT_FOUND && ret != 0 && ret != PARAM_CODE_NODE_EXIST) {
PARAM_CHECK(ret == 0, return ret, "Forbid to traversal parameters");
}
context.prefix = (char *)prefix; context.prefix = (char *)prefix;
} }
WorkSpace *workSpace = GetFirstWorkSpace(); WorkSpace *workSpace = GetNextWorkSpace(NULL);
if (workSpace != NULL && strcmp(workSpace->fileName, WORKSPACE_NAME_DAC) == 0) { if (workSpace != NULL && strcmp(workSpace->fileName, WORKSPACE_NAME_DAC) == 0) {
workSpace = GetNextWorkSpace(workSpace); workSpace = GetNextWorkSpace(workSpace);
} }
...@@ -145,8 +143,8 @@ static int DumpTrieDataNodeTraversal(const WorkSpace *workSpace, const ParamTrie ...@@ -145,8 +143,8 @@ static int DumpTrieDataNodeTraversal(const WorkSpace *workSpace, const ParamTrie
if (current->labelIndex != 0 && verbose) { if (current->labelIndex != 0 && verbose) {
ParamSecurityNode *label = (ParamSecurityNode *)GetTrieNode(workSpace, current->labelIndex); ParamSecurityNode *label = (ParamSecurityNode *)GetTrieNode(workSpace, current->labelIndex);
if (label != NULL) { if (label != NULL) {
PARAM_DUMP("\tparameter label dac %u %u %o \n\t label: %s \n", PARAM_DUMP("\tparameter label dac %u %u %o selinuxIndex %u \n",
label->uid, label->gid, label->mode, (label->length > 0) ? label->data : "null"); label->uid, label->gid, label->mode, label->selinuxIndex);
} }
} }
return 0; return 0;
...@@ -169,7 +167,7 @@ static void HashNodeTraverseForDump(WorkSpace *workSpace, int verbose) ...@@ -169,7 +167,7 @@ static void HashNodeTraverseForDump(WorkSpace *workSpace, int verbose)
PARAMSPACE_AREA_RW_UNLOCK(workSpace); PARAMSPACE_AREA_RW_UNLOCK(workSpace);
} }
void SystemDumpParameters(int verbose, int (*dump)(const char *fmt, ...)) void SystemDumpParameters(int verbose, int index, int (*dump)(const char *fmt, ...))
{ {
if (dump != NULL) { if (dump != NULL) {
g_printf = dump; g_printf = dump;
...@@ -180,26 +178,30 @@ void SystemDumpParameters(int verbose, int (*dump)(const char *fmt, ...)) ...@@ -180,26 +178,30 @@ void SystemDumpParameters(int verbose, int (*dump)(const char *fmt, ...))
PARAM_CHECK(paramSpace != NULL, return, "Invalid paramSpace"); PARAM_CHECK(paramSpace != NULL, return, "Invalid paramSpace");
PARAM_WORKSPACE_CHECK(paramSpace, return, "Invalid space"); PARAM_WORKSPACE_CHECK(paramSpace, return, "Invalid space");
// check default dac // check default dac
ParamHandle handle = 0; int ret = CheckParamPermission(GetParamSecurityLabel(), "#", DAC_READ);
int ret = ReadParamWithCheck("#", DAC_READ, &handle); PARAM_CHECK(ret == 0, return, "Forbid to dump parameters ");
if (ret != PARAM_CODE_NOT_FOUND && ret != 0 && ret != PARAM_CODE_NODE_EXIST) {
PARAM_CHECK(ret == 0, return, "Forbid to dump parameters");
}
#ifdef PARAM_SUPPORT_SELINUX // load security label #ifdef PARAM_SUPPORT_SELINUX // load security label
ParamSecurityOps *ops = GetParamSecurityOps(PARAM_SECURITY_SELINUX); ParamSecurityOps *ops = GetParamSecurityOps(PARAM_SECURITY_SELINUX);
if (ops != NULL && ops->securityGetLabel != NULL) { if (ops != NULL && ops->securityGetLabel != NULL) {
ops->securityGetLabel(NULL); ops->securityGetLabel("open");
} }
#endif #endif
PARAM_DUMP("Dump all parameters begin ...\n"); PARAM_DUMP("Dump all parameters begin ...\n");
if (verbose) { if (verbose) {
PARAM_DUMP("Local sercurity information\n"); PARAM_DUMP("Local security information\n");
PARAM_DUMP("pid: %d uid: %u gid: %u \n", PARAM_DUMP("pid: %d uid: %u gid: %u \n",
paramSpace->securityLabel.cred.pid, paramSpace->securityLabel.cred.pid,
paramSpace->securityLabel.cred.uid, paramSpace->securityLabel.cred.uid,
paramSpace->securityLabel.cred.gid); paramSpace->securityLabel.cred.gid);
} }
WorkSpace *workSpace = GetFirstWorkSpace(); if (index > 0) {
WorkSpace *workSpace = GetWorkSpace(index);
if (workSpace != NULL) {
HashNodeTraverseForDump(workSpace, verbose);
}
return;
}
WorkSpace *workSpace = GetNextWorkSpace(NULL);
while (workSpace != NULL) { while (workSpace != NULL) {
WorkSpace *next = GetNextWorkSpace(workSpace); WorkSpace *next = GetNextWorkSpace(workSpace);
HashNodeTraverseForDump(workSpace, verbose); HashNodeTraverseForDump(workSpace, verbose);
...@@ -215,7 +217,7 @@ INIT_LOCAL_API int SysCheckParamExist(const char *name) ...@@ -215,7 +217,7 @@ INIT_LOCAL_API int SysCheckParamExist(const char *name)
PARAM_WORKSPACE_CHECK(paramSpace, return -1, "Invalid space"); PARAM_WORKSPACE_CHECK(paramSpace, return -1, "Invalid space");
PARAM_CHECK(name != NULL, return -1, "The name or handle is null"); PARAM_CHECK(name != NULL, return -1, "The name or handle is null");
WorkSpace *workSpace = GetFirstWorkSpace(); WorkSpace *workSpace = GetNextWorkSpace(NULL);
while (workSpace != NULL) { while (workSpace != NULL) {
PARAM_LOGV("SysCheckParamExist name %s in space %s", name, workSpace->fileName); PARAM_LOGV("SysCheckParamExist name %s in space %s", name, workSpace->fileName);
WorkSpace *next = GetNextWorkSpace(workSpace); WorkSpace *next = GetNextWorkSpace(workSpace);
...@@ -238,7 +240,7 @@ INIT_INNER_API int GetParamSecurityAuditData(const char *name, int type, ParamAu ...@@ -238,7 +240,7 @@ INIT_INNER_API int GetParamSecurityAuditData(const char *name, int type, ParamAu
PARAM_WORKSPACE_CHECK(paramSpace, return -1, "Invalid space"); PARAM_WORKSPACE_CHECK(paramSpace, return -1, "Invalid space");
uint32_t labelIndex = 0; uint32_t labelIndex = 0;
// get from dac // get from dac
WorkSpace *space = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *space = GetWorkSpace(WORKSPACE_INDEX_DAC);
PARAM_CHECK(space != NULL, return -1, "Invalid workSpace"); PARAM_CHECK(space != NULL, return -1, "Invalid workSpace");
FindTrieNode(space, name, strlen(name), &labelIndex); FindTrieNode(space, name, strlen(name), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(space, labelIndex); ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(space, labelIndex);
...@@ -382,3 +384,277 @@ int SystemGetParameterName(ParamHandle handle, char *name, unsigned int len) ...@@ -382,3 +384,277 @@ int SystemGetParameterName(ParamHandle handle, char *name, unsigned int len)
PARAM_CHECK(name != NULL && handle != 0, return -1, "The name is null"); PARAM_CHECK(name != NULL && handle != 0, return -1, "The name is null");
return ReadParamName(handle, name, len); return ReadParamName(handle, name, len);
} }
static int AddParam(WorkSpace *workSpace, uint8_t type, const char *name, const char *value, uint32_t *dataIndex)
{
ParamTrieNode *node = AddTrieNode(workSpace, name, strlen(name));
PARAM_CHECK(node != NULL, return PARAM_CODE_REACHED_MAX,
"Failed to add node name %s space %s", name, workSpace->fileName);
ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, node->dataIndex);
if (entry == NULL) {
uint32_t offset = AddParamNode(workSpace, type, name, strlen(name), value, strlen(value));
PARAM_CHECK(offset > 0, return PARAM_CODE_REACHED_MAX,
"Failed to allocate name %s space %s", name, workSpace->fileName);
SaveIndex(&node->dataIndex, offset);
long long globalCommitId = ATOMIC_LOAD_EXPLICIT(&workSpace->area->commitId, memory_order_relaxed);
ATOMIC_STORE_EXPLICIT(&workSpace->area->commitId, ++globalCommitId, memory_order_release);
#ifdef PARAM_SUPPORT_SELINUX
WorkSpace *space = GetWorkSpace(WORKSPACE_INDEX_DAC);
if (space != NULL && space != workSpace) { // dac commit is global commit
globalCommitId = ATOMIC_LOAD_EXPLICIT(&space->area->commitId, memory_order_relaxed);
ATOMIC_STORE_EXPLICIT(&space->area->commitId, ++globalCommitId, memory_order_release);
}
#endif
}
if (dataIndex != NULL) {
*dataIndex = node->dataIndex;
}
PARAM_LOGV("AddParam name %s value: %s", name, value);
return 0;
}
static int UpdateParam(const WorkSpace *workSpace, uint32_t *dataIndex, const char *name, const char *value)
{
ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, *dataIndex);
PARAM_CHECK(entry != NULL, return PARAM_CODE_REACHED_MAX, "Failed to update param value %s %u", name, *dataIndex);
PARAM_CHECK(entry->keyLength == strlen(name), return PARAM_CODE_INVALID_NAME, "Failed to check name len %s", name);
uint32_t valueLen = strlen(value);
uint32_t commitId = ATOMIC_LOAD_EXPLICIT(&entry->commitId, memory_order_relaxed);
ATOMIC_STORE_EXPLICIT(&entry->commitId, commitId | PARAM_FLAGS_MODIFY, memory_order_relaxed);
long long globalCommitId = ATOMIC_LOAD_EXPLICIT(&workSpace->area->commitId, memory_order_relaxed);
if (entry->valueLength < PARAM_VALUE_LEN_MAX && valueLen < PARAM_VALUE_LEN_MAX) {
int ret = ParamMemcpy(entry->data + entry->keyLength + 1, PARAM_VALUE_LEN_MAX, value, valueLen + 1);
PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_VALUE, "Failed to copy value");
entry->valueLength = valueLen;
}
uint32_t flags = commitId & ~PARAM_FLAGS_COMMITID;
ATOMIC_STORE_EXPLICIT(&entry->commitId, (++commitId) | flags, memory_order_release);
ATOMIC_STORE_EXPLICIT(&workSpace->area->commitId, ++globalCommitId, memory_order_release);
#ifdef PARAM_SUPPORT_SELINUX
WorkSpace *space = GetWorkSpace(WORKSPACE_INDEX_DAC);
if (space != NULL && space != workSpace) { // dac commit is global commit
globalCommitId = ATOMIC_LOAD_EXPLICIT(&space->area->commitId, memory_order_relaxed);
ATOMIC_STORE_EXPLICIT(&space->area->commitId, ++globalCommitId, memory_order_release);
}
#endif
PARAM_LOGV("UpdateParam name %s value: %s", name, value);
futex_wake(&entry->commitId, INT_MAX);
return 0;
}
INIT_LOCAL_API int WriteParam(const char *name, const char *value, uint32_t *dataIndex, int mode)
{
PARAM_LOGV("WriteParam %s", name);
ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL, return -1, "Invalid paramSpace");
PARAM_WORKSPACE_CHECK(paramSpace, return -1, "Invalid space");
PARAM_CHECK(value != NULL && name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid name or value");
WorkSpace *workSpace = GetWorkSpace(GetWorkSpaceIndex(name));
PARAM_CHECK(workSpace != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid workSpace");
ParamTrieNode *node = FindTrieNode(workSpace, name, strlen(name), NULL);
int ret = 0;
if (node != NULL && node->dataIndex != 0) {
if (dataIndex != NULL) {
*dataIndex = node->dataIndex;
}
if ((mode & LOAD_PARAM_ONLY_ADD) == LOAD_PARAM_ONLY_ADD) {
return PARAM_CODE_READ_ONLY;
}
ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, node->dataIndex);
PARAM_CHECK(entry != NULL, return PARAM_CODE_REACHED_MAX,
"Failed to update param value %s %u", name, node->dataIndex);
// use save type to check value
ret = CheckParamValue(node, name, value, entry->type);
PARAM_CHECK(ret == 0, return ret, "Invalid param value param: %s=%s", name, value);
PARAMSPACE_AREA_RW_LOCK(workSpace);
ret = UpdateParam(workSpace, &node->dataIndex, name, value);
PARAMSPACE_AREA_RW_UNLOCK(workSpace);
} else {
uint8_t type = GetParamValueType(name);
ret = CheckParamValue(node, name, value, type);
PARAM_CHECK(ret == 0, return ret, "Invalid param value param: %s=%s", name, value);
PARAMSPACE_AREA_RW_LOCK(workSpace);
ret = AddParam((WorkSpace *)workSpace, type, name, value, dataIndex);
PARAMSPACE_AREA_RW_UNLOCK(workSpace);
}
return ret;
}
INIT_LOCAL_API int CheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
{
PARAM_CHECK(srcLabel != NULL, return DAC_RESULT_FORBIDED, "The srcLabel is null");
ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_WORKSPACE_CHECK(paramSpace, return DAC_RESULT_FORBIDED, "Invalid workspace");
PARAM_CHECK(paramSpace->checkParamPermission != NULL, return DAC_RESULT_FORBIDED, "Invalid check permission");
ParamLabelIndex labelIndex = {0};
// search node from dac space, and get selinux label index
WorkSpace *dacSpace = GetWorkSpace(WORKSPACE_INDEX_DAC);
(void)FindTrieNode(dacSpace, name, strlen(name), &labelIndex.dacLabelIndex);
ParamSecurityNode *securityNode = (ParamSecurityNode *)GetTrieNode(dacSpace, labelIndex.dacLabelIndex);
if ((securityNode == NULL) || (securityNode->selinuxIndex == 0) ||
(securityNode->selinuxIndex == INVALID_SELINUX_INDEX)) {
labelIndex.selinuxLabelIndex = GetWorkSpaceIndex(name);
} else {
labelIndex.selinuxLabelIndex = securityNode->selinuxIndex;
}
if (labelIndex.selinuxLabelIndex < paramSpace->maxLabelIndex) {
labelIndex.workspace = paramSpace->workSpace[labelIndex.selinuxLabelIndex];
}
PARAM_CHECK(labelIndex.workspace != NULL, return PARAM_CODE_INVALID_PARAM,
"Invalid workSpace for %s %u", name, labelIndex.selinuxLabelIndex);
int ret = paramSpace->checkParamPermission(&labelIndex, srcLabel, name, mode);
if (ret != 0) {
PARAM_LOGW("Forbid to access %s label %u %u", name, labelIndex.dacLabelIndex, labelIndex.selinuxLabelIndex);
}
return ret;
}
INIT_LOCAL_API WorkSpace *GetNextWorkSpace(WorkSpace *curr)
{
ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL, return NULL, "Invalid paramSpace");
uint32_t i = (curr == NULL) ? 0 : (curr->spaceIndex + 1);
WorkSpace *workSpace = NULL;
for (; i < paramSpace->maxLabelIndex; ++i) {
workSpace = GetWorkSpace(i);
if (workSpace != NULL) {
return workSpace;
}
}
return NULL;
}
INIT_LOCAL_API uint8_t GetParamValueType(const char *name)
{
uint32_t labelIndex = 0;
WorkSpace *space = GetWorkSpace(WORKSPACE_INDEX_DAC);
if (space == NULL) {
return PARAM_TYPE_STRING;
}
(void)FindTrieNode(space, name, strlen(name), &labelIndex);
ParamSecurityNode *securityNode = (ParamSecurityNode *)GetTrieNode(space, labelIndex);
if (securityNode == NULL) {
return PARAM_TYPE_STRING;
}
return securityNode->type;
}
static int CheckParamValueType(const char *name, const char *value, uint8_t paramType)
{
(void)name;
if (paramType == PARAM_TYPE_INT) {
long long int temp1 = 0;
if (strlen(value) > 1 && value[0] == '-' && StringToLL(value, &temp1) != 0) {
PARAM_LOGE("Illegal param value %s for int", value);
return PARAM_CODE_INVALID_VALUE;
}
unsigned long long int temp2 = 0;
if (StringToULL(value, &temp2) != 0) {
PARAM_LOGE("Illegal param value %s for int", value);
return PARAM_CODE_INVALID_VALUE;
}
} else if (paramType == PARAM_TYPE_BOOL) {
static const char *validValue[] = {
"1", "0", "true", "false", "y", "yes", "on", "off", "n", "no"
};
size_t i = 0;
for (; i < ARRAY_LENGTH(validValue); i++) {
if (strcasecmp(validValue[i], value) == 0) {
break;
}
}
if (i >= ARRAY_LENGTH(validValue)) {
PARAM_LOGE("Illegal param value %s for bool", value);
return PARAM_CODE_INVALID_VALUE;
}
}
return 0;
}
INIT_LOCAL_API int CheckParamValue(const ParamTrieNode *node, const char *name, const char *value, uint8_t paramType)
{
if (IS_READY_ONLY(name)) {
PARAM_CHECK(strlen(value) < PARAM_CONST_VALUE_LEN_MAX,
return PARAM_CODE_INVALID_VALUE, "Illegal param value %s", value);
if (node != NULL && node->dataIndex != 0) {
PARAM_LOGE("Read-only param was already set %s", name);
return PARAM_CODE_READ_ONLY;
}
} else {
PARAM_CHECK(strlen(value) < GetParamMaxLen(paramType),
return PARAM_CODE_INVALID_VALUE, "Illegal param value %s length", value);
}
return CheckParamValueType(name, value, paramType);
}
static int ReadParamName(ParamHandle handle, char *name, uint32_t length)
{
PARAM_CHECK(name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param");
ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_WORKSPACE_CHECK(paramSpace, return -1, "Param workspace has not init.");
PARAM_ONLY_CHECK(handle != (ParamHandle)-1, return PARAM_CODE_NOT_FOUND);
uint32_t labelIndex = 0;
uint32_t index = 0;
PARAM_GET_HANDLE_INFO(handle, labelIndex, index);
WorkSpace *workSpace = GetWorkSpace(labelIndex);
PARAM_CHECK(workSpace != NULL, return PARAM_CODE_NOT_FOUND, "Invalid workSpace for handle %x", handle);
ParamNode *entry = NULL;
if (PARAM_IS_ALIGNED(index)) {
entry = (ParamNode *)GetTrieNode(workSpace, index);
}
if (entry == NULL) {
return PARAM_CODE_NOT_FOUND;
}
PARAM_CHECK(length > entry->keyLength, return -1, "Invalid param size %u %u", entry->keyLength, length);
int ret = ParamMemcpy(name, length, entry->data, entry->keyLength);
PARAM_CHECK(ret == 0, return PARAM_CODE_INVALID_PARAM, "Failed to copy name");
name[entry->keyLength] = '\0';
return 0;
}
INIT_LOCAL_API int CheckParamName(const char *name, int info)
{
PARAM_CHECK(name != NULL, return PARAM_CODE_INVALID_PARAM, "Invalid param");
size_t nameLen = strlen(name);
if (nameLen >= PARAM_NAME_LEN_MAX) {
return PARAM_CODE_INVALID_NAME;
}
if (strcmp(name, "#") == 0) {
return 0;
}
if (nameLen < 1 || name[0] == '.' || (!info && name[nameLen - 1] == '.')) {
PARAM_LOGE("CheckParamName %s %d", name, info);
return PARAM_CODE_INVALID_NAME;
}
/* Only allow alphanumeric, plus '.', '-', '@', ':', or '_' */
/* Don't allow ".." to appear in a param name */
for (size_t i = 0; i < nameLen; i++) {
if (name[i] == '.') {
if (name[i - 1] == '.') {
return PARAM_CODE_INVALID_NAME;
}
continue;
}
if (name[i] == '_' || name[i] == '-' || name[i] == '@' || name[i] == ':') {
continue;
}
if (isalnum(name[i])) {
continue;
}
return PARAM_CODE_INVALID_NAME;
}
return 0;
}
void ResetParamSecurityLabel(void)
{
ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL, return, "Invalid paramSpace");
paramSpace->securityLabel.cred.pid = getpid();
paramSpace->securityLabel.cred.uid = geteuid();
paramSpace->securityLabel.cred.gid = getegid();
paramSpace->flags |= WORKSPACE_FLAGS_NEED_ACCESS;
}
\ No newline at end of file
...@@ -38,8 +38,8 @@ static long long GetPersistCommitId(void) ...@@ -38,8 +38,8 @@ static long long GetPersistCommitId(void)
ParamWorkSpace *paramSpace = GetParamWorkSpace(); ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL, return 0, "Invalid paramSpace"); PARAM_CHECK(paramSpace != NULL, return 0, "Invalid paramSpace");
PARAM_WORKSPACE_CHECK(paramSpace, return 0, "Invalid space"); PARAM_WORKSPACE_CHECK(paramSpace, return 0, "Invalid space");
WorkSpace *space = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *space = GetWorkSpace(WORKSPACE_INDEX_DAC);
if (space == NULL || space->area == NULL) { if (space == NULL) {
return 0; return 0;
} }
PARAMSPACE_AREA_RD_LOCK(space); PARAMSPACE_AREA_RD_LOCK(space);
...@@ -53,8 +53,8 @@ static void UpdatePersistCommitId(void) ...@@ -53,8 +53,8 @@ static void UpdatePersistCommitId(void)
ParamWorkSpace *paramSpace = GetParamWorkSpace(); ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL, return, "Invalid paramSpace"); PARAM_CHECK(paramSpace != NULL, return, "Invalid paramSpace");
PARAM_WORKSPACE_CHECK(paramSpace, return, "Invalid space"); PARAM_WORKSPACE_CHECK(paramSpace, return, "Invalid space");
WorkSpace *space = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *space = GetWorkSpace(WORKSPACE_INDEX_DAC);
if (space == NULL || space->area == NULL) { if (space == NULL) {
return; return;
} }
PARAMSPACE_AREA_RW_LOCK(space); PARAMSPACE_AREA_RW_LOCK(space);
...@@ -105,7 +105,7 @@ static int BatchSavePersistParam(void) ...@@ -105,7 +105,7 @@ static int BatchSavePersistParam(void)
const char *prefix = PARAM_PERSIST_PREFIX; const char *prefix = PARAM_PERSIST_PREFIX;
#endif #endif
// walk and save persist param // walk and save persist param
WorkSpace *workSpace = GetFirstWorkSpace(); WorkSpace *workSpace = GetNextWorkSpace(NULL);
while (workSpace != NULL) { while (workSpace != NULL) {
WorkSpace *next = GetNextWorkSpace(workSpace); WorkSpace *next = GetNextWorkSpace(workSpace);
ParamTrieNode *root = FindTrieNode(workSpace, prefix, strlen(prefix), NULL); ParamTrieNode *root = FindTrieNode(workSpace, prefix, strlen(prefix), NULL);
......
...@@ -53,7 +53,7 @@ static int CommonDealFun(const char *name, const char *value, int res) ...@@ -53,7 +53,7 @@ static int CommonDealFun(const char *name, const char *value, int res)
ret = WriteParam(name, value, NULL, 0); ret = WriteParam(name, value, NULL, 0);
PARAM_CHECK(ret == 0, return ret, "Failed to write param %s %s", name, value); PARAM_CHECK(ret == 0, return ret, "Failed to write param %s %s", name, value);
} else { } else {
PARAM_LOGE("Get %s parameter value is null.", name); PARAM_LOGW("Get %s parameter value is null.", name);
} }
return ret; return ret;
} }
...@@ -256,17 +256,7 @@ static int LoadOneParamAreaSize_(const uint32_t *context, const char *name, cons ...@@ -256,17 +256,7 @@ static int LoadOneParamAreaSize_(const uint32_t *context, const char *name, cons
ret = CheckParamValue(NULL, name, value, PARAM_TYPE_INT); ret = CheckParamValue(NULL, name, value, PARAM_TYPE_INT);
PARAM_CHECK(ret == 0, return 0, "Invalid value %s for %s", value, name); PARAM_CHECK(ret == 0, return 0, "Invalid value %s for %s", value, name);
PARAM_LOGV("LoadOneParamAreaSize_ [%s] [%s]", name, value); PARAM_LOGV("LoadOneParamAreaSize_ [%s] [%s]", name, value);
return AddParamEntry(WORKSPACE_INDEX_BASE, PARAM_TYPE_INT, name, value);
WorkSpace *workSpace = GetWorkSpace(WORKSPACE_NAME_DAC);
ParamTrieNode *node = AddTrieNode(workSpace, name, strlen(name));
PARAM_CHECK(node != NULL, return PARAM_CODE_REACHED_MAX, "Failed to add node");
ParamNode *entry = (ParamNode *)GetTrieNode(workSpace, node->dataIndex);
if (entry == NULL) {
uint32_t offset = AddParamNode(workSpace, PARAM_TYPE_INT, name, strlen(name), value, strlen(value));
PARAM_CHECK(offset > 0, return PARAM_CODE_REACHED_MAX, "Failed to allocate name %s", name);
SaveIndex(&node->dataIndex, offset);
}
return 0;
} }
INIT_LOCAL_API void LoadParamAreaSize(void) INIT_LOCAL_API void LoadParamAreaSize(void)
......
...@@ -24,7 +24,7 @@ namespace OHOS { ...@@ -24,7 +24,7 @@ namespace OHOS {
CloseStdout(); CloseStdout();
std::string str(reinterpret_cast<const char*>(data), size); std::string str(reinterpret_cast<const char*>(data), size);
int verbose = atoi(str.c_str()); int verbose = atoi(str.c_str());
SystemDumpParameters(verbose, nullptr); SystemDumpParameters(verbose, -1, nullptr);
return true; return true;
} }
} }
......
...@@ -25,6 +25,7 @@ ohos_shared_library("libparamtestmodule") { ...@@ -25,6 +25,7 @@ ohos_shared_library("libparamtestmodule") {
"//base/startup/init/services/log", "//base/startup/init/services/log",
"//base/startup/init/interfaces/innerkits/include", "//base/startup/init/interfaces/innerkits/include",
"//base/startup/init/services/loopevent/include", "//base/startup/init/services/loopevent/include",
"//base/startup/init/services/param/include",
"//base/startup/init/ueventd/include", "//base/startup/init/ueventd/include",
"//third_party/cJSON", "//third_party/cJSON",
"//third_party/bounds_checking_function/include", "//third_party/bounds_checking_function/include",
......
...@@ -25,6 +25,7 @@ ...@@ -25,6 +25,7 @@
#include "plugin_test.h" #include "plugin_test.h"
#include "service_watcher.h" #include "service_watcher.h"
#include "parameter.h" #include "parameter.h"
#include "param_base.h"
#define MAX_THREAD_NUMBER 100 #define MAX_THREAD_NUMBER 100
#define MAX_NUMBER 10 #define MAX_NUMBER 10
...@@ -63,6 +64,12 @@ static void *CmdReader(void *args) ...@@ -63,6 +64,12 @@ static void *CmdReader(void *args)
static int32_t BShellParamCmdRead(BShellHandle shell, int32_t argc, char *argv[]) static int32_t BShellParamCmdRead(BShellHandle shell, int32_t argc, char *argv[])
{ {
PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter"); PLUGIN_CHECK(argc >= 1, return -1, "Invalid parameter");
if (argc == 1) {
#ifdef PARAM_TEST_PERFORMANCE
TestParameterReaderPerformance();
#endif
return 0;
}
static pthread_t thread = 0; static pthread_t thread = 0;
PLUGIN_LOGV("BShellParamCmdWatch %s, threadId %d", argv[1], thread); PLUGIN_LOGV("BShellParamCmdWatch %s, threadId %d", argv[1], thread);
if (strcmp(argv[1], "start") == 0) { if (strcmp(argv[1], "start") == 0) {
......
...@@ -282,6 +282,7 @@ ohos_unittest("init_unittest") { ...@@ -282,6 +282,7 @@ ohos_unittest("init_unittest") {
"USE_MBEDTLS", "USE_MBEDTLS",
"PARAM_DECODE_GROUPID_FROM_FILE", "PARAM_DECODE_GROUPID_FROM_FILE",
"WORKSPACE_AREA_NEED_MUTEX", "WORKSPACE_AREA_NEED_MUTEX",
"PARAMWORKSPACE_NEED_MUTEX",
"PARAM_SUPPORT_REAL_CHECK", "PARAM_SUPPORT_REAL_CHECK",
"DISABLE_INIT_TWO_STAGES", "DISABLE_INIT_TWO_STAGES",
] ]
......
...@@ -212,7 +212,7 @@ HWTEST_F(ClientUnitTest, TestClient_03, TestSize.Level0) ...@@ -212,7 +212,7 @@ HWTEST_F(ClientUnitTest, TestClient_03, TestSize.Level0)
{ {
// 3 Traversal test // 3 Traversal test
TestParamTraversal(); TestParamTraversal();
SystemDumpParameters(1, NULL); SystemDumpParameters(1, -1, NULL);
} }
HWTEST_F(ClientUnitTest, TestClient_04, TestSize.Level0) HWTEST_F(ClientUnitTest, TestClient_04, TestSize.Level0)
......
...@@ -96,7 +96,7 @@ public: ...@@ -96,7 +96,7 @@ public:
ParamSecurityLabel srclabel = {}; ParamSecurityLabel srclabel = {};
ret = initParamSecurityOps.securityInitLabel(&srclabel, LABEL_INIT_FOR_INIT); ret = initParamSecurityOps.securityInitLabel(&srclabel, LABEL_INIT_FOR_INIT);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = initParamSecurityOps.securityCheckParamPermission(&srclabel, name, mode); ret = initParamSecurityOps.securityCheckParamPermission(TestGetParamLabelIndex(name), &srclabel, name, mode);
initParamSecurityOps.securityFreeLabel(&srclabel); initParamSecurityOps.securityFreeLabel(&srclabel);
return ret; return ret;
} }
......
...@@ -78,6 +78,9 @@ static int TestSetParamCheck(const char *paraName, const char *context, const Sr ...@@ -78,6 +78,9 @@ static int TestSetParamCheck(const char *paraName, const char *context, const Sr
static const char *TestGetParamLabel(const char *paraName) static const char *TestGetParamLabel(const char *paraName)
{ {
BEGET_LOGI("TestGetParamLabel %s", paraName); BEGET_LOGI("TestGetParamLabel %s", paraName);
if (paraName == nullptr) {
return nullptr;
}
for (size_t i = 0; i < ARRAY_LENGTH(selinuxLabels); i++) { for (size_t i = 0; i < ARRAY_LENGTH(selinuxLabels); i++) {
if (strncmp(selinuxLabels[i][0], paraName, strlen(selinuxLabels[i][0])) == 0) { if (strncmp(selinuxLabels[i][0], paraName, strlen(selinuxLabels[i][0])) == 0) {
return selinuxLabels[i][1]; return selinuxLabels[i][1];
...@@ -88,6 +91,18 @@ static const char *TestGetParamLabel(const char *paraName) ...@@ -88,6 +91,18 @@ static const char *TestGetParamLabel(const char *paraName)
return selinuxLabels[code][1]; return selinuxLabels[code][1];
} }
static int32_t TestGetSelinuxLabelIndex(const char *paraName)
{
for (size_t i = 0; i < ARRAY_LENGTH(selinuxLabels); i++) {
if (strncmp(selinuxLabels[i][0], paraName, strlen(selinuxLabels[i][0])) == 0) {
return i;
}
}
int code = TestGenHashCode(paraName);
code = code % (ARRAY_LENGTH(selinuxLabels));
return code;
}
static const char *g_forbidReadParamName[] = { static const char *g_forbidReadParamName[] = {
"ohos.servicectrl.", "ohos.servicectrl.",
// "test.permission.write", // "test.permission.write",
...@@ -122,6 +137,7 @@ static ParamContextsList *TestGetParamList(void) ...@@ -122,6 +137,7 @@ static ParamContextsList *TestGetParamList(void)
BEGET_ERROR_CHECK(head != nullptr, return nullptr, "Failed to alloc ParamContextsList"); BEGET_ERROR_CHECK(head != nullptr, return nullptr, "Failed to alloc ParamContextsList");
head->info.paraName = strdup(selinuxLabels[0][0]); head->info.paraName = strdup(selinuxLabels[0][0]);
head->info.paraContext = strdup(selinuxLabels[0][1]); head->info.paraContext = strdup(selinuxLabels[0][1]);
head->info.index = 0;
head->next = nullptr; head->next = nullptr;
for (size_t i = 1; i < ARRAY_LENGTH(selinuxLabels); i++) { for (size_t i = 1; i < ARRAY_LENGTH(selinuxLabels); i++) {
ParamContextsList *node = (ParamContextsList *)malloc(sizeof(ParamContextsList)); ParamContextsList *node = (ParamContextsList *)malloc(sizeof(ParamContextsList));
...@@ -129,6 +145,7 @@ static ParamContextsList *TestGetParamList(void) ...@@ -129,6 +145,7 @@ static ParamContextsList *TestGetParamList(void)
return nullptr, "Failed to alloc ParamContextsList"); return nullptr, "Failed to alloc ParamContextsList");
node->info.paraName = strdup(selinuxLabels[i][0]); node->info.paraName = strdup(selinuxLabels[i][0]);
node->info.paraContext = strdup(selinuxLabels[i][1]); node->info.paraContext = strdup(selinuxLabels[i][1]);
node->info.index = i;
node->next = head->next; node->next = head->next;
head->next = node; head->next = node;
} }
...@@ -156,6 +173,7 @@ static ParamContextsList *TestGetParamList(void) ...@@ -156,6 +173,7 @@ static ParamContextsList *TestGetParamList(void)
return nullptr, "Failed to alloc ParamContextsList"); return nullptr, "Failed to alloc ParamContextsList");
node->info.paraName = strdup(selinuxLabels[0][0]); node->info.paraName = strdup(selinuxLabels[0][0]);
node->info.paraContext = strdup(selinuxLabels[0][1]); node->info.paraContext = strdup(selinuxLabels[0][1]);
node->info.index = 0;
node->next = head->next; node->next = head->next;
head->next = node; head->next = node;
return head; return head;
...@@ -174,6 +192,7 @@ void TestSetSelinuxOps(void) ...@@ -174,6 +192,7 @@ void TestSetSelinuxOps(void)
selinuxSpace->readParamCheck = TestReadParamCheck; selinuxSpace->readParamCheck = TestReadParamCheck;
selinuxSpace->getParamList = TestGetParamList; selinuxSpace->getParamList = TestGetParamList;
selinuxSpace->destroyParamList = TestDestroyParamList; selinuxSpace->destroyParamList = TestDestroyParamList;
selinuxSpace->getParamLabelIndex = TestGetSelinuxLabelIndex;
#endif #endif
} }
...@@ -511,7 +530,8 @@ void PrepareInitUnitTestEnv(void) ...@@ -511,7 +530,8 @@ void PrepareInitUnitTestEnv(void)
evnOk = 1; evnOk = 1;
} }
int TestCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode) int TestCheckParamPermission(const ParamLabelIndex *labelIndex,
const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
{ {
// DAC_RESULT_FORBIDED // DAC_RESULT_FORBIDED
return g_testPermissionResult; return g_testPermissionResult;
...@@ -531,11 +551,11 @@ void SetStubResult(STUB_TYPE type, int result) ...@@ -531,11 +551,11 @@ void SetStubResult(STUB_TYPE type, int result)
static void TestBeforeInit(void) static void TestBeforeInit(void)
{ {
ParamWorkSpace *paramSpace = GetParamWorkSpace(); ParamWorkSpace *paramSpace = GetParamWorkSpace();
EXPECT_EQ(paramSpace, nullptr); EXPECT_NE(paramSpace, nullptr);
InitParamService(); InitParamService();
CloseParamWorkSpace(); CloseParamWorkSpace();
paramSpace = GetParamWorkSpace(); paramSpace = GetParamWorkSpace();
EXPECT_EQ(paramSpace, nullptr); EXPECT_NE(paramSpace, nullptr);
EnableInitLogFromCmdline(); EnableInitLogFromCmdline();
// test read cmdline // test read cmdline
...@@ -693,6 +713,31 @@ int setfilecon(const char *name, const char *content) ...@@ -693,6 +713,31 @@ int setfilecon(const char *name, const char *content)
g_selinuxOptResult++; g_selinuxOptResult++;
return g_selinuxOptResult % g_testRandom; return g_selinuxOptResult % g_testRandom;
} }
ParamLabelIndex *TestGetParamLabelIndex(const char *name)
{
static ParamLabelIndex labelIndex = {0};
uint32_t index = 0;
ParamWorkSpace *paramWorkspace = GetParamWorkSpace();
if (paramWorkspace == nullptr) {
return &labelIndex;
}
labelIndex.workspace = paramWorkspace->workSpace[0];
#ifdef PARAM_SUPPORT_SELINUX
if (paramWorkspace->selinuxSpace.getParamLabelIndex == nullptr) {
return &labelIndex;
}
index = (uint32_t)paramWorkspace->selinuxSpace.getParamLabelIndex(name) + WORKSPACE_INDEX_BASE;
if (index >= paramWorkspace->maxLabelIndex) {
return &labelIndex;
}
#endif
labelIndex.workspace = paramWorkspace->workSpace[index];
PARAM_CHECK(labelIndex.workspace != NULL, return NULL, "Invalid workSpace");
labelIndex.selinuxLabelIndex = labelIndex.workspace->spaceIndex;
(void)FindTrieNode(paramWorkspace->workSpace[0], name, strlen(name), &labelIndex.dacLabelIndex);
return &labelIndex;
}
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -38,6 +38,7 @@ extern "C" { ...@@ -38,6 +38,7 @@ extern "C" {
typedef struct ParameterNode { typedef struct ParameterNode {
const char *paraName; const char *paraName;
const char *paraContext; const char *paraContext;
int index;
} ParameterNode; } ParameterNode;
typedef struct ParamContextsList { typedef struct ParamContextsList {
...@@ -56,7 +57,8 @@ void PrepareInitUnitTestEnv(void); ...@@ -56,7 +57,8 @@ void PrepareInitUnitTestEnv(void);
void TestSetSelinuxOps(void); void TestSetSelinuxOps(void);
void SetTestPermissionResult(int result); void SetTestPermissionResult(int result);
void TestSetParamCheckResult(const char *prefix, uint16_t mode, int result); void TestSetParamCheckResult(const char *prefix, uint16_t mode, int result);
int TestCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode); int TestCheckParamPermission(const ParamLabelIndex *labelIndex,
const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode);
int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel); int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel);
typedef enum { typedef enum {
...@@ -67,6 +69,8 @@ typedef enum { ...@@ -67,6 +69,8 @@ typedef enum {
} STUB_TYPE; } STUB_TYPE;
void SetStubResult(STUB_TYPE type, int result); void SetStubResult(STUB_TYPE type, int result);
void PrepareCmdLineData(); void PrepareCmdLineData();
ParamLabelIndex *TestGetParamLabelIndex(const char *name);
#ifdef __cplusplus #ifdef __cplusplus
#if __cplusplus #if __cplusplus
} }
......
...@@ -26,6 +26,7 @@ using namespace testing::ext; ...@@ -26,6 +26,7 @@ using namespace testing::ext;
using namespace std; using namespace std;
extern "C" { extern "C" {
int IsWorkSpaceReady(WorkSpace *workSpace);
void ParamWorBaseLog(InitLogLevel logLevel, uint32_t domain, const char *tag, const char *fmt, ...); void ParamWorBaseLog(InitLogLevel logLevel, uint32_t domain, const char *tag, const char *fmt, ...);
static void OnClose(const TaskHandle taskHandle) static void OnClose(const TaskHandle taskHandle)
{ {
...@@ -84,7 +85,7 @@ public: ...@@ -84,7 +85,7 @@ public:
uint32_t labelIndex = 0; uint32_t labelIndex = 0;
SystemWriteParam(name, value); SystemWriteParam(name, value);
// get root // get root
WorkSpace *workspace = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *workspace = GetWorkSpace(WORKSPACE_INDEX_DAC);
(void)FindTrieNode(workspace, name, strlen(name), &labelIndex); (void)FindTrieNode(workspace, name, strlen(name), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex); ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex);
if (node == nullptr) { if (node == nullptr) {
...@@ -109,7 +110,7 @@ public: ...@@ -109,7 +110,7 @@ public:
SystemWriteParam(name, value); SystemWriteParam(name, value);
uint32_t labelIndex = 0; uint32_t labelIndex = 0;
AddSecurityLabel(&auditData); AddSecurityLabel(&auditData);
WorkSpace *workspace = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *workspace = GetWorkSpace(WORKSPACE_INDEX_DAC);
(void)FindTrieNode(workspace, name, strlen(name), &labelIndex); (void)FindTrieNode(workspace, name, strlen(name), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex); ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex);
if (node == nullptr) { if (node == nullptr) {
...@@ -142,7 +143,7 @@ public: ...@@ -142,7 +143,7 @@ public:
AddSecurityLabel(&auditData); AddSecurityLabel(&auditData);
uint32_t labelIndex = 0; uint32_t labelIndex = 0;
WorkSpace *workspace = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *workspace = GetWorkSpace(WORKSPACE_INDEX_DAC);
ParamTrieNode *paramNode = FindTrieNode(workspace, name, strlen(name), &labelIndex); ParamTrieNode *paramNode = FindTrieNode(workspace, name, strlen(name), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex); ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex);
if (paramNode == nullptr || node == nullptr) { if (paramNode == nullptr || node == nullptr) {
...@@ -156,6 +157,7 @@ public: ...@@ -156,6 +157,7 @@ public:
// 添加一个label,完全匹配 // 添加一个label,完全匹配
int TestAddSecurityLabel4() int TestAddSecurityLabel4()
{ {
ResetParamSecurityLabel();
GetParamSecurityLabel()->cred.gid = 9999; // 9999 test gid GetParamSecurityLabel()->cred.gid = 9999; // 9999 test gid
const char *name = "label4.test.aaa.bbb.ccc.dddd.eee"; const char *name = "label4.test.aaa.bbb.ccc.dddd.eee";
const char *value = "2001"; const char *value = "2001";
...@@ -167,7 +169,7 @@ public: ...@@ -167,7 +169,7 @@ public:
SystemWriteParam(name, value); SystemWriteParam(name, value);
uint32_t labelIndex = 0; uint32_t labelIndex = 0;
AddSecurityLabel(&auditData); AddSecurityLabel(&auditData);
WorkSpace *workspace = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *workspace = GetWorkSpace(WORKSPACE_INDEX_DAC);
ParamTrieNode *paramNode = FindTrieNode(workspace, name, strlen(name), &labelIndex); ParamTrieNode *paramNode = FindTrieNode(workspace, name, strlen(name), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex); ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex);
if (paramNode == nullptr || node == nullptr) { if (paramNode == nullptr || node == nullptr) {
...@@ -296,7 +298,7 @@ public: ...@@ -296,7 +298,7 @@ public:
int TestDumpParamMemory() int TestDumpParamMemory()
{ {
SystemDumpParameters(1, NULL); SystemDumpParameters(1, -1, NULL);
return 0; return 0;
} }
}; };
...@@ -407,13 +409,13 @@ HWTEST_F(ParamUnitTest, TestLinuxRWLock, TestSize.Level0) ...@@ -407,13 +409,13 @@ HWTEST_F(ParamUnitTest, TestLinuxRWLock, TestSize.Level0)
HWTEST_F(ParamUnitTest, TestWorkSpace1, TestSize.Level0) HWTEST_F(ParamUnitTest, TestWorkSpace1, TestSize.Level0)
{ {
int ret = AddWorkSpace("test.workspace.1", 0, PARAM_WORKSPACE_DEF); int ret = AddWorkSpace("test.workspace.1", GetWorkSpaceIndex("test.workspace.1"), 0, PARAM_WORKSPACE_DEF);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = AddWorkSpace("test.workspace.2", 0, PARAM_WORKSPACE_DEF); ret = AddWorkSpace("test.workspace.2", GetWorkSpaceIndex("test.workspace.2"), 0, PARAM_WORKSPACE_DEF);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = AddWorkSpace("test.workspace.3", 0, PARAM_WORKSPACE_DEF); ret = AddWorkSpace("test.workspace.3", GetWorkSpaceIndex("test.workspace.3"), 0, PARAM_WORKSPACE_DEF);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
WorkSpace *space = GetWorkSpace("test.workspace.1"); WorkSpace *space = GetWorkSpace(GetWorkSpaceIndex("test.workspace.1"));
EXPECT_NE(space, nullptr); EXPECT_NE(space, nullptr);
CloseWorkSpace(nullptr); CloseWorkSpace(nullptr);
} }
...@@ -429,26 +431,11 @@ HWTEST_F(ParamUnitTest, TestWorkSpace2, TestSize.Level0) ...@@ -429,26 +431,11 @@ HWTEST_F(ParamUnitTest, TestWorkSpace2, TestSize.Level0)
} }
workSpace->flags = 0; workSpace->flags = 0;
workSpace->area = NULL; workSpace->area = NULL;
OH_ListInit(&workSpace->node);
int ret = ParamStrCpy(workSpace->fileName, size, spaceName); int ret = ParamStrCpy(workSpace->fileName, size, spaceName);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
HASHMAPInitNode(&workSpace->hashNode);
CloseWorkSpace(workSpace); CloseWorkSpace(workSpace);
} }
HWTEST_F(ParamUnitTest, TestWorkSpace3, TestSize.Level0)
{
const char *spaceName = "test.workspace3";
int ret = AddWorkSpace(spaceName, 1, PARAM_WORKSPACE_DEF);
#ifdef PARAM_SUPPORT_SELINUX
EXPECT_NE(ret, 0);
#else
EXPECT_EQ(ret, 0);
#endif
HashNode *node = OH_HashMapGet(GetParamWorkSpace()->workSpaceHashHandle, (const void *)spaceName);
EXPECT_EQ(node, nullptr);
}
#if !(defined __LITEOS_A__ || defined __LITEOS_M__) // can not support parameter type #if !(defined __LITEOS_A__ || defined __LITEOS_M__) // can not support parameter type
HWTEST_F(ParamUnitTest, TestParamValueType1, TestSize.Level0) HWTEST_F(ParamUnitTest, TestParamValueType1, TestSize.Level0)
{ {
...@@ -516,9 +503,9 @@ HWTEST_F(ParamUnitTest, TestGetServiceCtlName, TestSize.Level0) ...@@ -516,9 +503,9 @@ HWTEST_F(ParamUnitTest, TestGetServiceCtlName, TestSize.Level0)
HWTEST_F(ParamUnitTest, TestFindTrieNode, TestSize.Level0) HWTEST_F(ParamUnitTest, TestFindTrieNode, TestSize.Level0)
{ {
int ret = AddWorkSpace("test.workspace.1", 0, PARAM_WORKSPACE_DEF); int ret = AddWorkSpace("test.workspace.1", GetWorkSpaceIndex("test.workspace.1"), 0, PARAM_WORKSPACE_DEF);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
WorkSpace *space = GetWorkSpace("test.workspace.1"); WorkSpace *space = GetWorkSpace(GetWorkSpaceIndex("test.workspace.1"));
ASSERT_NE(space, nullptr); ASSERT_NE(space, nullptr);
ParamTrieNode *node = FindTrieNode(nullptr, nullptr, 0, nullptr); ParamTrieNode *node = FindTrieNode(nullptr, nullptr, 0, nullptr);
ASSERT_EQ(node, nullptr); ASSERT_EQ(node, nullptr);
...@@ -633,5 +620,45 @@ HWTEST_F(ParamUnitTest, TestStreamTaskFail, TestSize.Level0) ...@@ -633,5 +620,45 @@ HWTEST_F(ParamUnitTest, TestStreamTaskFail, TestSize.Level0)
ret = ParamTaskSendMsg(GetParamService()->serverTask, nullptr); ret = ParamTaskSendMsg(GetParamService()->serverTask, nullptr);
EXPECT_NE(ret, 0); EXPECT_NE(ret, 0);
} }
HWTEST_F(ParamUnitTest, TestParamCache, TestSize.Level0)
{
const char *name = "test.write.1111111.222222";
CachedHandle cacheHandle = CachedParameterCreate(name, "true");
EXPECT_NE(cacheHandle, nullptr);
const char *value = CachedParameterGet(cacheHandle);
EXPECT_EQ(strcmp(value, "true"), 0);
uint32_t dataIndex = 0;
int ret = WriteParam(name, "false", &dataIndex, 0);
EXPECT_EQ(ret, 0);
value = CachedParameterGet(cacheHandle);
EXPECT_EQ(strcmp(value, "false"), 0);
CachedParameterDestroy(cacheHandle);
// cache 2, for parameter exist
CachedHandle cacheHandle3 = CachedParameterCreate(name, "true");
EXPECT_NE(cacheHandle3, nullptr);
value = CachedParameterGet(cacheHandle3);
EXPECT_EQ(strcmp(value, "false"), 0);
ret = WriteParam(name, "2222222", &dataIndex, 0);
EXPECT_EQ(ret, 0);
value = CachedParameterGet(cacheHandle3);
EXPECT_EQ(strcmp(value, "2222222"), 0);
CachedParameterDestroy(cacheHandle3);
}
#ifdef PARAM_SUPPORT_SELINUX
HWTEST_F(ParamUnitTest, TestInitParameterClient, TestSize.Level0)
{
InitParameterClient();
WorkSpace *workspace = GetWorkSpace(0);
int ret = IsWorkSpaceReady(workspace);
EXPECT_EQ(ret, 0);
ret = IsWorkSpaceReady(NULL);
EXPECT_NE(ret, 0);
workspace = GetWorkSpace(1);
ret = IsWorkSpaceReady(workspace);
EXPECT_EQ(ret, 0);
}
#endif
#endif #endif
} }
...@@ -87,7 +87,7 @@ public: ...@@ -87,7 +87,7 @@ public:
uint32_t labelIndex = 0; uint32_t labelIndex = 0;
SystemWriteParam(name, value); SystemWriteParam(name, value);
// 获取到跟属性 // 获取到跟属性
WorkSpace *workspace = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *workspace = GetWorkSpace(WORKSPACE_INDEX_DAC);
(void)FindTrieNode(workspace, name, strlen(name), &labelIndex); (void)FindTrieNode(workspace, name, strlen(name), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex); ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex);
if (node == nullptr) { if (node == nullptr) {
...@@ -112,7 +112,7 @@ public: ...@@ -112,7 +112,7 @@ public:
SystemWriteParam(name, value); SystemWriteParam(name, value);
uint32_t labelIndex = 0; uint32_t labelIndex = 0;
AddSecurityLabel(&auditData); AddSecurityLabel(&auditData);
WorkSpace *workspace = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *workspace = GetWorkSpace(WORKSPACE_INDEX_DAC);
(void)FindTrieNode(workspace, name, strlen(name), &labelIndex); (void)FindTrieNode(workspace, name, strlen(name), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex); ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex);
if (node == nullptr) { if (node == nullptr) {
...@@ -145,7 +145,7 @@ public: ...@@ -145,7 +145,7 @@ public:
AddSecurityLabel(&auditData); AddSecurityLabel(&auditData);
uint32_t labelIndex = 0; uint32_t labelIndex = 0;
WorkSpace *workspace = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *workspace = GetWorkSpace(WORKSPACE_INDEX_DAC);
ParamTrieNode *paramNode = FindTrieNode(workspace, name, strlen(name), &labelIndex); ParamTrieNode *paramNode = FindTrieNode(workspace, name, strlen(name), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex); ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex);
if (paramNode == nullptr || node == nullptr) { if (paramNode == nullptr || node == nullptr) {
...@@ -170,7 +170,7 @@ public: ...@@ -170,7 +170,7 @@ public:
SystemWriteParam(name, value); SystemWriteParam(name, value);
uint32_t labelIndex = 0; uint32_t labelIndex = 0;
AddSecurityLabel(&auditData); AddSecurityLabel(&auditData);
WorkSpace *workspace = GetWorkSpace(WORKSPACE_NAME_DAC); WorkSpace *workspace = GetWorkSpace(WORKSPACE_INDEX_DAC);
ParamTrieNode *paramNode = FindTrieNode(workspace, name, strlen(name), &labelIndex); ParamTrieNode *paramNode = FindTrieNode(workspace, name, strlen(name), &labelIndex);
ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex); ParamSecurityNode *node = (ParamSecurityNode *)GetTrieNode(workspace, labelIndex);
if (paramNode == nullptr || node == nullptr) { if (paramNode == nullptr || node == nullptr) {
......
...@@ -83,7 +83,8 @@ public: ...@@ -83,7 +83,8 @@ public:
ret = initParamSercurityOps.securityInitLabel(&srclabel, LABEL_INIT_FOR_INIT); ret = initParamSercurityOps.securityInitLabel(&srclabel, LABEL_INIT_FOR_INIT);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = initParamSercurityOps.securityCheckParamPermission(&srclabel, name, DAC_WRITE); ret = initParamSercurityOps.securityCheckParamPermission(
TestGetParamLabelIndex(name), &srclabel, name, DAC_WRITE);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = initParamSercurityOps.securityFreeLabel(&srclabel); ret = initParamSercurityOps.securityFreeLabel(&srclabel);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
...@@ -119,7 +120,8 @@ public: ...@@ -119,7 +120,8 @@ public:
ParamSecurityLabel srclabel = {}; ParamSecurityLabel srclabel = {};
ret = clientParamSercurityOps.securityInitLabel(&srclabel, 0); ret = clientParamSercurityOps.securityInitLabel(&srclabel, 0);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = clientParamSercurityOps.securityCheckParamPermission(&srclabel, name, DAC_WRITE); ret = clientParamSercurityOps.securityCheckParamPermission(
TestGetParamLabelIndex(name), &srclabel, name, DAC_WRITE);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = clientParamSercurityOps.securityFreeLabel(&srclabel); ret = clientParamSercurityOps.securityFreeLabel(&srclabel);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
...@@ -136,17 +138,18 @@ public: ...@@ -136,17 +138,18 @@ public:
ParamSecurityLabel srclabel = {}; ParamSecurityLabel srclabel = {};
ret = clientParamSercurityOps.securityInitLabel(&srclabel, 0); ret = clientParamSercurityOps.securityInitLabel(&srclabel, 0);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = clientParamSercurityOps.securityCheckParamPermission(&srclabel, name, DAC_READ); ret = clientParamSercurityOps.securityCheckParamPermission(
TestGetParamLabelIndex(name), &srclabel, name, DAC_READ);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
ret = clientParamSercurityOps.securityFreeLabel(&srclabel); ret = clientParamSercurityOps.securityFreeLabel(&srclabel);
EXPECT_EQ(ret, 0); EXPECT_EQ(ret, 0);
uint8_t updataMode = GetParamWorkSpace()->ops.updaterMode; uint8_t updateMode = GetParamWorkSpace()->ops.updaterMode;
GetParamWorkSpace()->ops.updaterMode = 1; // 1 test updater mode GetParamWorkSpace()->ops.updaterMode = 1; // 1 test updater mode
RegisterSecuritySelinuxOps(&clientParamSercurityOps, 0); RegisterSecuritySelinuxOps(&clientParamSercurityOps, 0);
if (clientParamSercurityOps.securityCheckParamPermission != nullptr) { if (clientParamSercurityOps.securityCheckParamPermission != nullptr) {
clientParamSercurityOps.securityCheckParamPermission(nullptr, nullptr, 0); clientParamSercurityOps.securityCheckParamPermission(TestGetParamLabelIndex(name), nullptr, nullptr, 0);
} }
GetParamWorkSpace()->ops.updaterMode = updataMode; GetParamWorkSpace()->ops.updaterMode = updateMode;
return 0; return 0;
} }
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册