diff mbox series

[OpenWrt-Devel,2/7] package/system/procd: add SELinux support

Message ID 20191122095541.688125-3-thomas.petazzoni@bootlin.com
State Changes Requested
Delegated to: Daniel Golle
Headers show
Series SELinux support: core OpenWrt changes | expand

Commit Message

Thomas Petazzoni Nov. 22, 2019, 9:55 a.m. UTC
This commit adds a patch to procd to support loading the SELinux
policy early at boot time, and adjusts the procd package to use this
SELinux support when libselinux is enabled.

The procd patch has been submitted separately [1]: obviously the
intent is to have it merged in the procd Git repository rather than
have it in OpenWrt itself.

[1] http://lists.infradead.org/pipermail/openwrt-devel/2019-November/020070.html

Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
---
 package/system/procd/Makefile                 |   5 +-
 ...inimal-SELinux-policy-loading-suppor.patch | 110 ++++++++++++++++++
 2 files changed, 113 insertions(+), 2 deletions(-)
 create mode 100644 package/system/procd/patches/0001-initd-init-add-minimal-SELinux-policy-loading-suppor.patch

Comments

Daniel Golle Jan. 4, 2020, 12:35 p.m. UTC | #1
Hi Thomas,

On Fri, Nov 22, 2019 at 10:55:36AM +0100, Thomas Petazzoni wrote:
> This commit adds a patch to procd to support loading the SELinux
> policy early at boot time, and adjusts the procd package to use this
> SELinux support when libselinux is enabled.
> 
> The procd patch has been submitted separately [1]: obviously the
> intent is to have it merged in the procd Git repository rather than
> have it in OpenWrt itself.
> 
> [1] http://lists.infradead.org/pipermail/openwrt-devel/2019-November/020070.html
> 
> Signed-off-by: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
> ---
>  package/system/procd/Makefile                 |   5 +-
>  ...inimal-SELinux-policy-loading-suppor.patch | 110 ++++++++++++++++++
>  2 files changed, 113 insertions(+), 2 deletions(-)
>  create mode 100644 package/system/procd/patches/0001-initd-init-add-minimal-SELinux-policy-loading-suppor.patch
> 
> diff --git a/package/system/procd/Makefile b/package/system/procd/Makefile
> index c4b86ba746..53d9e1120f 100644
> --- a/package/system/procd/Makefile
> +++ b/package/system/procd/Makefile
> @@ -43,7 +43,7 @@ TARGET_LDFLAGS += -flto
>  define Package/procd
>    SECTION:=base
>    CATEGORY:=Base system
> -  DEPENDS:=+ubusd +ubus +libjson-script +ubox +USE_GLIBC:librt +libubox +libubus +libblobmsg-json +libjson-c
> +  DEPENDS:=+ubusd +ubus +libjson-script +ubox +USE_GLIBC:librt +libubox +libubus +libblobmsg-json +libjson-c +PACKAGE_libselinux:libselinux
>    TITLE:=OpenWrt system process manager
>    USERID:=:dialout=20 :audio=29
>  endef
> @@ -92,7 +92,8 @@ ifdef CONFIG_PACKAGE_procd-ujail
>  endif
>  
>  SECCOMP=$(if $(CONFIG_PACKAGE_procd-seccomp),1,0)
> -CMAKE_OPTIONS += -DSECCOMP_SUPPORT=$(SECCOMP) -DUTRACE_SUPPORT=$(SECCOMP)
> +SELINUX=$(if $(CONFIG_PACKAGE_libselinux),1,0)

Selecting this based on libselinux being selected for build is not
feasible. The buildbot always builds with all packages enabled, yet
not everyone will want libselinux installed on their small-flash
devices... Please use introduce a VARIANT:=selinux instead to have
an additional package procd-selinux. In that way, binary builds will
allow for both, selinux-enabled and non-selinux images being generated.
Another (and even better) solution would be to out-source SELinux
policy loading into a small independent executable in it's own packages
(like eg. procd-seccomp).


Cheers


Daniel

