decode group by file

Signed-off-by: cheng_jinsong <chengjinsong2@huawei.com>
This commit is contained in:
cheng_jinsong 2022-09-27 15:29:31 +08:00
parent 0e7ea05c44
commit d3bbb380ec
15 changed files with 181 additions and 76 deletions

View File

@ -84,7 +84,7 @@ huks_server:x:3510:
cert_manager_server:x:3515:
dms:x:5522:
foundation:x:5523:
quickfixserver:x:5524;
quickfixserver:x:5524:
samgr:x:5555:
update:x:6666:
charger:x:6667:

View File

@ -123,7 +123,7 @@ int PluginExecCmd(const char *name, int argc, const char **argv)
return -1;
}
PluginCmd *cmd = groupNode->data.cmd;
INIT_LOGI("PluginExecCmd index %s", cmd->name);
INIT_LOGV("PluginExecCmd index %s", cmd->name);
int ret = 0;
ListNode *node = cmd->cmdExecutor.next;
while (node != &cmd->cmdExecutor) {

View File

@ -28,8 +28,11 @@
#define USER_BUFFER_LEN 64
#define MAX_BUF_SIZE 1024
#define GROUP_FORMAT "const.group"
#define INVALID_MODE 0550
#define GROUP_FILE_PATH "/etc/group"
#define OCT_BASE 8
#define INVALID_UID(uid) ((uid) == (uid_t)-1)
static void GetUserIdByName(uid_t *uid, const char *name, uint32_t nameLen)
{
*uid = -1;
@ -210,7 +213,6 @@ static int CheckFilePermission(const ParamSecurityLabel *localLabel, const char
static int CheckUserInGroup(WorkSpace *space, gid_t groupId, uid_t uid)
{
#ifdef __MUSL__
char buffer[USER_BUFFER_LEN] = {0};
uint32_t labelIndex = 0;
int ret = ParamSprintf(buffer, sizeof(buffer), "%s.%d.%d", GROUP_FORMAT, groupId, uid);
@ -218,14 +220,11 @@ static int CheckUserInGroup(WorkSpace *space, gid_t groupId, uid_t 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, groupId, uid);
PARAM_LOGV("CheckUserInGroup %s groupid %d uid %d", buffer, node->gid, node->uid);
if (node->gid == groupId && node->uid == uid) {
return 0;
}
return -1;
#else
return 0;
#endif
}
static int DacCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode)
@ -265,9 +264,6 @@ static int DacCheckParamPermission(const ParamSecurityLabel *srcLabel, const cha
PARAM_LOGW("Cfg label %d gid:%d uid:%d mode 0%o ", labelIndex, node->gid, node->uid, node->mode);
#ifndef STARTUP_INIT_TEST
ret = DAC_RESULT_PERMISSION;
#endif
#ifndef __MUSL__ // for wgr, return permission
ret = DAC_RESULT_PERMISSION;
#endif
}
return ret;
@ -288,45 +284,136 @@ INIT_LOCAL_API int RegisterSecurityDacOps(ParamSecurityOps *ops, int isInit)
return ret;
}
static void AddGroupUser(unsigned int uid, unsigned int gid, int mode, const char *format)
static void AddGroupUser(const char *userName, gid_t gid)
{
if (userName == NULL || strlen(userName) == 0) {
return;
}
uid_t uid = 0;
GetUserIdByName(&uid, userName, strlen(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;
}
ParamAuditData auditData = {0};
char buffer[USER_BUFFER_LEN] = {0};
int ret = ParamSprintf(buffer, sizeof(buffer), "%s.%u.%u", format, gid, uid);
PARAM_CHECK(ret >= 0, return, "Failed to format name for %s.%d.%d", format, gid, uid);
int ret = ParamSprintf(buffer, sizeof(buffer), "%s.%u.%u", GROUP_FORMAT, gid, uid);
PARAM_CHECK(ret >= 0, return, "Failed to format name for %d.%d", gid, uid);
auditData.name = buffer;
auditData.dacData.uid = uid;
auditData.dacData.gid = gid;
auditData.dacData.mode = mode;
auditData.dacData.mode = INVALID_MODE;
AddSecurityLabel(&auditData);
}
INIT_LOCAL_API void LoadGroupUser(void)
#ifdef PARAM_DECODE_GROUPID_FROM_FILE
static char *UserNameTrim(char *str)
{
#ifndef __MUSL__
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);
// skip x
(void)strtok(NULL, ":");
char *strGid = strtok(NULL, ":");
strGid = UserNameTrim(strGid);
PARAM_CHECK(strGid != NULL, continue, "Invalid gid %s", buff);
errno = 0;
gid_t gid = (gid_t)strtoul(strGid, 0, 10); // 10 base
PARAM_CHECK(errno == 0, continue, "Invalid gid %s", strGid);
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;
#endif
PARAM_LOGV("LoadGroupUser ");
uid_t uid = 0;
}
#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
GetUserIdByName(&uid, data->gr_name, strlen(data->gr_name));
PARAM_LOGV("LoadGroupUser %s gid %d uid %d", data->gr_name, data->gr_gid, uid);
AddGroupUser(uid, data->gr_gid, 0550, GROUP_FORMAT); // 0550 read and watch
AddGroupUser(data->gr_name, data->gr_gid);
continue;
}
int index = 0;
while (data->gr_mem[index]) { // user in this group
GetUserIdByName(&uid, data->gr_mem[index], strlen(data->gr_mem[index]));
PARAM_LOGV("LoadGroupUser %s gid %d uid %d user %s", data->gr_name, data->gr_gid, uid, data->gr_mem[index]);
AddGroupUser(uid, data->gr_gid, 0550, GROUP_FORMAT); // 0550 read and watch
AddGroupUser(data->gr_mem[index], data->gr_gid);
index++;
}
}
PARAM_LOGV("LoadGroupUser getgrent fail errnor %d ", errno);
endgrent();
}
#endif
INIT_LOCAL_API void LoadGroupUser(void)
{
PARAM_LOGV("LoadGroupUser ");
LoadGroupUser_();
}

