[PATCH procd] initd/init: add minimal SELinux policy loading support

Paul Spooren mail at aparcar.org
Sun Aug 9 21:15:20 EDT 2020


From: Thomas Petazzoni <thomas.petazzoni at bootlin.com>

In order to support SELinux in OpenWrt, this commit introduces minimal
support for loading the SELinux policy in the init code. The logic is
very much inspired from what Busybox is doing: call
selinux_init_load_policy() from libselinux, and then re-execute init
so that it runs with the SELinux policy in place and enforced.

Signed-off-by: Thomas Petazzoni <thomas.petazzoni at bootlin.com>
[fix spelling of OpenWrt]
Signed-off-by: Paul Spooren <mail at aparcar.org>
---
This is part of a bigger PR on GitHub[1], however this patch should be
added directly to `procd` rather than as a patch in openwrt.git.

As some core devs avoid GitHubs heavy frontend, I send this particular
patch here again.

I've tested the patch series and it compiles and runs as (I) expected.

[1]: https://github.com/openwrt/openwrt/pull/3207

 CMakeLists.txt |  9 ++++++++-
 initd/init.c   | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 46 insertions(+), 1 deletion(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index c7adfa3..d20e57b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -46,6 +46,12 @@ IF(ZRAM_TMPFS)
   SET(SOURCES_ZRAM initd/zram.c)
 ENDIF()
 
+IF(SELINUX)
+  include(FindPkgConfig)
+  pkg_search_module(SELINUX REQUIRED libselinux)
+  add_compile_definitions(WITH_SELINUX)
+ENDIF()
+
 add_subdirectory(upgraded)
 
 ADD_EXECUTABLE(procd ${SOURCES})
@@ -62,7 +68,8 @@ ADD_DEFINITIONS(-DDISABLE_INIT)
 ELSE()
 ADD_EXECUTABLE(init initd/init.c initd/early.c initd/preinit.c initd/mkdev.c sysupgrade.c watchdog.c
 	utils/utils.c ${SOURCES_ZRAM})
-TARGET_LINK_LIBRARIES(init ${LIBS})
+TARGET_INCLUDE_DIRECTORIES(init PUBLIC ${SELINUX_INCLUDE_DIRS})
+TARGET_LINK_LIBRARIES(init ${LIBS} ${SELINUX_LIBRARIES})
 INSTALL(TARGETS init
 	RUNTIME DESTINATION ${CMAKE_INSTALL_SBINDIR}
 )
diff --git a/initd/init.c b/initd/init.c
index 9b47826..2eb6ead 100644
--- a/initd/init.c
+++ b/initd/init.c
@@ -29,6 +29,10 @@
 #include <unistd.h>
 #include <stdio.h>
 
+#if defined(WITH_SELINUX)
+#include <selinux/selinux.h>
+#endif
+
 #include "../utils/utils.h"
 #include "init.h"
 #include "../watchdog.h"
@@ -67,6 +71,38 @@ cmdline(void)
 	}
 }
 
+#if defined(WITH_SELINUX)
+static int
+selinux(char **argv)
+{
+	int enforce = 0;
+	int ret;
+
+	/* SELinux already initialized */
+	if (getenv("SELINUX_INIT"))
+		return 0;
+
+	putenv("SELINUX_INIT=1");
+
+	ret = selinux_init_load_policy(&enforce);
+	if (ret == 0)
+		execv(argv[0], argv);
+
+	if (enforce > 0) {
+		fprintf(stderr, "Cannot load SELinux policy, but system in enforcing mode. Halting.\n");
+		return 1;
+	}
+
+	return 0;
+}
+#else
+static int
+selinux(char **argv)
+{
+	return 0;
+}
+#endif
+
 int
 main(int argc, char **argv)
 {
@@ -79,6 +115,8 @@ main(int argc, char **argv)
 	sigaction(SIGUSR2, &sa_shutdown, NULL);
 	sigaction(SIGPWR, &sa_shutdown, NULL);
 
+	if (selinux(argv))
+		exit(-1);
 	early();
 	cmdline();
 	watchdog_init(1);
-- 
2.25.1




More information about the openwrt-devel mailing list