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)