once
|
Whether the current service process is a one-off process.
diff --git a/README_zh.md b/README_zh.md
index 2caa463..5f6f6e7 100644
--- a/README_zh.md
+++ b/README_zh.md
@@ -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将系统启动分为三个阶段:
| 当前服务进程的gid值。
|
+once
|
当前服务进程是否为一次性进程:
diff --git a/services/BUILD.gn b/services/BUILD.gn
index bc814a2..fb284e2 100755
--- a/services/BUILD.gn
+++ b/services/BUILD.gn
@@ -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" ]
}
diff --git a/services/include/param/init_selinux_param.h b/services/include/param/init_selinux_param.h
new file mode 100644
index 0000000..cf60011
--- /dev/null
+++ b/services/include/param/init_selinux_param.h
@@ -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
diff --git a/services/init/include/init_service.h b/services/init/include/init_service.h
index 87713e1..6a33631 100755
--- a/services/init/include/init_service.h
+++ b/services/init/include/init_service.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;
diff --git a/services/init/init_common_service.c b/services/init/init_common_service.c
index 197db70..4218db6 100755
--- a/services/init/init_common_service.c
+++ b/services/init/init_common_service.c
@@ -37,6 +37,11 @@
#include "init_utils.h"
#include "securec.h"
+#ifdef WITH_SELINUX
+# include "init_selinux_param.h"
+# include
+#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) {
diff --git a/services/init/init_service_manager.c b/services/init/init_service_manager.c
index be677f6..42019c8 100755
--- a/services/init/init_service_manager.c
+++ b/services/init/init_service_manager.c
@@ -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])) {
diff --git a/services/init/standard/init.c b/services/init/standard/init.c
index abd0e31..fbe1ba5 100755
--- a/services/init/standard/init.c
+++ b/services/init/standard/init.c
@@ -29,6 +29,9 @@
#include "init_utils.h"
#include "securec.h"
#include "switch_root.h"
+#ifdef WITH_SELINUX
+# include
+#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)
diff --git a/services/init/standard/init_service.c b/services/init/standard/init_service.c
index 533addb..bf10341 100755
--- a/services/init/standard/init_service.c
+++ b/services/init/standard/init_service.c
@@ -73,4 +73,4 @@ int ServiceExec(const Service *service)
INIT_LOGE("service %s execve failed! err %d.", service->name, errno);
}
return SERVICE_SUCCESS;
-}
\ No newline at end of file
+}
|