diff --git a/usr/lib/dracut/modules.d/99emerg-shutdown/module-setup.sh b/usr/lib/dracut/modules.d/99emerg-shutdown/module-setup.sh new file mode 100755 index 0000000..98d6be9 --- /dev/null +++ b/usr/lib/dracut/modules.d/99emerg-shutdown/module-setup.sh @@ -0,0 +1,48 @@ +#!/bin/bash + +## Copyright (C) 2025 - 2025 ENCRYPTED SUPPORT LLC +## See the file COPYING for copying conditions. + +## called by dracut +check() { + require_binaries /run/emerg-shutdown || return 1 + return 255 +} + +## called by dracut +depends() { + echo 'systemd bash' + return 0 +} + +## called by dracut +install() { + local config_file + + inst systemd-notify + + inst_simple /usr/libexec/security-misc/emerg-shutdown + inst_simple /usr/share/security-misc/emerg-shutdown-initramfs.service /usr/lib/systemd/system/emerg-shutdown-initramfs.service + inst_simple /run/emerg-shutdown /emerg-shutdown + + for config_file in /etc/security-misc/emerg-shutdown/*.conf; do + if [ -f "${config_file}" ]; then + inst_multiple /etc/security-misc/emerg-shutdown/*.conf + break + fi + done + for config_file in /usr/local/etc/security-misc/emerg-shutdown/*.conf; do + if [ -f "${config_file}" ]; then + inst_multiple /usr/local/etc/security-misc/emerg-shutdown/*.conf + break + fi + done + + mkdir -p "${initdir}/usr/lib/systemd/system/initrd.target.wants" + ln -s '../emerg-shutdown-initramfs.service' "${initdir}/usr/lib/systemd/system/initrd.target.wants/emerg-shutdown-initramfs.service" +} + +## called by dracut +installkernel () { + hostonly='' instmods evdev +} diff --git a/usr/lib/systemd/system/emerg-shutdown.service b/usr/lib/systemd/system/emerg-shutdown.service index f2dc2e8..fa738ab 100644 --- a/usr/lib/systemd/system/emerg-shutdown.service +++ b/usr/lib/systemd/system/emerg-shutdown.service @@ -6,8 +6,8 @@ Description=Emergency shutdown when boot media is removed Documentation=https://github.com/Kicksecure/security-misc DefaultDependencies=no Before=sysinit.target -Requires=udev.service -After=udev.service +Requires=systemd-udevd.service +After=systemd-udevd.service Requires=local-fs.target After=local-fs.target diff --git a/usr/lib/systemd/system/ensure-shutdown.service b/usr/lib/systemd/system/ensure-shutdown.service index 52eb487..8e4c5b6 100644 --- a/usr/lib/systemd/system/ensure-shutdown.service +++ b/usr/lib/systemd/system/ensure-shutdown.service @@ -9,8 +9,8 @@ Description=Forcibly shut down the system if normal shutdown gets stuck Documentation=https://github.com/Kicksecure/security-misc DefaultDependencies=no Before=sysinit.target -Requires=udev.service -After=udev.service +Requires=systemd-udevd.service +After=systemd-udevd.service Wants=emerg-shutdown.service After=emerg-shutdown.service diff --git a/usr/libexec/security-misc/emerg-shutdown b/usr/libexec/security-misc/emerg-shutdown index 1afebcb..f3496fc 100755 --- a/usr/libexec/security-misc/emerg-shutdown +++ b/usr/libexec/security-misc/emerg-shutdown @@ -1,7 +1,7 @@ #!/bin/bash -# Copyright (C) 2025 - 2025 ENCRYPTED SUPPORT LLC -# See the file COPYING for copying conditions. +## Copyright (C) 2025 - 2025 ENCRYPTED SUPPORT LLC +## See the file COPYING for copying conditions. set -o errexit set -o nounset @@ -11,6 +11,14 @@ set -o pipefail ## Make sure globs sort in a predictable, reproducible fashion export LC_ALL=C +in_dracut='false' +if [ -f '/dracut-state.sh' ]; then + in_dracut='true' +fi +binary_prefix='/run' +EMERG_SHUTDOWN_KEYS='' +root_devices[0]='' + ## Read emergency shutdown key configuration for config_file in /etc/security-misc/emerg-shutdown/*.conf /usr/local/etc/security-misc/emerg-shutdown/*.conf; do if [ -f "${config_file}" ]; then @@ -18,38 +26,40 @@ for config_file in /etc/security-misc/emerg-shutdown/*.conf /usr/local/etc/secur source "${config_file}" fi done -if [ -z "${EMERG_SHUTDOWN_KEYS}" ]; then - ## Default to Ctrl+Alt+Delete if nothing else is set - EMERG_SHUTDOWN_KEYS="KEY_LEFTCTRL|KEY_RIGHTCTRL,KEY_LEFTALT|KEY_RIGHTALT,KEY_DELETE" -fi -## Find the devices that make up the root device -readarray -t root_devices < <(/usr/libexec/helper-scripts/get-backing-devices-for-mountpoint '/') || true; -if [ "${#root_devices[@]}" = '0' ] \ - || [ "${root_devices[0]}" == '' ]; then - ## /dev/sda1 might be the right one... - root_devices[0]='/dev/sda1' -fi +if [ "${in_dracut}" = 'true' ]; then + binary_prefix='' + modprobe evdev || { + printf '%s\n' 'Failed to load evdev driver!' + exit 1 + } + ## modules may not work immediately after loaded, give them time to + ## initialize + sleep 0.1 +else + ## Find the devices that make up the root device + readarray -t root_devices < <(/usr/libexec/helper-scripts/get-backing-devices-for-mountpoint '/') || true; -## Build the actual emerg-shutdown executable -if [ ! -f '/run/emerg-shutdown' ]; then - gcc \ - -o \ - /run/emerg-shutdown \ - -static \ - /usr/src/security-misc/emerg-shutdown.c \ - || { - printf "%s\n" 'Could not compile force-shutdown executable!' - exit 1; - } + ## Build the actual emerg-shutdown executable + if [ ! -f '/run/emerg-shutdown' ]; then + gcc \ + -o \ + /run/emerg-shutdown \ + -static \ + /usr/src/security-misc/emerg-shutdown.c \ + || { + printf "%s\n" 'Could not compile force-shutdown executable!' + exit 1 + } + fi + + ## memlockd daemonizes itself, so no need to background it. + memlockd -c /usr/share/security-misc/security-misc-memlockd.cfg || true fi systemd-notify --ready -## memlockd daemonizes itself, so no need to background it. -memlockd -c /usr/share/security-misc/security-misc-memlockd.cfg || true - ## Launch emerg-shutdown OLDIFS="$IFS" IFS=',' -/run/emerg-shutdown "--devices=${root_devices[*]}" "--keys=${EMERG_SHUTDOWN_KEYS}" +"${binary_prefix}/emerg-shutdown" "--devices=${root_devices[*]}" "--keys=${EMERG_SHUTDOWN_KEYS}" diff --git a/usr/share/security-misc/emerg-shutdown-initramfs.service b/usr/share/security-misc/emerg-shutdown-initramfs.service new file mode 100644 index 0000000..8de5412 --- /dev/null +++ b/usr/share/security-misc/emerg-shutdown-initramfs.service @@ -0,0 +1,21 @@ +## Copyright (C) 2025 - 2025 ENCRYPTED SUPPORT LLC +## See the file COPYING for copying conditions. + +## This file should not be installed on the host system, it is intended for +## inclusion in a dracut initramfs only. + +[Unit] +Description=Emergency shutdown when boot media is removed +Documentation=https://github.com/Kicksecure/security-misc +DefaultDependencies=no +Before=sysinit.target +Requires=systemd-udevd.service +After=systemd-udevd.service + +[Service] +Type=notify +ExecStart=/usr/libexec/security-misc/emerg-shutdown +NotifyAccess=main + +[Install] +WantedBy=sysinit.target