From d3212f69fd5cc8ba8bb0637121ceef9df777647e Mon Sep 17 00:00:00 2001
From: Demi Marie Obenour <demi@invisiblethingslab.com>
Date: Sun, 22 Dec 2024 19:23:47 -0500
Subject: [PATCH] Relabel / and /rw if needed

Creating /.autorelabel must cause a Qubes OS VM to relabel everything,
as otherwise users will not be able to troubleshoot their systems and
upstream packages that create it will break.  However, it was ignored,
so fix that.

Furthermore, relabel the filesystem of a TemplateBasedVM whenever its
TemplateVM has been relabeled since the TemplateBasedVM was.  This
ensures that policy changes propagate to TemplateBasedVMs too.
---
 Makefile                              | 1 +
 init/relabel-rw.sh                    | 6 ++++++
 rpm_spec/core-agent.spec.in           | 1 +
 vm-systemd/qubes-relabel-root.service | 3 ++-
 vm-systemd/qubes-relabel-rw.service   | 8 +++-----
 5 files changed, 13 insertions(+), 6 deletions(-)
 create mode 100755 init/relabel-rw.sh

diff --git a/Makefile b/Makefile
index 9848a8e83..c42255395 100644
--- a/Makefile
+++ b/Makefile
@@ -130,6 +130,7 @@ install-init:
 	install -m 0644 init/functions $(DESTDIR)$(LIBDIR)/qubes/init/
 ifneq ($(ENABLE_SELINUX),1)
 	rm -f $(DESTDIR)$(LIBDIR)/qubes/init/relabel-root.sh
+	rm -f $(DESTDIR)$(LIBDIR)/qubes/init/relabel-rw.sh
 endif
 
 # Systemd service files
diff --git a/init/relabel-rw.sh b/init/relabel-rw.sh
new file mode 100755
index 000000000..189bd8c80
--- /dev/null
+++ b/init/relabel-rw.sh
@@ -0,0 +1,6 @@
+#!/bin/bash --
+set -eu
+if [ /.qubes-relabeled -nt /rw/.autorelabel ]; then
+    restorecon -R /rw /home /usr/local
+    touch --reference=/.qubes-relabeled /rw/.autorelabel
+fi
diff --git a/rpm_spec/core-agent.spec.in b/rpm_spec/core-agent.spec.in
index 143dc02f0..fbfd397f8 100644
--- a/rpm_spec/core-agent.spec.in
+++ b/rpm_spec/core-agent.spec.in
@@ -426,6 +426,7 @@ a VM with SELinux enforcing, as is the default on Red Hat-family distributions.
 %dir %_unitdir/selinux-autorelabel.service.d
 %_unitdir/selinux-autorelabel.service.d/30_qubes.conf
 /usr/lib/qubes/init/relabel-root.sh
+/usr/lib/qubes/init/relabel-rw.sh
 
 %postun selinux
 if [ "$1" -eq 0 ]; then
diff --git a/vm-systemd/qubes-relabel-root.service b/vm-systemd/qubes-relabel-root.service
index c1611cc3f..a79e6b116 100644
--- a/vm-systemd/qubes-relabel-root.service
+++ b/vm-systemd/qubes-relabel-root.service
@@ -3,7 +3,8 @@ Description=Relabel /
 After=qubes-sysinit.service
 Requires=qubes-sysinit.service
 ConditionSecurity=selinux
-ConditionPathExists=!/.qubes-relabeled
+ConditionPathExists=|/.autorelabel
+ConditionPathExists=|!/.qubes-relabeled
 ConditionPathExists=/run/qubes/persistent-full
 DefaultDependencies=no
 Conflicts=shutdown.target
diff --git a/vm-systemd/qubes-relabel-rw.service b/vm-systemd/qubes-relabel-rw.service
index 2e4d42037..cbffb991b 100644
--- a/vm-systemd/qubes-relabel-rw.service
+++ b/vm-systemd/qubes-relabel-rw.service
@@ -1,9 +1,8 @@
 [Unit]
 Description=Relabel /rw and /home
-After=qubes-mount-dirs.service qubes-sysinit.service
-Requires=qubes-mount-dirs.service qubes-sysinit.service
+After=qubes-mount-dirs.service qubes-sysinit.service qubes-relabel-root.service
+Requires=qubes-mount-dirs.service qubes-sysinit.service qubes-relabel-root.service
 ConditionSecurity=selinux
-ConditionPathExists=!/rw/.autorelabel
 DefaultDependencies=no
 Conflicts=selinux-autorelabel.service
 Before=local-fs.target rw.mount home.mount qubes-gui-agent.service qubes-qrexec-agent.service
@@ -11,8 +10,7 @@ Before=local-fs.target rw.mount home.mount qubes-gui-agent.service qubes-qrexec-
 [Service]
 Type=oneshot
 RemainAfterExit=yes
-ExecStart=/usr/sbin/restorecon -RF /rw /home /usr/local
-ExecStart=/bin/touch /rw/.autorelabel
+ExecStart=/usr/lib/qubes/init/relabel-rw.sh
 
 [Install]
 WantedBy=multi-user.target