Merge pull request #10425 from acrogenesis/security/root-owned-sleep-hooks

Harden ownership of installed sleep hooks
This commit is contained in:
Ryan Hughes authored and GitHub committed 2026-09-06 19:36:07 -04:00
commit c82a0837b0
8 files changed
+1189 -21

No files matched your search

+38 -3
View File
@@ -30,6 +30,35 @@ MKINITCPIO_CONF="/etc/mkinitcpio.conf.d/omarchy_resume.conf"
SWAP_FILE="/swap/swapfile"
RESUME_DROP_IN="/etc/limine-entry-tool.d/resume.conf"
install_root_file() {
local source="$1"
local destination="$2"
local mode="$3"
local stage
stage=$(sudo /usr/bin/mktemp -- "${destination%/*}/.${destination##*/}.omarchy.XXXXXX") || return 1
safe_stage_path "$stage" "$destination" || return 1
if sudo /usr/bin/install -m "$mode" -o root -g root -T "$source" "$stage" &&
sudo /usr/bin/mv -Tf -- "$stage" "$destination"; then
return 0
else
safe_stage_path "$stage" "$destination" && sudo /usr/bin/rm -f -- "$stage"
return 1
fi
}
safe_stage_path() {
local stage="$1"
local destination="$2"
local prefix suffix
prefix="${destination%/*}/.${destination##*/}.omarchy."
[[ $stage == "$prefix"* ]] || return 1
suffix=${stage#"$prefix"}
[[ $suffix =~ ^[[:alnum:]]{6}$ ]]
}
# Check if hibernation is already configured
if [[ -f $MKINITCPIO_CONF ]] && grep -q "^HOOKS+=(resume)$" "$MKINITCPIO_CONF"; then
# Fix empty resume_offset if btrfs map-swapfile failed during initial setup
@@ -83,14 +112,20 @@ if ! swapon --show | grep -q "$SWAP_FILE"; then
sudo swapon -p 0 "$SWAP_FILE"
fi
# Ensure keyboard backlight doesn't prevent sleep
# Install this before writing the resume marker so a failed install remains
# retryable through the normal setup command.
if ! install_root_file "$OMARCHY_PATH/default/systemd/system-sleep/keyboard-backlight" \
/usr/lib/systemd/system-sleep/keyboard-backlight 0755; then
echo "Could not install the keyboard-backlight system-sleep hook" >&2
exit 1
fi
# Add resume hook to mkinitcpio
sudo mkdir -p /etc/mkinitcpio.conf.d
echo "Adding resume hook to $MKINITCPIO_CONF"
echo "HOOKS+=(resume)" | sudo tee "$MKINITCPIO_CONF" >/dev/null
# Ensure keyboard backlight doesn't prevent sleep
sudo cp -p "$OMARCHY_PATH/default/systemd/system-sleep/keyboard-backlight" /usr/lib/systemd/system-sleep/
# Add resume= kernel parameters so the initramfs resume hook knows where to find the
# hibernation image. Without these, resume happens late (after GPU drivers load) and fails.
if [[ ! -f $RESUME_DROP_IN ]]; then
+51 -9
View File
@@ -3,6 +3,35 @@
# omarchy:summary=Toggle dedicated vs integrated GPU mode via supergfxd (for hybrid gpu laptops, like Asus G14).
# omarchy:requires-sudo=true
install_root_file() {
local source="$1"
local destination="$2"
local mode="$3"
local stage
stage=$(sudo /usr/bin/mktemp -- "${destination%/*}/.${destination##*/}.omarchy.XXXXXX") || return 1
safe_stage_path "$stage" "$destination" || return 1
if sudo /usr/bin/install -m "$mode" -o root -g root -T "$source" "$stage" &&
sudo /usr/bin/mv -Tf -- "$stage" "$destination"; then
return 0
else
safe_stage_path "$stage" "$destination" && sudo /usr/bin/rm -f -- "$stage"
return 1
fi
}
safe_stage_path() {
local stage="$1"
local destination="$2"
local prefix suffix
prefix="${destination%/*}/.${destination##*/}.omarchy."
[[ $stage == "$prefix"* ]] || return 1
suffix=${stage#"$prefix"}
[[ $suffix =~ ^[[:alnum:]]{6}$ ]]
}
if omarchy-cmd-missing supergfxctl; then
omarchy-pkg-add supergfxctl
@@ -54,18 +83,31 @@ case "$gpu_mode" in
;;
"Hybrid")
if gum confirm "Use only integrated GPU and reboot?"; then
# Switch to integrated mode and ensure vfio is enabled (needed for sleep/wake trick)
sudo sed -i "s/\"mode\": \".*\"/\"mode\": \"Integrated\"/" /etc/supergfxd.conf
sudo sed -i 's/"vfio_enable": false/"vfio_enable": true/' /etc/supergfxd.conf
# Force igpu mode after system sleep (or dgpu could get activated)
sudo mkdir -p /usr/lib/systemd/system-sleep
sudo cp -p "$OMARCHY_PATH/default/systemd/system-sleep/force-igpu" /usr/lib/systemd/system-sleep/
# Delay supergfxd startup to avoid race condition with display manager
# that can cause system freeze when booting in Integrated mode
sudo mkdir -p /etc/systemd/system/supergfxd.service.d
sudo cp -p "$OMARCHY_PATH/default/systemd/system/supergfxd.service.d/delay-start.conf" /etc/systemd/system/supergfxd.service.d/
if ! install_root_file "$OMARCHY_PATH/default/systemd/system/supergfxd.service.d/delay-start.conf" \
/etc/systemd/system/supergfxd.service.d/delay-start.conf 0644; then
echo "Could not install the supergfxd startup-delay override" >&2
exit 1
fi
# Publish the self-guarding sleep hook before enabling Integrated mode. It
# remains inert while the config says Hybrid, so any failed step is safe to
# retry without leaving the GPU config partially switched.
sudo mkdir -p /usr/lib/systemd/system-sleep
if ! install_root_file "$OMARCHY_PATH/default/systemd/system-sleep/force-igpu" \
/usr/lib/systemd/system-sleep/force-igpu 0755; then
echo "Could not install the force-igpu system-sleep hook" >&2
exit 1
fi
# Switch both settings in one atomic config rewrite only after every
# supporting file has been installed successfully.
sudo sed -i \
-e 's/"mode": ".*"/"mode": "Integrated"/' \
-e 's/"vfio_enable": false/"vfio_enable": true/' \
/etc/supergfxd.conf
omarchy-system-reboot
fi
+42 -6
View File
@@ -1,29 +1,65 @@
#!/bin/bash
set -e
# Use the Vfio to Integrated trick to turn off NVIDIA dgpu when in integrated mode
# without needing to restart the computer. This is needed because computers like the Asus G14
# will wake after suspend in Hybrid mode, even if the system was in Integrated mode before
# suspending.
restore_marker=/run/omarchy-force-igpu-integrated
sleep_action=${SYSTEMD_SLEEP_ACTION:-$2}
[[ -x /usr/bin/supergfxctl ]] || exit 0
switch_mode() {
local expected="$1" current
if ! /usr/bin/timeout --kill-after=1s 3s /usr/bin/supergfxctl -m "$expected"; then
echo "Could not request the GPU transition to $expected mode" >&2
return 1
fi
for _ in {1..10}; do
if current=$(/usr/bin/timeout --kill-after=1s 2s /usr/bin/supergfxctl -g 2>/dev/null) &&
[[ $current == "$expected" ]]; then
return 0
fi
sleep 1
done
echo "Could not confirm the GPU transition to $expected mode" >&2
return 1
}
case "$1" in
pre)
# Remember the mode this sleep cycle started in. supergfxctl persists the
# temporary hibernate switch to Vfio, so post must not consult that mutable
# value when deciding whether to restore Integrated mode.
if [[ -L $restore_marker ]]; then
exit 1
elif [[ ! -f $restore_marker ]]; then
/usr/bin/grep -Eq '"mode"[[:space:]]*:[[:space:]]*"Integrated"' /etc/supergfxd.conf 2>/dev/null || exit 0
/usr/bin/install -m 0600 -o root -g root -T /dev/null "$restore_marker"
fi
# Before hibernating, switch to Vfio so the nvidia driver is detached from the dGPU.
# Without this, hibernate resume fails because the nvidia driver can't freeze a
# powered-off dGPU (returns -EIO), which aborts the entire resume.
if [[ $2 == "hibernate" ]]; then
/usr/bin/supergfxctl -m Vfio
sleep 1
if [[ $sleep_action == "hibernate" ]]; then
switch_mode Vfio
fi
;;
post)
[[ -f $restore_marker && ! -L $restore_marker ]] || exit 0
# small delay so the device is fully re-enumerated
sleep 4
# force-bind dGPU to vfio (fully detached from nvidia)
/usr/bin/supergfxctl -m Vfio
sleep 1
switch_mode Vfio
# then go back to Integrated, which powers it off again
/usr/bin/supergfxctl -m Integrated
switch_mode Integrated
/usr/bin/rm -f -- "$restore_marker"
;;
esac
@@ -3,7 +3,9 @@
# Turn off keyboard backlight before hibernate to prevent hang on power-off.
# The ASUS keyboard controller can block S4 shutdown if LEDs are active.
if [[ $1 == "pre" && $2 == "hibernate" ]]; then
sleep_action=${SYSTEMD_SLEEP_ACTION:-$2}
if [[ $1 == "pre" && $sleep_action == "hibernate" ]]; then
device=""
for candidate in /sys/class/leds/*kbd_backlight*; do
if [[ -e "$candidate" ]]; then
+3 -2
View File
@@ -124,8 +124,7 @@ default/** ──► omarchy-settings /usr/share/omarchy
├─ applications/mimeapps.list /usr/share/applications/mimeapps.list
├─ systemd/user/*.service /usr/lib/systemd/user/
├─ systemd/user/app.slice.d/10-oomd.conf /usr/lib/systemd/user/app.slice.d/
├─ systemd/system-sleep/{force-igpu,
│ keyboard-backlight,unmount-fuse} /usr/lib/systemd/system-sleep/
├─ systemd/system-sleep/unmount-fuse /usr/lib/systemd/system-sleep/
├─ systemd/zram-generator.conf.d/90-omarchy.conf /usr/lib/systemd/zram-generator.conf.d/
├─ fonts/omarchy/omarchy.ttf /usr/share/fonts/omarchy/
├─ sddm/omarchy/ /usr/share/sddm/themes/omarchy/
@@ -139,6 +138,8 @@ logo.{txt,svg}, icon.{txt,png} ──► omarchy-settings /usr/share/omarchy
/etc/skel/.config/omarchy/branding/{about,screensaver}.txt
```
The hardware-conditional `force-igpu` and `keyboard-backlight` sources also live under `default/systemd/system-sleep/`, but their setup commands publish root-owned copies only on machines that need them; they are not installed by `omarchy-settings`.
### Why `etc-overrides/` exists
Some files under `/etc/` (`.bashrc` in `/etc/skel`, `nsswitch.conf`,
+303
View File
@@ -0,0 +1,303 @@
echo "Repair user-owned system-sleep hooks and hybrid GPU service configuration"
system_sleep_dir=/usr/lib/systemd/system-sleep
supergfxd_drop_in=/etc/systemd/system/supergfxd.service.d/delay-start.conf
quarantine_root=/var/lib/omarchy/migrations/1788662350-system-sleep
reload_needed_marker=/var/lib/omarchy/migrations/1788662350-systemd-reload-needed
keyboard_source="$OMARCHY_PATH/default/systemd/system-sleep/keyboard-backlight"
force_igpu_source="$OMARCHY_PATH/default/systemd/system-sleep/force-igpu"
supergfxd_source="$OMARCHY_PATH/default/systemd/system/supergfxd.service.d/delay-start.conf"
legacy_keyboard_sha256=f313a81e47401f0d38b8602e5997f52c5286d5e97f74027564ddd515b3d16511
legacy_force_igpu_sha256=d604e7c4903829563e45fc52188fc5602c3f1bc66e247f0a2cc0a974ed6e57db
as_root() {
if (( EUID == 0 )); then
"$@"
else
sudo "$@"
fi
}
path_is_root_controlled() {
local path="$1"
local current=/ component candidate file_mode link metadata part status uid gid mode
local missing_depth=0 symlink_count=0
local -a pending resolved link_components
[[ $path == /* ]] || return 1
IFS=/ read -r -a pending <<<"$path"
# A non-root group is harmless when neither it nor everyone else can write.
# Resolve symlinks component by component so an indirect link cannot hide an
# intermediate directory controlled by an unprivileged user.
metadata=$(path_metadata /) || return 1
read -r file_mode uid gid mode <<<"$metadata"
(( uid == 0 && (8#$mode & 8#022) == 0 )) || return 1
while ((${#pending[@]})); do
component=${pending[0]}
pending=("${pending[@]:1}")
[[ -n $component ]] || continue
[[ $component == "." ]] && continue
if [[ $component == ".." ]]; then
if ((${#resolved[@]})); then
unset 'resolved[-1]'
fi
current=/
for part in "${resolved[@]}"; do
if [[ $current == "/" ]]; then
current="/$part"
else
current="$current/$part"
fi
done
if (( missing_depth > 0 && ${#resolved[@]} < missing_depth )); then
missing_depth=0
fi
continue
fi
if [[ $current == "/" ]]; then
candidate="/$component"
else
candidate="$current/$component"
fi
if (( missing_depth > 0 )); then
# The first missing component makes descendants inactive today, but keep
# consuming the lexical suffix. A later .. can escape back into an
# existing user-controlled path that would become active if an
# administrator creates the missing directory.
resolved+=("$component")
current=$candidate
continue
elif metadata=$(path_metadata "$candidate"); then
read -r file_mode uid gid mode <<<"$metadata"
else
status=$?
if (( status == 2 )); then
resolved+=("$component")
current=$candidate
missing_depth=${#resolved[@]}
continue
else
return 1
fi
fi
if (( (16#$file_mode & 16#f000) == 16#a000 )); then
((++symlink_count <= 40)) || return 1
link=$(readlink_with_privilege "$candidate") || return 1
IFS=/ read -r -a link_components <<<"$link"
pending=("${link_components[@]}" "${pending[@]}")
if [[ $link == /* ]]; then
resolved=()
current=/
fi
continue
fi
(( uid == 0 && (8#$mode & 8#022) == 0 )) || return 1
resolved+=("$component")
current=$candidate
done
}
path_metadata() {
local path="$1"
local metadata parent
if /usr/bin/stat -c '%f %u %g %a' -- "$path" 2>/dev/null; then
return 0
elif [[ ! -e $path && ! -L $path ]]; then
parent=${path%/*}
[[ -n $parent ]] || parent=/
# Avoid asking for sudo for ordinary ENOENT. If the parent is searchable,
# the absence is conclusive; an inaccessible root-only chain still needs a
# privileged metadata check so safe administrator symlinks are preserved.
[[ -x $parent ]] && return 2
if metadata=$(as_root /usr/bin/stat -c '%f %u %g %a' -- "$path" 2>/dev/null); then
printf '%s\n' "$metadata"
return 0
elif as_root /usr/bin/test -x "$parent"; then
# The privileged probe could search the protected parent, so stat's
# failure identifies a target that does not exist yet.
return 2
else
return 1
fi
else
as_root /usr/bin/stat -c '%f %u %g %a' -- "$path"
fi
}
readlink_with_privilege() {
local path="$1"
if /usr/bin/readlink -- "$path" 2>/dev/null; then
return 0
else
as_root /usr/bin/readlink -- "$path"
fi
}
privileged_entry_is_safe() {
local path="$1"
path_is_root_controlled "$path"
}
file_matches_source() {
local source="$1"
local destination="$2"
[[ -f $destination && ! -L $destination ]] || return 1
if [[ -r $destination ]]; then
/usr/bin/cmp -s -- "$source" "$destination"
else
as_root /usr/bin/cmp -s -- "$source" "$destination"
fi
}
file_matches_sha256() {
local destination="$1"
local expected="$2"
local digest
[[ -f $destination && ! -L $destination ]] || return 1
if [[ -r $destination ]]; then
digest=$(/usr/bin/sha256sum -- "$destination") || return 1
else
digest=$(as_root /usr/bin/sha256sum -- "$destination") || return 1
fi
[[ ${digest%% *} == "$expected" ]]
}
safe_stage_path() {
local stage="$1"
local destination="$2"
local prefix suffix
prefix="${destination%/*}/.${destination##*/}.omarchy."
[[ $stage == "$prefix"* ]] || return 1
suffix=${stage#"$prefix"}
[[ $suffix =~ ^[[:alnum:]]{6}$ ]]
}
install_root_file() {
local source="$1"
local destination="$2"
local mode="$3"
local stage
stage=$(as_root /usr/bin/mktemp -- "${destination%/*}/.${destination##*/}.omarchy.XXXXXX") || return 1
safe_stage_path "$stage" "$destination" || return 1
if as_root /usr/bin/install -m "$mode" -o root -g root -T "$source" "$stage" &&
as_root /usr/bin/mv -Tf -- "$stage" "$destination"; then
return 0
else
safe_stage_path "$stage" "$destination" && as_root /usr/bin/rm -f -- "$stage"
return 1
fi
}
preserve_unsafe_customization() {
local path="$1"
local label="$2"
local backup_dir backup
if ! as_root /usr/bin/install -d -m 0700 -o root -g root "$quarantine_root"; then
echo "Could not create the root-only system-sleep quarantine at $quarantine_root" >&2
return 1
fi
if ! backup_dir=$(as_root /usr/bin/mktemp -d -- "$quarantine_root/${label}.XXXXXX"); then
echo "Could not reserve a quarantine path for $path" >&2
return 1
fi
backup="$backup_dir/original"
if as_root /usr/bin/cp -a --no-dereference -T -- "$path" "$backup"; then
printf '%s\n' "$backup"
else
as_root /usr/bin/rm -rf -- "$backup_dir"
echo "Could not preserve unsafe custom content from $path before repairing it" >&2
return 1
fi
}
repair_unsafe_privileged_entry() {
local source="$1"
local destination="$2"
local mode="$3"
local label="$4"
local legacy_sha256="${5:-}"
local backup current_mode
[[ -e $destination || -L $destination ]] || return 0
[[ -f $destination || -L $destination ]] || return 0
if file_matches_source "$source" "$destination"; then
current_mode=$(/usr/bin/stat -c '%a' -- "$destination" 2>/dev/null) ||
current_mode=$(as_root /usr/bin/stat -c '%a' -- "$destination") || return 1
if privileged_entry_is_safe "$destination" && [[ $current_mode == "${mode#0}" ]]; then
return 0
fi
elif [[ -n $legacy_sha256 ]] && file_matches_sha256 "$destination" "$legacy_sha256"; then
:
else
privileged_entry_is_safe "$destination" && return 0
backup=$(preserve_unsafe_customization "$destination" "$label") || return 1
fi
if install_root_file "$source" "$destination" "$mode"; then
if [[ -n ${backup:-} ]]; then
echo "Preserved unsafe custom content from $destination at $backup for administrator review" >&2
fi
else
if [[ -n ${backup:-} ]]; then
echo "Preserved unsafe custom content from $destination at $backup, but could not repair the active path" >&2
fi
return 1
fi
}
# Replace rather than chown an unsafe destination: its current owner may have
# already changed the contents or kept a writable file descriptor open. The
# root-owned staging inode makes the final rename an atomic trust transition.
repair_unsafe_privileged_entry "$keyboard_source" \
"$system_sleep_dir/keyboard-backlight" 0755 keyboard-backlight "$legacy_keyboard_sha256"
force_igpu="$system_sleep_dir/force-igpu"
repair_unsafe_privileged_entry "$force_igpu_source" "$force_igpu" 0755 force-igpu "$legacy_force_igpu_sha256"
systemd_reload_needed=false
if [[ -e $reload_needed_marker || -L $reload_needed_marker ]]; then
systemd_reload_needed=true
fi
if [[ -e $supergfxd_drop_in || -L $supergfxd_drop_in ]]; then
if ! privileged_entry_is_safe "$supergfxd_drop_in"; then
# Replacing the drop-in and reloading systemd are one repair. Record the
# second half before changing the file so failure or interruption cannot
# be forgotten when a retry sees only the trusted replacement on disk.
if ! as_root /usr/bin/install -Dm0644 -o root -g root /dev/null "$reload_needed_marker"; then
echo "Could not persist the pending systemd reload for the repaired supergfxd configuration" >&2
exit 1
fi
systemd_reload_needed=true
repair_unsafe_privileged_entry "$supergfxd_source" "$supergfxd_drop_in" 0644 delay-start.conf
fi
fi
if $systemd_reload_needed; then
if ! as_root /usr/bin/systemctl daemon-reload; then
echo "Could not reload systemd after repairing the supergfxd configuration; the migration will retry" >&2
exit 1
fi
if ! as_root /usr/bin/rm -f -- "$reload_needed_marker"; then
echo "Could not clear the pending systemd reload marker; the migration will retry" >&2
exit 1
fi
fi
@@ -0,0 +1,705 @@
#!/bin/bash
set -euo pipefail
source "$(dirname "$0")/base-test.sh"
migration="$ROOT/migrations/1788662350.sh"
test_tmp=$(mktemp -d -p /tmp)
trap 'rm -rf "$test_tmp"' EXIT
mock_omarchy="$test_tmp/omarchy"
sleep_dir="$test_tmp/system-sleep"
systemd_dir="$test_tmp/systemd"
drop_in="$systemd_dir/supergfxd.service.d/delay-start.conf"
quarantine="$test_tmp/quarantine"
reload_needed_marker="$test_tmp/reload-needed"
migration_copy="$test_tmp/migration.sh"
stub_bin="$test_tmp/bin"
calls="$test_tmp/calls"
mkdir -p "$mock_omarchy/default/systemd/system-sleep" \
"$mock_omarchy/default/systemd/system/supergfxd.service.d" \
"$sleep_dir" "${drop_in%/*}" "$stub_bin"
cp "$ROOT/default/systemd/system-sleep/keyboard-backlight" \
"$mock_omarchy/default/systemd/system-sleep/keyboard-backlight"
cp "$ROOT/default/systemd/system-sleep/force-igpu" \
"$mock_omarchy/default/systemd/system-sleep/force-igpu"
cp "$ROOT/default/systemd/system/supergfxd.service.d/delay-start.conf" \
"$mock_omarchy/default/systemd/system/supergfxd.service.d/delay-start.conf"
[[ $(grep -Fxc 'system_sleep_dir=/usr/lib/systemd/system-sleep' "$migration") == 1 ]] ||
fail "migration fixes one literal system-sleep directory"
[[ $(grep -Fxc 'supergfxd_drop_in=/etc/systemd/system/supergfxd.service.d/delay-start.conf' "$migration") == 1 ]] ||
fail "migration fixes one literal supergfxd drop-in"
sed \
-e "s|system_sleep_dir=/usr/lib/systemd/system-sleep|system_sleep_dir=$sleep_dir|" \
-e "s|supergfxd_drop_in=/etc/systemd/system/supergfxd.service.d/delay-start.conf|supergfxd_drop_in=$drop_in|" \
-e "s|quarantine_root=/var/lib/omarchy/migrations/1788662350-system-sleep|quarantine_root=$quarantine|" \
-e "s|/var/lib/omarchy/migrations/1788662350-systemd-reload-needed|$reload_needed_marker|" \
-e "s|/usr/bin/stat|$stub_bin/stat|g" \
-e "s|/usr/bin/readlink|$stub_bin/readlink|g" \
"$migration" >"$migration_copy"
cat >"$stub_bin/stat" <<'SH'
#!/bin/bash
path=${!#}
if [[ :${INACCESSIBLE_AS_USER:-}: == *":$path:"* && ${FAKE_SUDO:-0} == 0 ]]; then
exit 13
fi
actual_file_mode=$(/usr/bin/stat -c '%f' -- "$path") || exit 1
actual_mode=$(/usr/bin/stat -c '%a' -- "$path") || exit 1
if [[ :${FAKE_ROOT_DIRS:-}: == *":$path:"* ]]; then
uid=0
gid=0
mode=$(printf '%o' "$((8#$actual_mode & ~8#022))")
elif [[ :${FAKE_ROOT_FILES:-}: == *":$path:"* ]]; then
uid=0
gid=${FAKE_ROOT_GID:-0}
mode=${FAKE_ROOT_MODE:-$actual_mode}
else
exec /usr/bin/stat "$@"
fi
file_type=$((16#$actual_file_mode & 16#f000))
file_mode=$(printf '%x' "$((file_type | 8#$mode))")
case "$*" in
*"%f %u %g %a"*) printf '%s %s %s %s\n' "$file_mode" "$uid" "$gid" "$mode" ;;
*"%u %g %a"*) printf '%s %s %s\n' "$uid" "$gid" "$mode" ;;
*"%a"*) printf '%s\n' "$mode" ;;
*) exec /usr/bin/stat "$@" ;;
esac
SH
cat >"$stub_bin/readlink" <<'SH'
#!/bin/bash
path=${!#}
if [[ :${INACCESSIBLE_AS_USER:-}: == *":$path:"* && ${FAKE_SUDO:-0} == 0 ]]; then
exit 13
fi
exec /usr/bin/readlink "$@"
SH
chmod +x "$stub_bin/stat" "$stub_bin/readlink"
cat >"$stub_bin/sudo" <<'SH'
#!/bin/bash
set -euo pipefail
printf 'sudo' >>"$CALLS"
printf '\t%s' "$@" >>"$CALLS"
printf '\n' >>"$CALLS"
case "$1" in
*/stat | */readlink)
FAKE_SUDO=1 exec "$@"
;;
/usr/bin/test)
shift
if [[ $1 == "-x" && :${FAKE_ROOT_DIRS:-}: == *":$2:"* ]]; then
exit 0
else
exec /usr/bin/test "$@"
fi
;;
/usr/bin/mktemp | /usr/bin/mv | /usr/bin/chmod | /usr/bin/cp | /usr/bin/rm)
exec "$@"
;;
/usr/bin/systemctl)
if [[ -n ${SYSTEMCTL_FAIL_ONCE_FILE:-} && -e $SYSTEMCTL_FAIL_ONCE_FILE ]]; then
/usr/bin/rm -f -- "$SYSTEMCTL_FAIL_ONCE_FILE"
exit 1
fi
exit 0
;;
/usr/bin/install)
shift
args=()
while (($#)); do
case "$1" in
-o | -g)
shift 2
;;
*)
args+=("$1")
shift
;;
esac
done
exec /usr/bin/install "${args[@]}"
;;
*)
printf 'unexpected sudo command: %s\n' "$*" >&2
exit 97
;;
esac
SH
chmod +x "$stub_bin/sudo"
run_migration() {
local fake_root_dirs
: >"$calls"
fake_root_dirs="/:/tmp:$test_tmp:$sleep_dir:$systemd_dir:${drop_in%/*}"
[[ -z ${EXTRA_FAKE_ROOT_DIRS:-} ]] || fake_root_dirs+=":$EXTRA_FAKE_ROOT_DIRS"
CALLS="$calls" \
FAKE_ROOT_DIRS="$fake_root_dirs" \
FAKE_ROOT_FILES="${FAKE_ROOT_FILES:-${2:-}}" \
FAKE_ROOT_MODE="${FAKE_ROOT_MODE:-${3:-}}" \
FAKE_ROOT_GID="${FAKE_ROOT_GID:-0}" \
INACCESSIBLE_AS_USER="${INACCESSIBLE_AS_USER:-}" \
SYSTEMCTL_FAIL_ONCE_FILE="${SYSTEMCTL_FAIL_ONCE_FILE:-}" \
OMARCHY_PATH="$mock_omarchy" \
PATH="$stub_bin:$PATH" bash -euo pipefail "$migration_copy" >/dev/null
}
printf 'attacker keyboard\n' >"$sleep_dir/keyboard-backlight"
printf 'attacker gpu\n' >"$sleep_dir/force-igpu"
printf 'attacker drop-in\n' >"$drop_in"
chmod 0777 "$sleep_dir/keyboard-backlight" "$sleep_dir/force-igpu"
chmod 0666 "$drop_in"
exec 9>>"$sleep_dir/keyboard-backlight"
run_migration Integrated
printf 'write through stale attacker descriptor\n' >&9
exec 9>&-
cmp -s "$mock_omarchy/default/systemd/system-sleep/keyboard-backlight" "$sleep_dir/keyboard-backlight" ||
fail "migration replaces the user-owned keyboard hook with trusted content"
cmp -s "$mock_omarchy/default/systemd/system-sleep/force-igpu" "$sleep_dir/force-igpu" ||
fail "migration replaces the user-owned GPU hook with trusted content"
cmp -s "$mock_omarchy/default/systemd/system/supergfxd.service.d/delay-start.conf" "$drop_in" ||
fail "migration replaces the user-owned root service drop-in with trusted content"
[[ $(stat -c '%a' "$sleep_dir/keyboard-backlight") == 755 ]] ||
fail "migration activates the repaired keyboard hook"
[[ $(stat -c '%a' "$sleep_dir/force-igpu") == 755 ]] ||
fail "migration activates force-igpu only in Integrated mode"
[[ $(stat -c '%a' "$drop_in") == 644 ]] ||
fail "migration installs the service drop-in as configuration"
grep -Fx $'sudo\t/usr/bin/systemctl\tdaemon-reload' "$calls" >/dev/null ||
fail "migration reloads systemd after repairing its root service drop-in"
[[ ! -e $reload_needed_marker ]] ||
fail "migration leaves a reload marker after systemd accepted the repaired drop-in"
[[ $(stat -c '%a' "$quarantine") == 700 ]] ||
fail "migration keeps preserved unsafe custom content in a root-only directory"
keyboard_backup=$(find "$quarantine" -path '*/keyboard-backlight.*/original' -type f -print -quit)
force_backup=$(find "$quarantine" -path '*/force-igpu.*/original' -type f -print -quit)
drop_in_backup=$(find "$quarantine" -path '*/delay-start.conf.*/original' -type f -print -quit)
grep -Fxq 'attacker keyboard' "$keyboard_backup" ||
fail "migration preserves unknown keyboard-hook content before replacing it"
grep -Fxq 'attacker gpu' "$force_backup" ||
fail "migration preserves unknown force-iGPU content before replacing it"
grep -Fxq 'attacker drop-in' "$drop_in_backup" ||
fail "migration preserves unknown service-drop-in content before replacing it"
pass "migration replaces writable privileged files with trusted root-owned copies"
backup_count=$(find "$quarantine" -mindepth 2 -maxdepth 2 -name original | wc -l)
FAKE_ROOT_FILES="$sleep_dir/keyboard-backlight:$sleep_dir/force-igpu:$drop_in" \
run_migration Integrated
[[ ! -s $calls ]] ||
fail "migration changes already-repaired privileged files on a second run" "$(<"$calls")"
[[ $(find "$quarantine" -mindepth 2 -maxdepth 2 -name original | wc -l) == "$backup_count" ]] ||
fail "migration creates duplicate quarantines on a second run"
pass "migration is idempotent after repairing unsafe privileged files"
printf 'attacker drop-in\n' >"$drop_in"
chmod 0666 "$drop_in"
reload_failure="$test_tmp/fail-systemd-reload-once"
touch "$reload_failure"
set +e
SYSTEMCTL_FAIL_ONCE_FILE="$reload_failure" \
FAKE_ROOT_FILES="$sleep_dir/keyboard-backlight:$sleep_dir/force-igpu" \
run_migration Integrated
reload_status=$?
set -e
(( reload_status != 0 )) ||
fail "migration reports success after systemd rejects the repaired drop-in"
cmp -s "$mock_omarchy/default/systemd/system/supergfxd.service.d/delay-start.conf" "$drop_in" ||
fail "migration does not repair the drop-in before the simulated reload failure"
[[ -e $reload_needed_marker && $(stat -c '%a' "$reload_needed_marker") == 644 ]] ||
fail "migration does not persist the reload requirement before replacing the drop-in"
FAKE_ROOT_FILES="$sleep_dir/keyboard-backlight:$sleep_dir/force-igpu:$drop_in" \
run_migration Integrated
grep -Fx $'sudo\t/usr/bin/systemctl\tdaemon-reload' "$calls" >/dev/null ||
fail "migration does not retry a failed reload after the drop-in is already safe"
[[ ! -e $reload_needed_marker ]] ||
fail "migration does not clear the reload requirement after a successful retry"
FAKE_ROOT_FILES="$sleep_dir/keyboard-backlight:$sleep_dir/force-igpu:$drop_in" \
run_migration Integrated
[[ ! -s $calls ]] ||
fail "migration repeats a successfully completed reload repair" "$(<"$calls")"
pass "migration persists and retries systemd reload after failure or interruption"
keyboard_backup_count=$(find "$quarantine" -path '*/keyboard-backlight.*/original' | wc -l)
cp "$mock_omarchy/default/systemd/system-sleep/keyboard-backlight" \
"$sleep_dir/keyboard-backlight"
chmod 0644 "$sleep_dir/keyboard-backlight"
FAKE_ROOT_FILES="$sleep_dir/force-igpu:$drop_in" run_migration Integrated
[[ $(stat -c '%a' "$sleep_dir/keyboard-backlight") == 755 ]] ||
fail "migration does not safely activate a user-owned canonical hook"
[[ $(find "$quarantine" -path '*/keyboard-backlight.*/original' | wc -l) == "$keyboard_backup_count" ]] ||
fail "migration quarantines an exact legacy artifact as administrator content"
pass "migration replaces exact vulnerable installer artifacts without inventing backups"
legacy_keyboard="$test_tmp/legacy-keyboard-backlight"
cat >"$legacy_keyboard" <<'SH'
#!/bin/bash
# Turn off keyboard backlight before hibernate to prevent hang on power-off.
# The ASUS keyboard controller can block S4 shutdown if LEDs are active.
if [[ $1 == "pre" && $2 == "hibernate" ]]; then
device=""
for candidate in /sys/class/leds/*kbd_backlight*; do
if [[ -e "$candidate" ]]; then
device="$(basename "$candidate")"
break
fi
done
if [[ -n "$device" ]]; then
brightnessctl -d "$device" set 0 >/dev/null 2>&1
fi
fi
SH
[[ $(sha256sum "$legacy_keyboard" | cut -d' ' -f1) == f313a81e47401f0d38b8602e5997f52c5286d5e97f74027564ddd515b3d16511 ]] ||
fail "keyboard-backlight legacy fixture no longer matches the migration fingerprint"
keyboard_backup_count=$(find "$quarantine" -path '*/keyboard-backlight.*/original' | wc -l)
cp "$legacy_keyboard" "$sleep_dir/keyboard-backlight"
chmod 0644 "$sleep_dir/keyboard-backlight"
FAKE_ROOT_FILES="$sleep_dir/keyboard-backlight:$sleep_dir/force-igpu:$drop_in" \
run_migration Integrated
cmp -s "$mock_omarchy/default/systemd/system-sleep/keyboard-backlight" "$sleep_dir/keyboard-backlight" ||
fail "migration does not upgrade the released keyboard-backlight hook"
[[ $(stat -c '%a' "$sleep_dir/keyboard-backlight") == 755 ]] ||
fail "migration leaves the released keyboard-backlight hook non-executable"
[[ $(find "$quarantine" -path '*/keyboard-backlight.*/original' | wc -l) == "$keyboard_backup_count" ]] ||
fail "migration quarantines the released keyboard hook as administrator content"
pass "migration activates the released root-owned keyboard-backlight hook"
cp "$legacy_keyboard" "$sleep_dir/keyboard-backlight"
chmod 0755 "$sleep_dir/keyboard-backlight"
FAKE_ROOT_FILES="$sleep_dir/keyboard-backlight:$sleep_dir/force-igpu:$drop_in" \
run_migration Integrated
cmp -s "$mock_omarchy/default/systemd/system-sleep/keyboard-backlight" "$sleep_dir/keyboard-backlight" ||
fail "migration mistakes executable released hook bytes for a current artifact"
pass "migration refreshes recognized legacy hook contents at the final mode"
printf 'attacker gpu\n' >"$sleep_dir/force-igpu"
chmod 0777 "$sleep_dir/force-igpu"
run_migration Hybrid
[[ $(stat -c '%a' "$sleep_dir/force-igpu") == 755 ]] ||
fail "migration does not activate the trusted self-guarding force-igpu hook"
pass "migration repairs force-igpu without depending on a live GPU-mode query"
printf 'administrator customization\n' >"$sleep_dir/keyboard-backlight"
chmod 0755 "$sleep_dir/keyboard-backlight"
run_migration Integrated "$sleep_dir/keyboard-backlight" 755
grep -Fxq 'administrator customization' "$sleep_dir/keyboard-backlight" ||
fail "migration preserves a secure administrator-owned custom hook"
cp "$mock_omarchy/default/systemd/system-sleep/keyboard-backlight" "$sleep_dir/keyboard-backlight"
chmod 0644 "$sleep_dir/keyboard-backlight"
run_migration Integrated "$sleep_dir/keyboard-backlight" 644
[[ $(stat -c '%a' "$sleep_dir/keyboard-backlight") == 755 ]] ||
fail "migration leaves an exact packaged keyboard hook non-executable"
printf 'administrator customization\n' >"$sleep_dir/keyboard-backlight"
chmod 0644 "$sleep_dir/keyboard-backlight"
run_migration Integrated "$sleep_dir/keyboard-backlight" 644
[[ $(stat -c '%a' "$sleep_dir/keyboard-backlight") == 644 ]] ||
fail "migration changes the mode of a safe noncanonical administrator hook"
grep -Fxq 'administrator customization' "$sleep_dir/keyboard-backlight" ||
fail "migration replaces a safe noncanonical administrator hook"
pass "migration activates only exact packaged hooks while preserving safe custom files"
legacy_force_igpu="$test_tmp/legacy-force-igpu"
cat >"$legacy_force_igpu" <<'SH'
#!/bin/bash
# Use the Vfio to Integrated trick to turn off NVIDIA dgpu when in integrated mode
# without needing to restart the computer. This is needed because computers like the Asus G14
# will wake after suspend in Hybrid mode, even if the system was in Integrated mode before
# suspending.
case "$1" in
pre)
# Before hibernating, switch to Vfio so the nvidia driver is detached from the dGPU.
# Without this, hibernate resume fails because the nvidia driver can't freeze a
# powered-off dGPU (returns -EIO), which aborts the entire resume.
if [[ $2 == "hibernate" ]]; then
/usr/bin/supergfxctl -m Vfio
sleep 1
fi
;;
post)
# small delay so the device is fully re-enumerated
sleep 4
# force-bind dGPU to vfio (fully detached from nvidia)
/usr/bin/supergfxctl -m Vfio
sleep 1
# then go back to Integrated, which powers it off again
/usr/bin/supergfxctl -m Integrated
;;
esac
SH
[[ $(sha256sum "$legacy_force_igpu" | cut -d' ' -f1) == d604e7c4903829563e45fc52188fc5602c3f1bc66e247f0a2cc0a974ed6e57db ]] ||
fail "force-igpu legacy fixture no longer matches the migration fingerprint"
cp "$legacy_force_igpu" "$sleep_dir/force-igpu"
chmod 0644 "$sleep_dir/force-igpu"
FAKE_ROOT_FILES="$sleep_dir/keyboard-backlight:$sleep_dir/force-igpu:$drop_in" \
run_migration Integrated
cmp -s "$mock_omarchy/default/systemd/system-sleep/force-igpu" "$sleep_dir/force-igpu" ||
fail "migration does not upgrade the exact legacy force-igpu hook"
[[ $(stat -c '%a' "$sleep_dir/force-igpu") == 755 ]] ||
fail "migration leaves the exact legacy force-igpu hook non-executable"
pass "migration activates the exact legacy force-igpu artifact with its new guard"
printf 'wheel-managed customization\n' >"$sleep_dir/keyboard-backlight"
chmod 0755 "$sleep_dir/keyboard-backlight"
FAKE_ROOT_FILES="$sleep_dir/keyboard-backlight:$sleep_dir/force-igpu:$drop_in" \
FAKE_ROOT_GID=10 run_migration Integrated
grep -Fxq 'wheel-managed customization' "$sleep_dir/keyboard-backlight" ||
fail "migration replaces a safe root:wheel administrator hook"
[[ ! -s $calls ]] ||
fail "migration escalates while preserving safe root:wheel entries"
pass "migration treats non-writable root-owned files as safe regardless of group"
admin_dir="$test_tmp/admin-hooks"
admin_keyboard="$admin_dir/keyboard"
admin_delay="$admin_dir/delay.conf"
mkdir -p "$admin_dir"
printf 'protected keyboard customization\n' >"$admin_keyboard"
printf 'protected delay customization\n' >"$admin_delay"
chmod 0755 "$admin_keyboard"
chmod 0644 "$admin_delay"
rm -f "$sleep_dir/keyboard-backlight" "$drop_in"
ln -s "$admin_keyboard" "$sleep_dir/keyboard-backlight"
ln -s "$admin_delay" "$drop_in"
EXTRA_FAKE_ROOT_DIRS="$admin_dir" \
FAKE_ROOT_FILES="$admin_keyboard:$admin_delay:$sleep_dir/force-igpu" \
FAKE_ROOT_GID=10 run_migration Integrated
[[ -L $sleep_dir/keyboard-backlight && $(readlink "$sleep_dir/keyboard-backlight") == "$admin_keyboard" ]] ||
fail "migration replaces a safe administrator-managed keyboard-hook symlink"
[[ -L $drop_in && $(readlink "$drop_in") == "$admin_delay" ]] ||
fail "migration replaces a safe administrator-managed service-drop-in symlink"
[[ ! -s $calls ]] ||
fail "migration escalates while preserving safe administrator symlinks"
pass "migration preserves symlinks whose full target paths are root-controlled"
dangling_target="$admin_dir/future-keyboard"
rm -f "$sleep_dir/keyboard-backlight" "$dangling_target"
ln -s "$dangling_target" "$sleep_dir/keyboard-backlight"
EXTRA_FAKE_ROOT_DIRS="$admin_dir" \
FAKE_ROOT_FILES="$admin_delay:$sleep_dir/force-igpu:$drop_in" \
run_migration Integrated
[[ -L $sleep_dir/keyboard-backlight && $(readlink "$sleep_dir/keyboard-backlight") == "$dangling_target" ]] ||
fail "migration replaces a safe dangling administrator symlink"
[[ ! -s $calls ]] ||
fail "migration asks for sudo to verify an absent target below a searchable root-controlled directory"
pass "migration handles safe dangling administrator symlinks without sudo"
escaping_user_dir="$test_tmp/escaping-user-hooks"
escaping_user_hook="$escaping_user_dir/keyboard"
escaping_missing_dir="$admin_dir/future"
escaping_target="$escaping_missing_dir/../../escaping-user-hooks/keyboard"
mkdir -p "$escaping_user_dir"
printf 'future unsafe keyboard customization\n' >"$escaping_user_hook"
chmod 0755 "$escaping_user_hook"
rm -f "$sleep_dir/keyboard-backlight"
ln -s "$escaping_target" "$sleep_dir/keyboard-backlight"
EXTRA_FAKE_ROOT_DIRS="$admin_dir" \
FAKE_ROOT_FILES="$admin_delay:$sleep_dir/force-igpu:$drop_in" \
run_migration Integrated
[[ ! -L $sleep_dir/keyboard-backlight ]] ||
fail "migration trusts a dangling symlink whose unresolved suffix escapes to a user-controlled path"
cmp -s "$mock_omarchy/default/systemd/system-sleep/keyboard-backlight" \
"$sleep_dir/keyboard-backlight" ||
fail "migration does not replace a future user-controlled dangling symlink"
pass "migration resolves the full dangling-symlink suffix before trusting it"
protected_dir="$test_tmp/root-only-hooks"
protected_target="$protected_dir/target"
protected_bridge="$protected_dir/bridge"
mkdir -p "$protected_dir"
printf 'root-only administrator customization\n' >"$protected_target"
ln -s "$protected_target" "$protected_bridge"
chmod 0700 "$protected_dir"
rm -f "$sleep_dir/keyboard-backlight"
ln -s "$protected_bridge" "$sleep_dir/keyboard-backlight"
EXTRA_FAKE_ROOT_DIRS="$admin_dir:$protected_dir" \
FAKE_ROOT_FILES="$protected_target:$admin_delay:$sleep_dir/force-igpu:$drop_in" \
INACCESSIBLE_AS_USER="$protected_bridge:$protected_target" \
run_migration Integrated
[[ -L $sleep_dir/keyboard-backlight && $(readlink "$sleep_dir/keyboard-backlight") == "$protected_bridge" ]] ||
fail "migration replaces a safe symlink whose target is hidden by a root-only directory"
grep -q $'^sudo\t.*/stat\t-c\t%f %u %g %a\t--\t.*/root-only-hooks/bridge$' "$calls" ||
fail "migration does not inspect inaccessible symlink metadata with privilege"
grep -q $'^sudo\t.*/readlink\t--\t.*/root-only-hooks/bridge$' "$calls" ||
fail "migration does not resolve an inaccessible administrator symlink with privilege"
grep -q $'^sudo\t.*/stat\t-c\t%f %u %g %a\t--\t.*/root-only-hooks/target$' "$calls" ||
fail "migration does not inspect an inaccessible administrator target with privilege"
pass "migration preserves root-controlled symlink chains hidden from the invoking user"
protected_dangling_dir="$test_tmp/root-only-dangling"
protected_dangling_target="$protected_dangling_dir/future-keyboard"
mkdir -p "$protected_dangling_dir"
chmod 0000 "$protected_dangling_dir"
rm -f "$sleep_dir/keyboard-backlight"
ln -s "$protected_dangling_target" "$sleep_dir/keyboard-backlight"
EXTRA_FAKE_ROOT_DIRS="$admin_dir:$protected_dangling_dir" \
FAKE_ROOT_FILES="$admin_delay:$sleep_dir/force-igpu:$drop_in" \
INACCESSIBLE_AS_USER="$protected_dangling_target" \
run_migration Integrated
[[ -L $sleep_dir/keyboard-backlight && $(readlink "$sleep_dir/keyboard-backlight") == "$protected_dangling_target" ]] ||
fail "migration replaces a safe dangling symlink below a root-only directory"
grep -q $'^sudo\t.*/stat\t-c\t%f %u %g %a\t--\t.*/root-only-dangling/future-keyboard$' "$calls" ||
fail "migration does not inspect a protected dangling target with privilege"
grep -q $'^sudo\t/usr/bin/test\t-x\t.*/root-only-dangling$' "$calls" ||
fail "migration does not distinguish a protected missing target from an inaccessible parent"
pass "migration preserves dangling administrator symlinks below root-only directories"
user_dir="$test_tmp/user-hooks"
user_keyboard="$user_dir/keyboard"
mkdir -p "$user_dir"
printf 'unsafe symlink customization\n' >"$user_keyboard"
chmod 0755 "$user_keyboard"
rm -f "$sleep_dir/keyboard-backlight"
ln -s "$user_keyboard" "$sleep_dir/keyboard-backlight"
EXTRA_FAKE_ROOT_DIRS="$admin_dir" \
FAKE_ROOT_FILES="$admin_delay:$sleep_dir/force-igpu" run_migration Integrated
[[ ! -L $sleep_dir/keyboard-backlight ]] ||
fail "migration leaves a user-controlled keyboard-hook symlink active"
cmp -s "$mock_omarchy/default/systemd/system-sleep/keyboard-backlight" \
"$sleep_dir/keyboard-backlight" ||
fail "migration does not replace an unsafe symlink with trusted hook content"
symlink_backup=$(find "$quarantine" -path '*/keyboard-backlight.*/original' -type l -print -quit)
[[ -n $symlink_backup && $(readlink "$symlink_backup") == "$user_keyboard" ]] ||
fail "migration discards an unsafe custom symlink instead of preserving it"
pass "migration quarantines unsafe symlinks outside the active systemd directory"
bridge="$user_dir/bridge"
ln -s "$admin_keyboard" "$bridge"
rm -f "$sleep_dir/keyboard-backlight"
ln -s "$bridge" "$sleep_dir/keyboard-backlight"
EXTRA_FAKE_ROOT_DIRS="$admin_dir" \
FAKE_ROOT_FILES="$admin_keyboard:$admin_delay:$sleep_dir/force-igpu" \
run_migration Integrated
[[ ! -L $sleep_dir/keyboard-backlight ]] ||
fail "migration trusts a symlink chain routed through a user-controlled directory"
cmp -s "$mock_omarchy/default/systemd/system-sleep/keyboard-backlight" \
"$sleep_dir/keyboard-backlight" ||
fail "migration does not repair an indirectly user-controlled symlink"
pass "migration checks every intermediate component in a symlink chain"
hook_copy="$test_tmp/force-igpu-hook"
hook_calls="$test_tmp/force-igpu-calls"
hook_queries="$test_tmp/force-igpu-queries"
hook_config="$test_tmp/supergfxd.conf"
hook_marker="$test_tmp/force-igpu-restore"
hook_pending="$test_tmp/force-igpu-pending"
sed \
-e "s|/usr/bin/supergfxctl|$stub_bin/hook-supergfxctl|g" \
-e "s|/usr/bin/install|$stub_bin/hook-install|g" \
-e "s|/etc/supergfxd.conf|$hook_config|g" \
-e "s|/run/omarchy-force-igpu-integrated|$hook_marker|g" \
"$ROOT/default/systemd/system-sleep/force-igpu" >"$hook_copy"
cat >"$stub_bin/hook-supergfxctl" <<'SH'
#!/bin/bash
case "$1" in
-m)
printf '%s\n' "$*" >>"$HOOK_CALLS"
if [[ ${HOOK_BLOCK_MODE:-} == "$2" ]]; then
trap '' TERM
/usr/bin/sleep 30
fi
current=$(sed -n 's/.*"mode"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$HOOK_CONFIG")
if [[ $current != "$2" ]]; then
printf '%s %s\n' "$2" "${HOOK_CONFIRM_AFTER:-1}" >"$HOOK_PENDING"
fi
;;
-g)
printf '%s\n' "$*" >>"$HOOK_QUERIES"
if [[ -f $HOOK_PENDING ]]; then
read -r pending remaining <"$HOOK_PENDING"
if [[ ${HOOK_FAIL_MODE:-} != "$pending" ]]; then
remaining=$((remaining - 1))
if (( remaining <= 0 )); then
sed -i "s/\"mode\"[[:space:]]*:[[:space:]]*\"[^\"]*\"/\"mode\": \"$pending\"/" "$HOOK_CONFIG"
rm -f -- "$HOOK_PENDING"
else
printf '%s %s\n' "$pending" "$remaining" >"$HOOK_PENDING"
fi
fi
fi
sed -n 's/.*"mode"[[:space:]]*:[[:space:]]*"\([^"]*\)".*/\1/p' "$HOOK_CONFIG"
;;
esac
SH
cat >"$stub_bin/hook-install" <<'SH'
#!/bin/bash
args=()
while (($#)); do
case "$1" in
-o | -g)
shift 2
;;
*)
args+=("$1")
shift
;;
esac
done
exec /usr/bin/install "${args[@]}"
SH
cat >"$stub_bin/sleep" <<'SH'
#!/bin/bash
:
SH
chmod +x "$stub_bin/hook-supergfxctl" "$stub_bin/hook-install" "$stub_bin/sleep"
hook_env=(
"HOOK_CALLS=$hook_calls"
"HOOK_QUERIES=$hook_queries"
"HOOK_CONFIG=$hook_config"
"HOOK_PENDING=$hook_pending"
"PATH=$stub_bin:$PATH"
)
printf '{ "mode": "Hybrid" }\n' >"$hook_config"
env "${hook_env[@]}" bash "$hook_copy" pre suspend
env "${hook_env[@]}" bash "$hook_copy" post suspend
[[ ! -e $hook_calls ]] || fail "force-igpu runs while the root-owned config says Hybrid"
[[ ! -e $hook_marker ]] || fail "force-igpu records restore intent while configured for Hybrid mode"
rm -f "$hook_config"
env "${hook_env[@]}" bash "$hook_copy" pre suspend
env "${hook_env[@]}" bash "$hook_copy" post suspend
[[ ! -e $hook_calls ]] || fail "force-igpu runs when its mode config is unavailable"
[[ ! -e $hook_marker ]] || fail "force-igpu records restore intent without a mode config"
printf '{ "mode": "Integrated" }\n' >"$hook_config"
env "${hook_env[@]}" bash "$hook_copy" pre suspend
[[ -f $hook_marker && $(stat -c '%a' "$hook_marker") == 600 ]] ||
fail "force-igpu does not securely record Integrated restore intent during pre-suspend"
HOOK_CONFIRM_AFTER=2 env "${hook_env[@]}" bash "$hook_copy" post suspend
[[ $(wc -l <"$hook_calls") == 2 ]] ||
fail "force-igpu does not run both GPU transitions in Integrated mode"
grep -Fqx -- '-m Integrated' "$hook_calls" ||
fail "force-igpu does not restore Integrated mode after suspend"
[[ ! -e $hook_marker ]] || fail "force-igpu leaves stale restore intent after suspend"
(( $(wc -l <"$hook_queries") >= 4 )) ||
fail "force-igpu does not wait for asynchronous GPU transitions"
pass "force-igpu confirms asynchronous transitions for Integrated sleep cycles"
: >"$hook_calls"
: >"$hook_queries"
printf '{ "mode": "Integrated" }\n' >"$hook_config"
env "${hook_env[@]}" bash "$hook_copy" pre suspend
set +e
HOOK_CONFIRM_AFTER=2 HOOK_FAIL_MODE=Integrated env "${hook_env[@]}" \
bash "$hook_copy" post suspend >/dev/null 2>&1
restore_status=$?
set -e
(( restore_status != 0 )) || fail "force-igpu reports success without confirming Integrated mode"
grep -Fq '"mode": "Vfio"' "$hook_config" ||
fail "force-igpu failure test does not leave the transition in Vfio mode"
[[ -f $hook_marker ]] || fail "force-igpu discards restore intent after an asynchronous transition failure"
HOOK_CONFIRM_AFTER=2 env "${hook_env[@]}" bash "$hook_copy" post suspend
grep -Fq '"mode": "Integrated"' "$hook_config" ||
fail "force-igpu does not recover the Integrated transition on the next sleep cycle"
[[ ! -e $hook_marker ]] || fail "force-igpu leaves restore intent after a confirmed retry"
pass "force-igpu retains restore intent until Integrated mode is confirmed"
: >"$hook_calls"
: >"$hook_queries"
printf '{ "mode": "Integrated" }\n' >"$hook_config"
env "${hook_env[@]}" bash "$hook_copy" pre suspend
set +e
HOOK_BLOCK_MODE=Vfio env "${hook_env[@]}" \
bash "$hook_copy" post suspend >/dev/null 2>&1
blocked_request_status=$?
set -e
(( blocked_request_status != 0 )) || fail "force-igpu waits forever for a blocked GPU transition request"
[[ -f $hook_marker ]] || fail "force-igpu discards restore intent after a blocked transition request"
[[ ! -s $hook_queries ]] || fail "force-igpu polls before a blocked transition request returns"
env "${hook_env[@]}" bash "$hook_copy" post suspend
[[ ! -e $hook_marker ]] || fail "force-igpu cannot retry after a blocked transition request"
pass "force-igpu bounds blocked transition requests and retains retry intent"
: >"$hook_calls"
printf '{ "mode": "Integrated" }\n' >"$hook_config"
env "${hook_env[@]}" bash "$hook_copy" pre hibernate
grep -Fq '"mode": "Vfio"' "$hook_config" ||
fail "force-igpu test double does not model the pre-hibernate Vfio persistence"
[[ -f $hook_marker ]] || fail "force-igpu loses restore intent during the Vfio transition"
env "${hook_env[@]}" bash "$hook_copy" post hibernate
[[ $(wc -l <"$hook_calls") == 3 ]] ||
fail "force-igpu skips the post-hibernate transitions after Vfio changes the config"
[[ $(tail -1 "$hook_calls") == "-m Integrated" ]] ||
fail "force-igpu does not finish post-hibernate restoration in Integrated mode"
grep -Fq '"mode": "Integrated"' "$hook_config" ||
fail "force-igpu leaves supergfxd configured for Vfio after hibernation"
[[ ! -e $hook_marker ]] || fail "force-igpu leaves stale restore intent after hibernation"
pass "force-igpu restores Integrated mode after pre-hibernate persists Vfio"
: >"$hook_calls"
printf '{ "mode": "Integrated" }\n' >"$hook_config"
SYSTEMD_SLEEP_ACTION=suspend env "${hook_env[@]}" bash "$hook_copy" pre suspend-then-hibernate
SYSTEMD_SLEEP_ACTION=suspend env "${hook_env[@]}" bash "$hook_copy" post suspend-then-hibernate
[[ $(wc -l <"$hook_calls") == 2 ]] ||
fail "force-igpu does not complete the initial suspend phase of suspend-then-hibernate"
SYSTEMD_SLEEP_ACTION=hibernate env "${hook_env[@]}" bash "$hook_copy" pre suspend-then-hibernate
[[ $(wc -l <"$hook_calls") == 3 && $(tail -1 "$hook_calls") == "-m Vfio" ]] ||
fail "force-igpu skips the Vfio transition before compound hibernation"
grep -Fq '"mode": "Vfio"' "$hook_config" ||
fail "force-igpu does not detach the dGPU during the hibernate phase"
[[ -f $hook_marker ]] || fail "force-igpu loses restore intent during compound hibernation"
SYSTEMD_SLEEP_ACTION=hibernate env "${hook_env[@]}" bash "$hook_copy" post suspend-then-hibernate
[[ $(wc -l <"$hook_calls") == 5 && $(tail -1 "$hook_calls") == "-m Integrated" ]] ||
fail "force-igpu does not restore Integrated mode after compound hibernation"
grep -Fq '"mode": "Integrated"' "$hook_config" ||
fail "force-igpu leaves supergfxd configured for Vfio after compound hibernation"
[[ ! -e $hook_marker ]] || fail "force-igpu leaves stale restore intent after compound hibernation"
pass "force-igpu handles both phases of suspend-then-hibernate"
keyboard_hook_copy="$test_tmp/keyboard-backlight-hook"
keyboard_calls="$test_tmp/keyboard-backlight-calls"
keyboard_led_dir="$test_tmp/leds"
mkdir -p "$keyboard_led_dir/asus::kbd_backlight"
sed "s|/sys/class/leds/\*kbd_backlight\*|$keyboard_led_dir/*kbd_backlight*|" \
"$ROOT/default/systemd/system-sleep/keyboard-backlight" >"$keyboard_hook_copy"
cat >"$stub_bin/brightnessctl" <<'SH'
#!/bin/bash
printf '%s\n' "$*" >>"$KEYBOARD_CALLS"
SH
chmod +x "$stub_bin/brightnessctl"
SYSTEMD_SLEEP_ACTION=suspend KEYBOARD_CALLS="$keyboard_calls" PATH="$stub_bin:$PATH" \
bash "$keyboard_hook_copy" pre suspend-then-hibernate
[[ ! -e $keyboard_calls ]] || fail "keyboard-backlight runs during the suspend phase of compound sleep"
SYSTEMD_SLEEP_ACTION=hibernate KEYBOARD_CALLS="$keyboard_calls" PATH="$stub_bin:$PATH" \
bash "$keyboard_hook_copy" pre suspend-then-hibernate
grep -Fqx -- '-d asus::kbd_backlight set 0' "$keyboard_calls" ||
fail "keyboard-backlight skips the hibernate phase of compound sleep"
pass "keyboard-backlight handles the hibernate phase of suspend-then-hibernate"
+44
View File
@@ -132,3 +132,47 @@ if problems:
PYTHON
pass "no Omarchy script writes a path under /usr that no package owns"
for script in bin/omarchy-hibernation-setup bin/omarchy-toggle-hybrid-gpu; do
grep -F '"${destination%/*}/.${destination##*/}.omarchy.XXXXXX"' "$ROOT/$script" >/dev/null ||
fail "$script reserves a hidden sibling for the privileged replacement"
grep -F 'sudo /usr/bin/install -m "$mode" -o root -g root -T "$source" "$stage"' "$ROOT/$script" >/dev/null ||
fail "$script prepares privileged files with final root ownership and mode"
grep -F 'sudo /usr/bin/mv -Tf -- "$stage" "$destination"' "$ROOT/$script" >/dev/null ||
fail "$script atomically replaces the privileged destination"
if grep -F 'sudo /usr/bin/chmod "$mode" "$destination"' "$ROOT/$script" >/dev/null; then
fail "$script changes mode after publishing the privileged destination"
fi
done
grep -F ' /usr/lib/systemd/system-sleep/keyboard-backlight 0755' "$ROOT/bin/omarchy-hibernation-setup" >/dev/null ||
fail "hibernation setup installs keyboard-backlight as a root-owned executable"
hook_install_line=$(rg -n '^if ! install_root_file .*keyboard-backlight' "$ROOT/bin/omarchy-hibernation-setup" | cut -d: -f1)
resume_marker_line=$(rg -n '^echo "HOOKS\+=\(resume\)"' "$ROOT/bin/omarchy-hibernation-setup" | cut -d: -f1)
[[ -n $hook_install_line && -n $resume_marker_line ]] ||
fail "hibernation setup keeps recognizable hook-install and resume-marker steps"
(( hook_install_line < resume_marker_line )) ||
fail "hibernation setup marks completion before a failed hook install can be retried"
grep -F ' /usr/lib/systemd/system-sleep/force-igpu 0755' "$ROOT/bin/omarchy-toggle-hybrid-gpu" >/dev/null ||
fail "hybrid GPU setup installs force-igpu as a root-owned executable"
grep -F ' /etc/systemd/system/supergfxd.service.d/delay-start.conf 0644' "$ROOT/bin/omarchy-toggle-hybrid-gpu" >/dev/null ||
fail "hybrid GPU setup installs its root service drop-in as root-owned configuration"
delay_install_line=$(rg -n '^ if ! install_root_file .*delay-start\.conf' "$ROOT/bin/omarchy-toggle-hybrid-gpu" | cut -d: -f1)
force_install_line=$(rg -n '^ if ! install_root_file .*force-igpu' "$ROOT/bin/omarchy-toggle-hybrid-gpu" | cut -d: -f1)
config_switch_line=$(rg -n '^ sudo sed -i \\' "$ROOT/bin/omarchy-toggle-hybrid-gpu" | tail -1 | cut -d: -f1)
[[ -n $delay_install_line && -n $force_install_line && -n $config_switch_line ]] ||
fail "hybrid GPU setup keeps recognizable support-file and config-switch steps"
(( delay_install_line < config_switch_line && force_install_line < config_switch_line )) ||
fail "hybrid GPU setup switches config before every required file is installed"
grep -Fq '/usr/bin/grep -Eq' "$ROOT/default/systemd/system-sleep/force-igpu" ||
fail "force-igpu does not guard execution with the configured GPU mode"
if rg -n 'cp -p.*(system-sleep|supergfxd\.service\.d)' "$ROOT/bin/omarchy-hibernation-setup" "$ROOT/bin/omarchy-toggle-hybrid-gpu"; then
fail "privileged sleep and hybrid GPU files are never copied with source ownership"
fi
pass "system-sleep hooks and the hybrid GPU drop-in enforce root ownership"