> +CMAKE_OPTIONS += -DSECCOMP_SUPPORT=$(SECCOMP) -DUTRACE_SUPPORT=$(SECCOMP) -DSELINUX=$(SELINUX)
>  
>  define Package/procd/install
>  	$(INSTALL_DIR) $(1)/sbin $(1)/etc $(1)/lib/functions
> diff --git a/package/system/procd/patches/0001-initd-init-add-minimal-SELinux-policy-loading-suppor.patch b/package/system/procd/patches/0001-initd-init-add-minimal-SELinux-policy-loading-suppor.patch
> new file mode 100644
> index 0000000000..cfab059b40
> --- /dev/null
> +++ b/package/system/procd/patches/0001-initd-init-add-minimal-SELinux-policy-loading-suppor.patch
> @@ -0,0 +1,110 @@
> +From fe74ad8b11977d0ced5c44f5e389c50ee70bc008 Mon Sep 17 00:00:00 2001
> +From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
> +Date: Thu, 23 May 2019 13:57:30 +0200
> +Subject: [PATCH] initd/init: add minimal SELinux policy loading support
> +
> +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@bootlin.com>
> +---
> + CMakeLists.txt |  9 ++++++++-
> + initd/init.c   | 38 ++++++++++++++++++++++++++++++++++++++
> + 2 files changed, 46 insertions(+), 1 deletion(-)
> +
> +diff --git a/CMakeLists.txt b/CMakeLists.txt
> +index 4b3eebd..865e43c 100644
> +--- a/CMakeLists.txt
> ++++ b/CMakeLists.txt
> +@@ -40,6 +40,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})
> +@@ -56,7 +62,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 29eee50..561970c 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.21.0
> +
> -- 
> 2.23.0
> 
> 
> _______________________________________________
> openwrt-devel mailing list
> openwrt-devel@lists.openwrt.org
> https://lists.openwrt.org/mailman/listinfo/openwrt-devel
diff mbox series

Patch

diff --git a/package/system/procd/Makefile b/package/system/procd/Makefile
index c4b86ba746..53d9e1120f 100644
--- a/package/system/procd/Makefile
+++ b/package/system/procd/Makefile
@@ -43,7 +43,7 @@  TARGET_LDFLAGS += -flto
 define Package/procd
   SECTION:=base
   CATEGORY:=Base system
-  DEPENDS:=+ubusd +ubus +libjson-script +ubox +USE_GLIBC:librt +libubox +libubus +libblobmsg-json +libjson-c
+  DEPENDS:=+ubusd +ubus +libjson-script +ubox +USE_GLIBC:librt +libubox +libubus +libblobmsg-json +libjson-c +PACKAGE_libselinux:libselinux
   TITLE:=OpenWrt system process manager
   USERID:=:dialout=20 :audio=29
 endef
@@ -92,7 +92,8 @@  ifdef CONFIG_PACKAGE_procd-ujail
 endif
 
 SECCOMP=$(if $(CONFIG_PACKAGE_procd-seccomp),1,0)
-CMAKE_OPTIONS += -DSECCOMP_SUPPORT=$(SECCOMP) -DUTRACE_SUPPORT=$(SECCOMP)
+SELINUX=$(if $(CONFIG_PACKAGE_libselinux),1,0)
+CMAKE_OPTIONS += -DSECCOMP_SUPPORT=$(SECCOMP) -DUTRACE_SUPPORT=$(SECCOMP) -DSELINUX=$(SELINUX)
 
 define Package/procd/install
 	$(INSTALL_DIR) $(1)/sbin $(1)/etc $(1)/lib/functions
diff --git a/package/system/procd/patches/0001-initd-init-add-minimal-SELinux-policy-loading-suppor.patch b/package/system/procd/patches/0001-initd-init-add-minimal-SELinux-policy-loading-suppor.patch
new file mode 100644
index 0000000000..cfab059b40
--- /dev/null
+++ b/package/system/procd/patches/0001-initd-init-add-minimal-SELinux-policy-loading-suppor.patch
@@ -0,0 +1,110 @@ 
+From fe74ad8b11977d0ced5c44f5e389c50ee70bc008 Mon Sep 17 00:00:00 2001
+From: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
+Date: Thu, 23 May 2019 13:57:30 +0200
+Subject: [PATCH] initd/init: add minimal SELinux policy loading support
+
+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@bootlin.com>
+---
+ CMakeLists.txt |  9 ++++++++-
+ initd/init.c   | 38 ++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 46 insertions(+), 1 deletion(-)
+
+diff --git a/CMakeLists.txt b/CMakeLists.txt
+index 4b3eebd..865e43c 100644
+--- a/CMakeLists.txt
++++ b/CMakeLists.txt
+@@ -40,6 +40,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})
+@@ -56,7 +62,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 29eee50..561970c 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.21.0
+