mirror of
https://gitee.com/openharmony/startup_init
synced 2024-11-24 08:39:46 +00:00
init: support selinux
此提交使 init 进程有支持 SELinux 的能力。 1. 启动时加载策略并根据策略文件设置进程安全上下文 2. 根据配置文件中的 secon 字段的值设置进程的安全上下文 仅在编译时有宏定义 WITH_SELINUX 时会将此功能引入,而仅在 BUILD.gn 中编译 L2 系统(ohos_executable("init"))时会定义宏 WITH_SELINUX ,因此不影响 L2 以下的系统。 services/BUILD.gn 编译配置,编译此功能时定义宏 -DWITH_SELINUX 并链接到库 libload_policy 、 librestorecon 、 libselinux 。 services/init/standard/init.c 启动时加载策略并根据策略文件设置进程安全上下文。调用接口 load_policy 和 restorencon 。 services/init/include/init_service.h 结构体 Service 中增加了成员字符数组 secon 对应配置文件的新字段 secon 。 services/include/param/init_selinux_param.h 定义了 SELinux 功能需要使用的宏。 services/init/init_service_manager.c 将配置文件的字段 secon 读到内存中。 services/init/standard/init_service.c 根据内存中读到的每个服务的 secon 字段,设置该服务进程的安全上下文。 Signed-off-by: Qin Fandong <qinfd@superred.com.cn>
This commit is contained in:
parent
93c3e2640f
commit
55582482ab
1
OAT.xml
1
OAT.xml
@ -22,6 +22,7 @@
|
||||
<licensefile></licensefile>
|
||||
<policylist>
|
||||
<policy name="projectPolicy" desc="">
|
||||
<policyitem type="copyright" name="北京万里红科技有限公司" path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc=""/>
|
||||
<!--policyitem type="compatibility" name="GPL-2.0+" path="abc/.*" desc="Process that runs independently, invoked by the X process."/-->
|
||||
<!--policyitem type="license" name="LGPL" path="abc/.*" desc="Dynamically linked by module X"/-->
|
||||
<!--policyitem type="copyright" name="xxx" path="abc/.*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Developed by X Company"/-->
|
||||
|
@ -75,6 +75,7 @@ The format and content of the **init.cfg** file are as follows:
|
||||
"path" : "/bin/process1",
|
||||
"uid" : 1,
|
||||
"gid" : 1,
|
||||
"secon" : "u:r:untrusted_app:s0",
|
||||
"once" : 0,
|
||||
"importance" : 1,
|
||||
"caps" : [0, 1, 2, 5]
|
||||
@ -83,6 +84,7 @@ The format and content of the **init.cfg** file are as follows:
|
||||
"path" : "/bin/process2",
|
||||
"uid" : 2,
|
||||
"gid" : 2,
|
||||
"secon" : "u:r:untrusted_app:s0",
|
||||
"once" : 1,
|
||||
"importance" : 0,
|
||||
"caps" : []
|
||||
@ -215,6 +217,11 @@ A single job can hold a maximum of 30 commands \(only **start**, **mkdir**, *
|
||||
<td class="cellrowborder" valign="top" width="89.63%" headers="mcps1.2.3.1.2 "><p id="p12738691479"><a name="p12738691479"></a><a name="p12738691479"></a>Group ID (GID) of the current service process.</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row127381591693"><td class="cellrowborder" valign="top" width="10.37%" headers="mcps1.2.3.1.1 "><p id="p47388919793"><a name="p47388919793"></a><a name="p47388919715"></a>secon</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="89.63%" headers="mcps1.2.3.1.2 "><p id="p12738691493"><a name="p12738691493"></a><a name="p12738691493"></a>Security context of the current service process (no need to set currently).</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row188301014171116"><td class="cellrowborder" valign="top" width="10.37%" headers="mcps1.2.3.1.1 "><p id="p183112146115"><a name="p183112146115"></a><a name="p183112146115"></a>once</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="89.63%" headers="mcps1.2.3.1.2 "><p id="p18548317195715"><a name="p18548317195715"></a><a name="p18548317195715"></a>Whether the current service process is a one-off process.</p>
|
||||
|
@ -75,6 +75,7 @@ init将系统启动分为三个阶段:
|
||||
"path" : "/bin/process1",
|
||||
"uid" : 1,
|
||||
"gid" : 1,
|
||||
"secon" : "u:r:untrusted_app:s0",
|
||||
"once" : 0,
|
||||
"importance" : 1,
|
||||
"caps" : [0, 1, 2, 5]
|
||||
@ -83,6 +84,7 @@ init将系统启动分为三个阶段:
|
||||
"path" : "/bin/process2",
|
||||
"uid" : 2,
|
||||
"gid" : 2,
|
||||
"secon" : "u:r:untrusted_app:s0",
|
||||
"once" : 1,
|
||||
"importance" : 0,
|
||||
"caps" : []
|
||||
@ -215,6 +217,11 @@ init将系统启动分为三个阶段:
|
||||
<td class="cellrowborder" valign="top" width="89.63%" headers="mcps1.2.3.1.2 "><p id="p12738691479"><a name="p12738691479"></a><a name="p12738691479"></a>当前服务进程的gid值。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row127381591693"><td class="cellrowborder" valign="top" width="10.37%" headers="mcps1.2.3.1.1 "><p id="p47388919793"><a name="p47388919793"></a><a name="p47388919715"></a>secon</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="89.63%" headers="mcps1.2.3.1.2 "><p id="p12738691493"><a name="p12738691493"></a><a name="p12738691493"></a>当前服务进程的安全上下文(当前不需要设置该字段)。</p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr id="row188301014171116"><td class="cellrowborder" valign="top" width="10.37%" headers="mcps1.2.3.1.1 "><p id="p183112146115"><a name="p183112146115"></a><a name="p183112146115"></a>once</p>
|
||||
</td>
|
||||
<td class="cellrowborder" valign="top" width="89.63%" headers="mcps1.2.3.1.2 "><p id="p18548317195715"><a name="p18548317195715"></a><a name="p18548317195715"></a>当前服务进程是否为一次性进程:</p>
|
||||
|
@ -127,6 +127,8 @@ if (defined(ohos_lite)) {
|
||||
"//third_party/bounds_checking_function:libsec_static",
|
||||
"//third_party/cJSON:cjson_static",
|
||||
]
|
||||
cflags = []
|
||||
|
||||
if (use_musl) {
|
||||
deps += [
|
||||
"//third_party/mksh:sh",
|
||||
@ -134,6 +136,19 @@ if (defined(ohos_lite)) {
|
||||
]
|
||||
}
|
||||
|
||||
if (build_selinux) {
|
||||
include_dirs += [
|
||||
"//third_party/selinux/libselinux/include/",
|
||||
"//base/security/selinux/interfaces/policycoreutils/include/",
|
||||
]
|
||||
deps += [
|
||||
"//base/security/selinux:libload_policy",
|
||||
"//base/security/selinux:librestorecon",
|
||||
"//third_party/selinux:libselinux",
|
||||
]
|
||||
cflags += [ "-DWITH_SELINUX" ]
|
||||
}
|
||||
|
||||
if (disable_init_two_stages) {
|
||||
defines = [ "DISABLE_INIT_TWO_STAGES" ]
|
||||
}
|
||||
|
35
services/include/param/init_selinux_param.h
Normal file
35
services/include/param/init_selinux_param.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* Copyright (c) 2021 北京万里红科技有限公司
|
||||
*
|
||||
* 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_INIT_SELINUX_PARAM_H
|
||||
#define BASE_STARTUP_INIT_SELINUX_PARAM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
# if __cplusplus
|
||||
extern "C" {
|
||||
# endif // __cplusplus
|
||||
#endif // __cplusplus
|
||||
|
||||
# define SECON_STR_IN_CFG ("secon")
|
||||
// https://github.com/xelerance/Openswan/blob/86dff2b/include/pluto/state.h#L222
|
||||
# define MAX_SECON_LEN (257)
|
||||
|
||||
#ifdef __cplusplus
|
||||
# if __cplusplus
|
||||
}
|
||||
# endif // __cplusplus
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif // BASE_STARTUP_INIT_SELINUX_PARAM_H
|
@ -19,6 +19,9 @@
|
||||
#include "cJSON.h"
|
||||
#include "init_cmds.h"
|
||||
#include "init_service_socket.h"
|
||||
#ifdef WITH_SELINUX
|
||||
# include "init_selinux_param.h"
|
||||
#endif // WITH_SELINUX
|
||||
#include "list.h"
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
@ -68,6 +71,9 @@ typedef struct {
|
||||
typedef struct {
|
||||
ListNode node;
|
||||
char name[MAX_SERVICE_NAME + 1];
|
||||
#ifdef WITH_SELINUX
|
||||
char secon[MAX_SECON_LEN];
|
||||
#endif // WITH_SELINUX
|
||||
int pid;
|
||||
int crashCnt;
|
||||
time_t firstCrashTime;
|
||||
|
@ -37,6 +37,11 @@
|
||||
#include "init_utils.h"
|
||||
#include "securec.h"
|
||||
|
||||
#ifdef WITH_SELINUX
|
||||
# include "init_selinux_param.h"
|
||||
# include <selinux/selinux.h>
|
||||
#endif // WITH_SELINUX
|
||||
|
||||
#ifndef TIOCSCTTY
|
||||
#define TIOCSCTTY 0x540E
|
||||
#endif
|
||||
@ -171,6 +176,19 @@ static int WritePid(const Service *service)
|
||||
return SERVICE_SUCCESS;
|
||||
}
|
||||
|
||||
void SetSecon(Service * service)
|
||||
{
|
||||
#ifdef WITH_SELINUX
|
||||
if (*(service->secon)) {
|
||||
if (setexeccon(service->secon) < 0) {
|
||||
INIT_LOGE("failed to set service %s's secon (%s).", service->name, service->secon);
|
||||
} else {
|
||||
INIT_LOGI("service %s secon set to %s.", service->name, service->secon);
|
||||
}
|
||||
}
|
||||
#endif // WITH_SELINUX
|
||||
}
|
||||
|
||||
int ServiceStart(Service *service)
|
||||
{
|
||||
INIT_ERROR_CHECK(service != NULL, return SERVICE_FAILURE, "start service failed! null ptr.");
|
||||
@ -208,6 +226,7 @@ int ServiceStart(Service *service)
|
||||
INIT_LOGE("service %s exit! write pid failed!", service->name);
|
||||
_exit(PROCESS_EXIT_CODE);
|
||||
}
|
||||
SetSecon(service);
|
||||
ServiceExec(service);
|
||||
_exit(PROCESS_EXIT_CODE);
|
||||
} else if (pid < 0) {
|
||||
|
@ -30,6 +30,9 @@
|
||||
#include "init_service_socket.h"
|
||||
#include "init_utils.h"
|
||||
#include "securec.h"
|
||||
#ifdef WITH_SELINUX
|
||||
# include "init_selinux_param.h"
|
||||
#endif // WITH_SELINUX
|
||||
|
||||
// All serivce processes that init will fork+exec.
|
||||
static ServiceSpace g_serviceSpace = { { &g_serviceSpace.services, &g_serviceSpace.services }, 0 };
|
||||
@ -398,7 +401,10 @@ static int CheckServiceKeyName(const cJSON *curService)
|
||||
{
|
||||
char *cfgServiceKeyList[] = {
|
||||
"name", "path", "uid", "gid", "once", "importance", "caps", "disabled",
|
||||
"writepid", "critical", "socket", "console", "dynamic"
|
||||
"writepid", "critical", "socket", "console", "dynamic",
|
||||
#ifdef WITH_SELINUX
|
||||
SECON_STR_IN_CFG,
|
||||
#endif // WITH_SELINUX
|
||||
};
|
||||
if (curService == NULL) {
|
||||
return SERVICE_FAILURE;
|
||||
@ -432,6 +438,10 @@ static int ParseOneService(const cJSON *curItem, Service *service)
|
||||
}
|
||||
int ret = GetStringItem(curItem, "name", service->name, MAX_SERVICE_NAME);
|
||||
INIT_ERROR_CHECK(ret == 0, return SERVICE_FAILURE, "Failed to get service name");
|
||||
#ifdef WITH_SELINUX
|
||||
ret = GetStringItem(curItem, SECON_STR_IN_CFG, service->secon, MAX_SECON_LEN);
|
||||
INIT_CHECK_ONLY_ELOG(ret == 0, "GetServiceSecon %s section not found, skip", SECON_STR_IN_CFG);
|
||||
#endif // WITH_SELINUX
|
||||
ret = GetServiceArgs(curItem, "path", MAX_PATH_ARGS_CNT, &service->pathArgs);
|
||||
INIT_ERROR_CHECK(ret == 0, return SERVICE_FAILURE, "Failed to get path for service %s", service->name);
|
||||
if ((service->pathArgs.count > 0) && IsForbidden(service->pathArgs.argv[0])) {
|
||||
|
@ -29,6 +29,9 @@
|
||||
#include "init_utils.h"
|
||||
#include "securec.h"
|
||||
#include "switch_root.h"
|
||||
#ifdef WITH_SELINUX
|
||||
# include <policycoreutils.h>
|
||||
#endif // WITH_SELINUX
|
||||
|
||||
void SystemInit(void)
|
||||
{
|
||||
@ -120,6 +123,23 @@ void SystemPrepare(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
void SystemLoadSelinux(void)
|
||||
{
|
||||
#ifdef WITH_SELINUX
|
||||
// load selinux policy and context
|
||||
if (load_policy() < 0) {
|
||||
INIT_LOGE("main, load_policy failed.");
|
||||
} else {
|
||||
INIT_LOGI("main, load_policy success.");
|
||||
}
|
||||
if (restorecon() < 0) {
|
||||
INIT_LOGE("main, restorecon failed.");
|
||||
} else {
|
||||
INIT_LOGI("main, restorecon success.");
|
||||
}
|
||||
#endif // WITH_SELINUX
|
||||
}
|
||||
|
||||
void SystemConfig(void)
|
||||
{
|
||||
InitParamService();
|
||||
@ -141,6 +161,9 @@ void SystemConfig(void)
|
||||
PostTrigger(EVENT_TRIGGER_BOOT, "pre-init", strlen("pre-init"));
|
||||
PostTrigger(EVENT_TRIGGER_BOOT, "init", strlen("init"));
|
||||
PostTrigger(EVENT_TRIGGER_BOOT, "post-init", strlen("post-init"));
|
||||
|
||||
// load SELinux context and policy
|
||||
SystemLoadSelinux();
|
||||
}
|
||||
|
||||
void SystemRun(void)
|
||||
|
@ -73,4 +73,4 @@ int ServiceExec(const Service *service)
|
||||
INIT_LOGE("service %s execve failed! err %d.", service->name, errno);
|
||||
}
|
||||
return SERVICE_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user