mirror of
https://gitee.com/openharmony/startup_init
synced 2024-11-24 00:30:12 +00:00
!2201 需求:系统参数可靠可用能力增强 ——减少DAC空间占用
Merge pull request !2201 from 钟柠/init-group
This commit is contained in:
commit
56792d2a4c
@ -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_();
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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++;
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -81,7 +81,3 @@ INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit)
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
INIT_LOCAL_API void LoadGroupUser(void)
|
||||
{
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user