From 7043815686df1a0346da1973dd2985b7c9d67c06 Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Fri, 12 Apr 2024 20:10:52 -0400 Subject: [PATCH] Allow logging in to rescue/emergency shell as root In Qubes OS guests, the console is _always_ the Xen console. There are _never_ untrusted entities with access to this under _any_ circumstances. The only supported way to get access to this from a VM is the admin.vm.Console service, which is (by design) equivalent to root access in the destination VM. Other consoles, such as a USB serial console, are not supported as domU consoles under Qubes OS. Therefore, set SYSTEMD_SULOGIN_FORCE=1 to tell systemd-sulogin-shell to pass --force to sulogin(8). Since the root account is locked in Qubes VMs, this causes sulogin(8) to allow login as root without a password. Use TTYPath= to enforce that the console is, in fact, the Xen console and not some other console, in case the assumption in the previous paragraph turns out false for some reason. This will break if the Xen drivers are not included in the guest kernel config, but an HVM guest with Qubes tools but no Xen drivers is not a supported configuration. --- Makefile | 2 +- boot/Makefile | 5 +++- boot/module-setup.sh | 10 +++++++ debian/qubes-core-agent.install | 2 ++ rpm_spec/core-agent.spec.in | 29 +++++++++++++++++++- vm-systemd/emergency.service.d/30_qubes.conf | 5 ++++ vm-systemd/rescue.service.d/30_qubes.conf | 5 ++++ 7 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 boot/module-setup.sh create mode 100644 vm-systemd/emergency.service.d/30_qubes.conf create mode 100644 vm-systemd/rescue.service.d/30_qubes.conf diff --git a/Makefile b/Makefile index 9848a8e8..7eadef04 100644 --- a/Makefile +++ b/Makefile @@ -50,7 +50,7 @@ SYSTEM_DROPINS += systemd-random-seed.service SYSTEM_DROPINS += tor.service tor@default.service SYSTEM_DROPINS += systemd-timesyncd.service SYSTEM_DROPINS += systemd-logind.service -SYSTEM_DROPINS += sysinit.target +SYSTEM_DROPINS += sysinit.target emergency.service rescue.service ifeq ($(ENABLE_SELINUX),1) SYSTEM_DROPINS += selinux-autorelabel.target selinux-autorelabel.service endif diff --git a/boot/Makefile b/boot/Makefile index c9b4123f..32a678b4 100644 --- a/boot/Makefile +++ b/boot/Makefile @@ -1,11 +1,14 @@ LIBDIR ?= /usr/lib SYSCONFDIR ?= /etc GRUBCONFDIR ?= $(SYSCONFDIR)/default -DRACUTCONFDIR ?= $(LIBDIR)/dracut/dracut.conf.d GRUBCFGNAME ?= grub.qubes +DRACUTDIR ?= $(LIBDIR)/dracut +DRACUTCONFDIR ?= $(DRACUTDIR)/dracut.conf.d +DRACUTMODDIR ?= $(DRACUTDIR)/modules.d .PHONY: install install: install -D -m 0644 grub.qubes $(DESTDIR)$(GRUBCONFDIR)/$(GRUBCFGNAME) install -D -m 0644 dracut-qubes.conf $(DESTDIR)$(DRACUTCONFDIR)/30-qubes.conf + install -D -m 0755 module-setup.sh $(DESTDIR)$(DRACUTMODDIR)/99qubes/module-setup.sh diff --git a/boot/module-setup.sh b/boot/module-setup.sh new file mode 100644 index 00000000..1278c2f5 --- /dev/null +++ b/boot/module-setup.sh @@ -0,0 +1,10 @@ +depends () { +} + +install () { + if [ -h /lib ]; then + inst_multiple /usr/lib/systemd/system/rescue.service.d/30_qubes.conf /usr/lib/systemd/system/emergency.service.d/30_qubes.conf + else + inst_multiple /lib/systemd/system/rescue.service.d/30_qubes.conf /lib/systemd/system/emergency.service.d/30_qubes.conf + fi +} diff --git a/debian/qubes-core-agent.install b/debian/qubes-core-agent.install index 3015aa9f..68ca877b 100644 --- a/debian/qubes-core-agent.install +++ b/debian/qubes-core-agent.install @@ -107,6 +107,8 @@ lib/systemd/system/sysinit.target.d/30_qubes.conf lib/systemd/system/systemd-timesyncd.service.d/30_qubes.conf lib/systemd/system/systemd-logind.service.d/30_qubes.conf lib/systemd/resolved.conf.d/30_resolved-no-mdns-or-llmnr.conf +lib/systemd/system/rescue.service.d/30_qubes.conf +lib/systemd/system/emergency.service.d/30_qubes.conf usr/lib/sysctl.d/20-qubes-core.conf usr/lib/systemd/user/tracker-extract-3.service.d/30_qubes.conf usr/lib/systemd/user/tracker-miner-fs-3.service.d/30_qubes.conf diff --git a/rpm_spec/core-agent.spec.in b/rpm_spec/core-agent.spec.in index 143dc02f..371b8a56 100644 --- a/rpm_spec/core-agent.spec.in +++ b/rpm_spec/core-agent.spec.in @@ -134,6 +134,7 @@ Requires: sed Requires: util-linux Requires: e2fsprogs Requires: hostname +Requires: (%{name}-dracut if dracut) # for Qubes Manager VM updater Requires: xterm # for qubes-desktop-run @@ -373,6 +374,19 @@ switching from user to root. Since all the user data in a VM is accessible already from normal user account, there is not much more to guard there. Qubes VMs are single user systems. +%package dracut +Summary: Dracut configuration needed in Qubes OS +License: GPL +Group: Qubes +Requires: dracut +Requires: qubes-core-agent = %{version} + +%description dracut +Dracut configuration needed in Qubes OS. This enables +passwordless login in rescue and emergency modes, as well +as configuring dracut to only install certain drivers and +omit others. + %package thunar Summary: Thunar support for Qubes VM tools Requires: Thunar @@ -521,6 +535,10 @@ sed -i \ $RPM_BUILD_ROOT/etc/yum.repos.d/qubes-*.repo %endif +install -D -m 0644 boot/dracut-qubes.conf $RPM_BUILD_ROOT/usr/lib/dracut/dracut.conf.d/30-qubes.conf +install -D -m 0644 boot/grub.qubes $RPM_BUILD_ROOT/etc/default/grub.qubes +install -D -m 0755 boot/module-setup.sh $RPM_BUILD_ROOT/usr/lib/dracut/modules.d/99qubes/module-setup.sh + %if ! %with_sysvinit rm -rf $RPM_BUILD_ROOT/etc/init.d/qubes-* $RPM_BUILD_ROOT/etc/sysconfig/modules/qubes-core.modules %endif @@ -1026,7 +1044,7 @@ rm -f %{name}-%{version} /usr/lib/qubes/resize-rootfs /usr/lib/qubes/set-default-text-editor /usr/lib/qubes/tinyproxy-wrapper -/usr/lib/dracut/dracut.conf.d/30-qubes.conf + /usr/lib/environment.d/60-gnome-software-fix.conf %dir /usr/lib/qubes/init /usr/lib/qubes/init/bind-dirs.sh @@ -1096,6 +1114,11 @@ rm -f %{name}-%{version} /usr/share/caja-python/extensions/qvm_dvm_caja.py* %endif +%files dracut +/usr/lib/dracut/dracut.conf.d/30-qubes.conf +%dir /usr/lib/dracut/modules.d/99qubes +/usr/lib/dracut/modules.d/99qubes/module-setup.sh + %files nautilus /usr/share/nautilus-python/extensions/qvm_copy_nautilus.py* /usr/share/nautilus-python/extensions/qvm_move_nautilus.py* @@ -1304,6 +1327,10 @@ The Qubes core startup configuration for SystemD init. %dir %_unitdir/sysinit.target.d %_unitdir/sysinit.target.d/30_qubes.conf %dir %_userunitdir/*.service.d +%dir %_unitdir/rescue.service.d +%dir %_unitdir/emergency.service.d +%_unitdir/emergency.service.d/30_qubes.conf +%_unitdir/rescue.service.d/30_qubes.conf %_userunitdir/tracker-extract-3.service.d/30_qubes.conf %_userunitdir/tracker-miner-fs-3.service.d/30_qubes.conf %_userunitdir/tracker-miner-fs-control-3.service.d/30_qubes.conf diff --git a/vm-systemd/emergency.service.d/30_qubes.conf b/vm-systemd/emergency.service.d/30_qubes.conf new file mode 100644 index 00000000..edca8f42 --- /dev/null +++ b/vm-systemd/emergency.service.d/30_qubes.conf @@ -0,0 +1,5 @@ +[Service] +# Ensure that the console is the secure Xen console, +# not e.g. a serial console that is exposed to the outside world. +TTYPath=/dev/hvc0 +Environment=SYSTEMD_SULOGIN_FORCE=1 diff --git a/vm-systemd/rescue.service.d/30_qubes.conf b/vm-systemd/rescue.service.d/30_qubes.conf new file mode 100644 index 00000000..edca8f42 --- /dev/null +++ b/vm-systemd/rescue.service.d/30_qubes.conf @@ -0,0 +1,5 @@ +[Service] +# Ensure that the console is the secure Xen console, +# not e.g. a serial console that is exposed to the outside world. +TTYPath=/dev/hvc0 +Environment=SYSTEMD_SULOGIN_FORCE=1