!2201 需求:系统参数可靠可用能力增强 ——减少DAC空间占用

Merge pull request !2201 from 钟柠/init-group
This commit is contained in:
openharmony_ci 2023-08-30 04:19:22 +00:00 committed by Gitee
commit 56792d2a4c
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
8 changed files with 97 additions and 158 deletions

View File

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

View File

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

View File

@ -124,9 +124,8 @@ static int CheckNeedInit(int onlyRead, const PARAM_WORKSPACE_OPS *ops)
INIT_INNER_API int InitParamWorkSpace(int onlyRead, const PARAM_WORKSPACE_OPS *ops)
{
if (CheckNeedInit(onlyRead, ops) == 0) {
return 0;
}
PARAM_ONLY_CHECK(CheckNeedInit(onlyRead, ops) != 0, return 0);
paramMutexEnvInit();
g_paramWorkSpace.maxLabelIndex = PARAM_DEF_SELINUX_LABEL;
if (!PARAM_TEST_FLAG(g_paramWorkSpace.flags, WORKSPACE_FLAGS_INIT)) {
@ -151,8 +150,6 @@ INIT_INNER_API int InitParamWorkSpace(int onlyRead, const PARAM_WORKSPACE_OPS *o
PARAM_CHECK(ret == 0, return -1, "Failed to add dac workspace");
#endif
if (onlyRead == 0) {
// load user info for dac
LoadGroupUser();
// add default dac policy
ParamAuditData auditData = {0};
auditData.name = "#";
@ -160,6 +157,8 @@ INIT_INNER_API int InitParamWorkSpace(int onlyRead, const PARAM_WORKSPACE_OPS *o
auditData.dacData.uid = DAC_DEFAULT_USER;
auditData.dacData.mode = DAC_DEFAULT_MODE; // 0774 default mode
auditData.dacData.paramType = PARAM_TYPE_STRING;
auditData.memberNum = 1;
auditData.members[0] = DAC_DEFAULT_GROUP;
#ifdef PARAM_SUPPORT_SELINUX
auditData.selinuxIndex = INVALID_SELINUX_INDEX;
#endif
@ -364,14 +363,12 @@ STATIC_INLINE int ReadParamWithCheck(WorkSpace **workspace, const char *name, ui
return ret;
}
static int CheckUserInGroup(WorkSpace *space, gid_t groupId, uid_t uid)
static int CheckUserInGroup(WorkSpace *space, const ParamSecurityNode *node, uid_t uid)
{
char buffer[USER_BUFFER_LEN] = {0};
int ret = PARAM_SPRINTF(buffer, sizeof(buffer), GROUP_FORMAT, groupId, uid);
PARAM_CHECK(ret >= 0, return -1, "Failed to format name for "GROUP_FORMAT, groupId, uid);
ParamNode *node = GetParamNode(WORKSPACE_INDEX_BASE, buffer);
if (node != NULL) {
return 0;
for (uint32_t i = 0; i < node->memberNum; i++) {
if (node->members[i] == uid) {
return 0;
}
}
return -1;
}
@ -436,7 +433,7 @@ STATIC_INLINE int DacCheckParamPermission(const ParamLabelIndex *labelIndex,
return DAC_RESULT_PERMISSION;
}
// 4, check user in group
if (CheckUserInGroup(space, node->gid, srcLabel->cred.uid) == 0) {
if (CheckUserInGroup(space, node, srcLabel->cred.uid) == 0) {
localMode = (mode & (DAC_READ | DAC_WRITE | DAC_WATCH)) >> DAC_GROUP_START;
if ((node->mode & localMode) != 0) {
return DAC_RESULT_PERMISSION;

View File

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

View File

@ -87,6 +87,8 @@ typedef struct {
uint16_t mode;
uint8_t type;
uint8_t length;
uint32_t memberNum;
uid_t members[0];
} ParamSecurityNode;
typedef struct {

View File

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

View File

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

View File

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