View File

@ -102,7 +102,10 @@ if (defined(ohos_lite)) {
cflags = [ "-fPIC" ]
include_dirs = base_include_dirs
public_configs = [ ":exported_header_files" ]
defines = [ "_GNU_SOURCE" ]
defines = [
"_GNU_SOURCE",
"PARAM_DECODE_GROUPID_FROM_FILE",
]
deps = []
if (use_musl) {

View File

@ -531,8 +531,8 @@ INIT_LOCAL_API int CheckParamPermission(const ParamSecurityLabel *srcLabel, cons
ParamWorkSpace *paramSpace = GetParamWorkSpace();
PARAM_CHECK(paramSpace != NULL, return DAC_RESULT_FORBIDED, "Invalid workspace");
int ret = DAC_RESULT_PERMISSION;
PARAM_LOGV("CheckParamPermission mode 0x%x name: %s uid:%d pid:%d",
mode, name, (int)srcLabel->cred.uid, (int)srcLabel->cred.pid);
PARAM_LOGV("CheckParamPermission mode 0x%x name: %s uid:%d gid:%d pid:%d",
mode, name, (int)srcLabel->cred.uid, (int)srcLabel->cred.gid, (int)srcLabel->cred.pid);
// for root, all permission, but for appspawn must to check
if (srcLabel->cred.uid == 0 && srcLabel->cred.pid == 1) {
return DAC_RESULT_PERMISSION;

View File

@ -67,7 +67,7 @@ extern "C" {
#define DAC_DEFAULT_MODE 0774
#define PARAM_WORKSPACE_DEF (1024 * 30)
#endif
#define DAC_DEFAULT_GROUP 2000
#define DAC_DEFAULT_GROUP 0
#define DAC_DEFAULT_USER 0
#endif

View File

@ -241,6 +241,7 @@ ohos_unittest("init_unittest") {
"_GNU_SOURCE",
"PARAM_SUPPORT_TRIGGER",
"USE_MBEDTLS",
"PARAM_DECODE_GROUPID_FROM_FILE",
]
defines += [ "_GNU_SOURCE" ]

View File

@ -124,7 +124,7 @@ HWTEST_F(DacUnitTest, TestDacCheckFilePermission, TestSize.Level0)
DacUnitTest test;
test.TestDacCheckFilePermission(STARTUP_INIT_UT_PATH "/trigger_test.cfg");
}
#ifdef __MUSL__
HWTEST_F(DacUnitTest, TestDacCheckUserParaPermission, TestSize.Level0)
{
// 相同用户
@ -247,7 +247,7 @@ HWTEST_F(DacUnitTest, TestDacCheckOtherParaPermission, TestSize.Level0)
ret = test.TestDacCheckParaPermission("test.permission.watch.aaa", &dacData, DAC_WATCH);
EXPECT_EQ(ret, 0);
}
#endif
HWTEST_F(DacUnitTest, TestClientDacCheckFilePermission, TestSize.Level0)
{
DacUnitTest test;

View File

@ -55,7 +55,7 @@ static int TestGenHashCode(const char *buff)
static void TestSetSelinuxLogCallback(void) {}
static const char *forbitWriteParamName[] = {
static const char *forbidWriteParamName[] = {
"ohos.servicectrl.",
"test.permission.read",
"test.persmission.watch"
@ -64,9 +64,9 @@ static const char *forbitWriteParamName[] = {
static int TestSetParamCheck(const char *paraName, const char *context, const SrcInfo *info)
{
// forbid to read ohos.servicectrl.
for (size_t i = 0; i < ARRAY_LENGTH(forbitWriteParamName); i++) {
if (strncmp(paraName, forbitWriteParamName[i], strlen(forbitWriteParamName[i])) == 0) {
return 1;
for (size_t i = 0; i < ARRAY_LENGTH(forbidWriteParamName); i++) {
if (strncmp(paraName, forbidWriteParamName[i], strlen(forbidWriteParamName[i])) == 0) {
return g_testPermissionResult;
}
}
return g_testPermissionResult;
@ -147,6 +147,18 @@ void TestSetSelinuxOps(void)
selinuxSpace->destroyParamList = TestDestroyParamList;
#endif
}
void TestSetParamCheckResult(const char *prefix, uint16_t mode, int result)
{
ParamAuditData auditData = {};
auditData.name = prefix;
auditData.dacData.gid = 202; // 202 test dac gid
auditData.dacData.uid = 202; // 202 test dac uid
auditData.dacData.mode = mode;
AddSecurityLabel(&auditData);
SetTestPermissionResult(result);
}
static void CreateTestFile(const char *fileName, const char *data)
{
CheckAndCreateDir(fileName);

View File

@ -33,7 +33,7 @@ extern "C" {
void PrepareInitUnitTestEnv(void);
void TestSetSelinuxOps(void);
void SetTestPermissionResult(int result);
void TestSetParamCheckResult(const char *prefix, uint16_t mode, int result);
int TestCheckParamPermission(const ParamSecurityLabel *srcLabel, const char *name, uint32_t mode);
int TestFreeLocalSecurityLabel(ParamSecurityLabel *srcLabel);

View File

@ -445,27 +445,17 @@ public:
return 0;
}
int TestServiceCtrl(const char *serviceName, int mode)
int TestServiceCtrl(const char *serviceName, uint16_t mode)
{
// service forbid
ParamAuditData auditData = {};
auditData.name = "ohos.servicectrl.";
auditData.dacData.gid = 202; // 202 test dac gid
auditData.dacData.uid = 202; // 202 test dac uid
auditData.dacData.mode = mode;
AddSecurityLabel(&auditData);
TestSetParamCheckResult("ohos.servicectrl.", mode, 1);
return SystemWriteParam("ohos.ctl.start", serviceName);
}
int TestPowerCtrl(const char *reboot, int mode)
int TestPowerCtrl(const char *reboot, uint16_t mode)
{
// service forbid
ParamAuditData auditData = {};
auditData.name = "ohos.servicectrl.reboot";
auditData.dacData.gid = 202; // 202 test dac gid
auditData.dacData.uid = 202; // 202 test dac uid
auditData.dacData.mode = mode;
AddSecurityLabel(&auditData);
TestSetParamCheckResult("ohos.servicectrl.reboot", mode, 1);
return SystemWriteParam("ohos.startup.powerctrl", reboot);
}
};
@ -528,9 +518,7 @@ HWTEST_F(ParamServiceUnitTest, TestServiceCtrl, TestSize.Level0)
{
ParamServiceUnitTest test;
int ret = test.TestServiceCtrl("server1", 0770);
#ifdef __MUSL__
EXPECT_NE(ret, 0);
#endif
#ifdef PARAM_SUPPORT_SELINUX
// selinux forbid
ret = test.TestServiceCtrl("server2", 0772);
@ -543,36 +531,29 @@ HWTEST_F(ParamServiceUnitTest, TestPowerCtrl, TestSize.Level0)
{
ParamServiceUnitTest test;
int ret = test.TestPowerCtrl("reboot,shutdown", 0770);
#ifdef __MUSL__
EXPECT_NE(ret, 0);
#endif
#ifdef PARAM_SUPPORT_SELINUX
ret = test.TestPowerCtrl("reboot,shutdown", 0772);
// selinux forbid
EXPECT_NE(ret, 0);
#endif
ret = test.TestPowerCtrl("reboot,updater", 0770);
#ifdef __MUSL__
EXPECT_NE(ret, 0);
#endif
#ifdef PARAM_SUPPORT_SELINUX
ret = test.TestPowerCtrl("reboot,updater", 0772);
// selinux forbid
EXPECT_NE(ret, 0);
#endif
ret = test.TestPowerCtrl("reboot,flash", 0770);
#ifdef __MUSL__
ret = test.TestPowerCtrl("reboot,flashd", 0770);
EXPECT_NE(ret, 0);
#endif
#ifdef PARAM_SUPPORT_SELINUX
ret = test.TestPowerCtrl("reboot,flash", 0772);
ret = test.TestPowerCtrl("reboot,flashd", 0772);
// selinux forbid
EXPECT_NE(ret, 0);
#endif
ret = test.TestPowerCtrl("reboot", 0770);
#ifdef __MUSL__
EXPECT_NE(ret, 0);
#endif
#ifdef PARAM_SUPPORT_SELINUX
ret = test.TestPowerCtrl("reboot", 0772);
// selinux forbid

View File

@ -29,7 +29,10 @@ public:
SelinuxUnitTest() {}
virtual ~SelinuxUnitTest() {}
void SetUp() {}
void SetUp()
{
SetTestPermissionResult(0);
}
void TearDown() {}
void TestBody() {}

View File

@ -68,7 +68,10 @@ public:
TriggerUnitTest() {}
virtual ~TriggerUnitTest() {}
void SetUp() {}
void SetUp()
{
SetTestPermissionResult(0);
}
void TearDown() {}
void TestBody() {}

View File

@ -22,6 +22,7 @@
#include "message_parcel.h"
#include "parameter.h"
#include "param_manager.h"
#include "param_stub.h"
#include "param_utils.h"
#include "system_ability_definition.h"
#include "watcher.h"
@ -53,6 +54,7 @@ public:
GetParamSecurityLabel()->cred.uid = 1000; // 1000 test uid
GetParamSecurityLabel()->cred.gid = 1000; // 1000 test gid
}
SetTestPermissionResult(0);
}
void TearDown() {}
void TestBody() {}
@ -60,30 +62,39 @@ public:
int TestAddWatcher()
{
size_t index = 1;
int ret = SystemWatchParameter("test.permission.watcher.test1", TestParameterChange, (void *)index);
int ret = SystemWatchParameter("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0);
ret = SystemWatchParameter("test.permission.watcher.test1*", TestParameterChange, (void *)index);
ret = SystemWatchParameter("test.permission.watcher.test1*",
TestParameterChange,reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0);
// repeat add, return fail
ret = SystemWatchParameter("test.permission.watcher.test1", TestParameterChange, (void *)index);
ret = SystemWatchParameter("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_NE(ret, 0);
index++;
ret = SystemWatchParameter("test.permission.watcher.test1", TestParameterChange, (void *)index);
ret = SystemWatchParameter("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0);
index++;
ret = SystemWatchParameter("test.permission.watcher.test1", TestParameterChange, (void *)index);
ret = SystemWatchParameter("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0);
// delete
ret = RemoveParameterWatcher("test.permission.watcher.test1", TestParameterChange, (void *)index);
ret = RemoveParameterWatcher("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0);
index--;
ret = RemoveParameterWatcher("test.permission.watcher.test1", TestParameterChange, (void *)index);
ret = RemoveParameterWatcher("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0);
index--;
ret = RemoveParameterWatcher("test.permission.watcher.test1", TestParameterChange, (void *)index);
ret = RemoveParameterWatcher("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0);
ret = RemoveParameterWatcher("test.permission.watcher.test1", TestParameterChange, (void *)index);
ret = RemoveParameterWatcher("test.permission.watcher.test1",
TestParameterChange, reinterpret_cast<void *>(index));
EXPECT_EQ(ret, 0);
// 非法

View File

@ -20,6 +20,7 @@
#include "parameter.h"
#include "sysparam_errno.h"
#include "param_comm.h"
#include "param_stub.h"
#include "param_wrapper.h"
#include "sysversion.h"
@ -32,7 +33,10 @@ class SysparaUnitTest : public testing::Test {
public:
static void SetUpTestCase() {}
static void TearDownTestCase() {}
void SetUp() {}
void SetUp()
{
SetTestPermissionResult(0);
}
void TearDown() {}
};