Revoke before session cleanup and protect standalone inhibition
This commit is contained in:
1 parent
c52381f092
commit
f2c3925431
4 files changed
+44
-11
No files matched your search
@@ -23,6 +23,10 @@ update_stay_awake_stopped=0
|
||||
cleanup_update() {
|
||||
local status=$?
|
||||
trap - EXIT HUP INT TERM
|
||||
if ! omarchy_security_revoke_sudo_timestamp; then
|
||||
echo "Could not invalidate sudo before update cleanup." >&2
|
||||
omarchy_security_exit_with_revoked_sudo 1
|
||||
fi
|
||||
if (( update_stay_awake_stopped == 0 )); then
|
||||
omarchy-update-stay-awake stop || status=1
|
||||
fi
|
||||
@@ -88,6 +92,7 @@ if [[ ${1:-} == "-y" ]] || omarchy-update-confirm; then
|
||||
# Release update-owned inhibitors before offering a reboot. A confirmed
|
||||
# reboot can terminate this process before its EXIT trap gets a chance to
|
||||
# remove the persistent Stay Awake marker.
|
||||
omarchy_security_revoke_sudo_timestamp
|
||||
omarchy-update-stay-awake stop
|
||||
update_stay_awake_stopped=1
|
||||
|
||||
|
||||
@@ -1,10 +1,21 @@
|
||||
#!/bin/bash
|
||||
#!/bin/bash -p
|
||||
|
||||
# omarchy:summary=Manage sleep and idle inhibition during an update
|
||||
# omarchy:args=<start|stop>
|
||||
# omarchy:hidden=true
|
||||
|
||||
if [[ $- != *p* ]]; then
|
||||
echo "Refusing an unsafe Bash startup." >&2
|
||||
exit 126
|
||||
fi
|
||||
|
||||
source "${BASH_SOURCE[0]%/*}/omarchy-security-functions" || exit 126
|
||||
omarchy_security_require_privileged_bash_startup || exit 126
|
||||
set -e
|
||||
omarchy_security_sanitize_bash_environment "$0" "$@"
|
||||
omarchy_security_revoke_sudo_timestamp || exit 1
|
||||
omarchy_security_install_sudo_cleanup_traps
|
||||
omarchy_security_enable_no_update_sudo
|
||||
|
||||
state_dir="${XDG_RUNTIME_DIR:-/tmp/omarchy-$UID}/omarchy-update-stay-awake"
|
||||
idle_owner_file="$state_dir/idle-owner"
|
||||
@@ -106,7 +117,7 @@ start() {
|
||||
( [[ -z ${OMARCHY_UPDATE_LOCK_FD:-} ]] || exec {OMARCHY_UPDATE_LOCK_FD}>&-
|
||||
exec "${hold_command[@]}" ) &
|
||||
elif [[ -t 0 ]]; then
|
||||
sudo -N -b -- "${hold_command[@]}"
|
||||
/usr/bin/sudo -N -b -- "${hold_command[@]}"
|
||||
else
|
||||
( [[ -z ${OMARCHY_UPDATE_LOCK_FD:-} ]] || exec {OMARCHY_UPDATE_LOCK_FD}>&-
|
||||
exec pkexec "${hold_command[@]}" ) &
|
||||
|
||||
@@ -36,6 +36,12 @@ for step in omarchy-update-system-pkgs yay omarchy-hook omarchy-update-mise; do
|
||||
export SUDO_TEST_FAIL_STEP=$step
|
||||
if run_update -y; then fail "$step failure must fail the update"; fi
|
||||
assert_boundary_cold "failed $step"
|
||||
python3 - "$SUDO_TEST_LOG" <<'PY'
|
||||
import sys
|
||||
s=open(sys.argv[1]).read().splitlines()
|
||||
for i,line in enumerate(s):
|
||||
if line=='step:omarchy-update-stay-awake stop': assert i>0 and s[i-1]=='sudo -k',s
|
||||
PY
|
||||
pass "update revokes credentials after $step fails"
|
||||
done
|
||||
|
||||
|
||||
@@ -136,14 +136,10 @@ kill -0 "$inhibitor_pid" 2>/dev/null &&
|
||||
pass "omarchy-update waits for its sleep inhibitor to stop"
|
||||
|
||||
if (( EUID != 0 )); then
|
||||
sudo_log="$test_tmp/sudo.log"
|
||||
sudo_log="$SUDO_TEST_LOG"
|
||||
: >"$sudo_log"
|
||||
pkexec_marker="$test_tmp/pkexec-used"
|
||||
terminal_inhibit_pid_file="$test_tmp/terminal-inhibit-pid"
|
||||
write_stub sudo '
|
||||
printf "%s\n" "$*" >>"$SUDO_LOG"
|
||||
[[ $1 == "-N" && $2 == "-b" && $3 == "--" ]] || exit 90
|
||||
shift 3
|
||||
"$@" &'
|
||||
write_stub pkexec '[[ -z ${PKEXEC_MARKER:-} ]] || touch "$PKEXEC_MARKER"; exec "$@"'
|
||||
|
||||
# start leaves the inhibitor running on purpose, but script tears the pty down
|
||||
@@ -154,7 +150,7 @@ shift 3
|
||||
#!/bin/bash
|
||||
omarchy-update-stay-awake start
|
||||
for _ in {1..200}; do
|
||||
grep -q -- '^-N -b -- ' "$SUDO_LOG" && break
|
||||
grep -q -- '^sudo -N -b -- ' "$SUDO_LOG" && break
|
||||
sleep 0.05
|
||||
done
|
||||
SH
|
||||
@@ -163,8 +159,7 @@ SH
|
||||
SUDO_LOG="$sudo_log" PKEXEC_MARKER="$pkexec_marker" INHIBIT_PID_FILE="$terminal_inhibit_pid_file" \
|
||||
run_with_lock_env script -qefc "$terminal_driver" /dev/null >/dev/null
|
||||
|
||||
grep -q -- '^-N -b -- ' "$sudo_log" || fail "terminal inhibition authenticates its background command without a reusable timestamp"
|
||||
grep -q -- '^-N -b -- ' "$sudo_log" || fail "terminal sleep inhibition runs through sudo"
|
||||
grep -q -- '^sudo -N -b -- ' "$sudo_log" || fail "terminal inhibition authenticates its background command without a reusable timestamp"
|
||||
[[ ! -e $pkexec_marker ]] || fail "terminal sleep inhibition does not use pkexec"
|
||||
run_with_lock_env "$SUDO_TEST_ROOT/bin/omarchy-update-stay-awake" stop
|
||||
pass "terminal updates use sudo instead of Polkit for sleep inhibition"
|
||||
@@ -229,3 +224,19 @@ kill -0 "$unrelated_pid" 2>/dev/null ||
|
||||
kill "$unrelated_pid"
|
||||
wait "$unrelated_pid" 2>/dev/null || true
|
||||
pass "stale inhibitor state does not terminate a reused PID"
|
||||
|
||||
# The hidden helper also establishes its own boundary when invoked directly.
|
||||
reset_boundary
|
||||
touch "$SUDO_TEST_CACHE"
|
||||
run_with_lock_env "$SUDO_TEST_ROOT/bin/omarchy-update-stay-awake" stop
|
||||
[[ $(head -1 "$SUDO_TEST_LOG") == "sudo -k" ]] || fail "standalone inhibitor cleanup did not start cold"
|
||||
assert_boundary_cold "standalone inhibitor cleanup"
|
||||
pass "standalone inhibitor cleanup revokes before and after session work"
|
||||
|
||||
reset_boundary
|
||||
export SUDO_TEST_REVOKE_FAIL=1
|
||||
if run_with_lock_env "$SUDO_TEST_ROOT/bin/omarchy-update-stay-awake" start; then
|
||||
fail "inhibitor started after failed initial revocation"
|
||||
fi
|
||||
[[ ! -e $stay_awake_helper_state/inhibit-pid ]] || fail "failed revocation started an inhibitor"
|
||||
pass "failed initial revocation prevents standalone inhibition"
|
||||
Reference in new issue
Block a user