diff --git a/Makefile b/Makefile index ff96de692..3b4a40b8c 100644 --- a/Makefile +++ b/Makefile @@ -50,6 +50,14 @@ completion: bin target/release/bootc completion $$shell > target/completion/bootc.$$shell; \ done +SELINUX_PP = contrib/selinux/bootc.pp +.PHONY: selinux +selinux: $(SELINUX_PP) +$(SELINUX_PP): contrib/selinux/bootc.te + checkmodule -M -m -o contrib/selinux/bootc.mod $< + semodule_package -o $@ -m contrib/selinux/bootc.mod + rm -f contrib/selinux/bootc.mod + STORAGE_RELATIVE_PATH ?= $(shell realpath -m -s --relative-to="$(prefix)/lib/bootc/storage" /sysroot/ostree/bootc/storage) install: completion install -D -m 0755 -t $(DESTDIR)$(prefix)/bin target/release/bootc @@ -85,6 +93,9 @@ install: completion install -D -m 0644 -t $(DESTDIR)/usr/lib/systemd/system crates/initramfs/*.service install -D -m 0755 target/release/bootc-initramfs-setup $(DESTDIR)/usr/lib/bootc/initramfs-setup install -D -m 0755 -t $(DESTDIR)/usr/lib/dracut/modules.d/51bootc crates/initramfs/dracut/module-setup.sh + if test -f $(SELINUX_PP); then \ + install -D -m 0644 $(SELINUX_PP) $(DESTDIR)$(prefix)/share/selinux/packages/bootc.pp; \ + fi # Run this to also take over the functionality of `ostree container` for example. # Only needed for OS/distros that have callers invoking `ostree container` and not bootc. diff --git a/contrib/packaging/bootc.spec b/contrib/packaging/bootc.spec index 7ce0f7fd2..bae55b8ad 100644 --- a/contrib/packaging/bootc.spec +++ b/contrib/packaging/bootc.spec @@ -54,6 +54,7 @@ BuildRequires: rust-toolset BuildRequires: cargo-rpm-macros >= 25 %endif BuildRequires: systemd +BuildRequires: checkpolicy policycoreutils # For tests BuildRequires: skopeo ostree @@ -128,6 +129,7 @@ cd %{name}-%{version}-build export SYSTEM_REINSTALL_BOOTC_INSTALL_PODMAN_PATH=%{system_reinstall_bootc_install_podman_path} # Build this first to avoid feature skew make manpages +make selinux # Build all binaries %if 0%{?container_build} @@ -182,6 +184,14 @@ else fi %endif +%post +semodule -i %{_datadir}/selinux/packages/bootc.pp 2>/dev/null || : + +%postun +if [ $1 -eq 0 ]; then + semodule -r bootc 2>/dev/null || : +fi + %files -f bootcdoclist.txt %license LICENSE-MIT %license LICENSE-APACHE @@ -199,6 +209,7 @@ fi %endif %{_unitdir}/* %{_mandir}/man*/*bootc* +%{_datadir}/selinux/packages/bootc.pp %if 0%{?rhel} && 0%{?rhel} <= 9 %{_datadir}/bash-completion/completions/bootc %{_datadir}/zsh/site-functions/_bootc diff --git a/contrib/selinux/bootc.te b/contrib/selinux/bootc.te new file mode 100644 index 000000000..e2c64b37f --- /dev/null +++ b/contrib/selinux/bootc.te @@ -0,0 +1,25 @@ +module bootc 1.0; + +require { + type install_t; + type install_exec_t; + type initrc_t; + type unconfined_service_t; + class process { transition sigchld }; +} + +# When systemd runs a wrapper script/service (rather than bootc directly), +# the wrapper process runs as initrc_t or unconfined_service_t. Without +# these rules, executing an install_exec_t binary (bootc, ostree) from +# the wrapper does NOT transition to install_t, so the process lacks the +# mac_admin capability needed for cross-version OS updates. +# +# See https://redhat.atlassian.net/browse/RHEL-117256 + +type_transition initrc_t install_exec_t : process install_t; +allow initrc_t install_t : process transition; +allow install_t initrc_t : process sigchld; + +type_transition unconfined_service_t install_exec_t : process install_t; +allow unconfined_service_t install_t : process transition; +allow install_t unconfined_service_t : process sigchld;