From e9f4ba4c1444893841d768a7e3845ea1dac0b50a Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Fri, 29 Sep 2023 13:36:40 +0200 Subject: [PATCH] Add ostree selinux module for transient etc When using transient /etc, ostree-prepare-root will mount an overlayfs on /etc from the initrd. This overlay mount will have the context kernel_t, meaning that not only will an external process need to pass its selinux checks against the overlay file, the overlay filesystem itself need to pass the selinux check against the overlayfs upper/work dirs. Unfortunately, for historical reasons kernel_t doesn't really have any permissions in the selinux, so the overlayfs will not be able to do most operations against the etc_t (and similar) upper files. To fix this we make the kernel context unconfined. It essentially is anyway, as the kernel is the entity that validates the permissions anyway. This was the recommended approach by Dan Walsh to solve this issue. Signed-off-by: Alexander Larsson --- Makefile-decls.am | 1 + Makefile-selinux.am | 18 ++++++++++++++++++ Makefile.am | 1 + configure.ac | 12 ++++++++++++ selinux/build-selinux.sh | 16 ++++++++++++++++ selinux/ostree.fc | 0 selinux/ostree.if | 1 + selinux/ostree.te | 20 ++++++++++++++++++++ 8 files changed, 69 insertions(+) create mode 100644 Makefile-selinux.am create mode 100755 selinux/build-selinux.sh create mode 100644 selinux/ostree.fc create mode 100644 selinux/ostree.if create mode 100644 selinux/ostree.te diff --git a/Makefile-decls.am b/Makefile-decls.am index 0b4d22c646..3c70aa3046 100644 --- a/Makefile-decls.am +++ b/Makefile-decls.am @@ -24,6 +24,7 @@ NULL = BUILT_SOURCES = MANPAGES = CLEANFILES = +DISTCLEANFILES = EXTRA_DIST = bin_PROGRAMS = sbin_PROGRAMS = diff --git a/Makefile-selinux.am b/Makefile-selinux.am new file mode 100644 index 0000000000..336418c931 --- /dev/null +++ b/Makefile-selinux.am @@ -0,0 +1,18 @@ +if BUILD_SELINUX_MODULE +selinux_moduledir = ${datadir}/selinux/packages +selinux_module_DATA = $(NULL) + +ostree.pp.bz2: selinux/ostree.te selinux/ostree.fc selinux/build-selinux.sh + $(srcdir)/selinux/build-selinux.sh . $^ + +selinux_module_DATA += ostree.pp.bz2 +endif + +EXTRA_DIST += \ + selinux/build-selinux.sh \ + selinux/ostree.te \ + selinux/ostree.fc \ + selinux/meson.build \ + $(NULL) + +DISTCLEANFILES += ostree.pp.bz2 diff --git a/Makefile.am b/Makefile.am index 19abc0c1e1..3d97ee7377 100644 --- a/Makefile.am +++ b/Makefile.am @@ -138,6 +138,7 @@ include Makefile-tests.am include Makefile-boot.am include Makefile-man.am include Makefile-bash.am +include Makefile-selinux.am release-tag: cd $(srcdir) && git $(srcdir) tag -m "Release $(VERSION)" v$(VERSION) diff --git a/configure.ac b/configure.ac index 4416bc06f9..2e15183cbd 100644 --- a/configure.ac +++ b/configure.ac @@ -681,6 +681,17 @@ AM_COND_IF([BUILDOPT_IS_DEVEL_BUILD], release_build_type=release) OSTREE_FEATURES="$OSTREE_FEATURES $release_build_type" +AC_ARG_ENABLE(selinux-module, + [AS_HELP_STRING([--enable-selinux-module],[Enable selinux module for system-helper])], + enable_selinux_module=$enableval, enable_selinux_module=auto) +if test x$enable_selinux_module = xauto ; then + AC_CHECK_FILE([/usr/share/selinux/devel/Makefile], [enable_selinux_module=yes], [enable_selinux_module=no]) +fi +if test x$enable_selinux_module = xyes ; then + AC_CHECK_FILE([/usr/share/selinux/devel/Makefile], [], [AC_MSG_ERROR([selinux-policy-devel needed to build selinux module])]) +fi +AM_CONDITIONAL(BUILD_SELINUX_MODULE, test x$enable_selinux_module = xyes) + # P2P API is public in OSTree >= 2018.6 OSTREE_FEATURES="$OSTREE_FEATURES p2p" @@ -722,6 +733,7 @@ echo " dracut: $with_dracut mkinitcpio: $with_mkinitcpio Static compiler for ostree-prepare-root: $with_static_compiler + Build selinux module: $enable_selinux_module Composefs: $with_composefs" AS_IF([test x$with_builtin_grub2_mkconfig = xyes], [ echo " builtin grub2-mkconfig (instead of system): $with_builtin_grub2_mkconfig" diff --git a/selinux/build-selinux.sh b/selinux/build-selinux.sh new file mode 100755 index 0000000000..0655074860 --- /dev/null +++ b/selinux/build-selinux.sh @@ -0,0 +1,16 @@ +#!/bin/sh +# Copyright 2023 Red Hat Inc. +# SPDX-License-Identifier: LGPL-2.1-or-later + +set -x +set -eu + +TMP=$(mktemp -d selinux-build-XXXXXX) +output="$1" +shift +cp -- "$@" "$TMP/" + +make -C "$TMP" -f /usr/share/selinux/devel/Makefile ostree.pp +bzip2 -9 "$TMP/ostree.pp" +cp "$TMP/ostree.pp.bz2" "$output" +rm -fr "$TMP" diff --git a/selinux/ostree.fc b/selinux/ostree.fc new file mode 100644 index 0000000000..e69de29bb2 diff --git a/selinux/ostree.if b/selinux/ostree.if new file mode 100644 index 0000000000..fcc6bb2dff --- /dev/null +++ b/selinux/ostree.if @@ -0,0 +1 @@ +## selinux diff --git a/selinux/ostree.te b/selinux/ostree.te new file mode 100644 index 0000000000..d33f0141df --- /dev/null +++ b/selinux/ostree.te @@ -0,0 +1,20 @@ +policy_module(ostree, 1.0) + +gen_require(` + type kernel_t; +') + +# When using transient /etc, ostree-prepare-root will mount an overlayfs on /etc +# from the initrd. This overlay mount will have the context kernel_t, meaning +# that not only will an external process need to pass its selinux checks against +# the overlay file, the overlay filesystem itself need to pass the selinux check +# against the overlayfs upper/work dirs. +# +# Unfortunately, for historical reasons kernel_t doesn't really have any permissions in +# the selinux, so the overlayfs will not be able to do most operations against the etc_t +# (and similar) upper files. +# +# To fix this we make the kernel context unconfined. It essentially is anyway, as +# the kernel is the entity that validates the permissions anyway. + +unconfined_domain(kernel_t)