Message ID | 20200810011540.128951-1-mail@aparcar.org |
---|---|
State | Accepted |
Headers | show |
Series | [procd] initd/init: add minimal SELinux policy loading support | expand |
[...] > 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. [...] I will update the GitHub pull request once this is merged. Thank you, Paul!
Hi, Sun, Aug 09, 2020 at 03:15:20PM -1000, Paul Spooren wrote: > 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@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. I've applied this to move forward, however, there will be a problem once we got libselinux packaged, as buildbots will then ALWAYS build procd with libselinux. What we would need now is packaging two variants of procd (and busybox and maybe other packages): One without selinux support and one seliux-enabled which depends on libselinux. (assuming we are heading for SELinux support in our binary distribution -- otherwise we can just mark libselinux as @BROKEN for buildbot not to consider it and only allow building from source if user wants support for SELinux) > > [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 >
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);