From 5faed2397710aa8385c387ed85f45b1872865b4f Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Sun, 19 Jul 2026 20:09:24 +0200 Subject: [PATCH] security-hardening: recognise the guard-lib shutdown guard Test 10 only knew the retired shutdown-schedule-guard.path, so it reported a skip while guard-file@shutdown-schedule.path was actively protecting /etc/shutdown-schedule.conf. That understated the real protection in the same way tests 2, 3 and 5 did before the last commit. It now accepts the guard-lib unit and passes. The disabled-is-intentional branch stays for hosts running neither unit. Host: 19 passed / 0 failed / 5 skipped. Container: exit 0. --- ...y-hardening-shutdown-guard-2026-07-19.json | 29 +++++++++++++++++++ .../tests/test_security_hardening.sh | 8 +++-- 2 files changed, 35 insertions(+), 2 deletions(-) create mode 100644 docs/superpowers/evidence/security-hardening-shutdown-guard-2026-07-19.json diff --git a/docs/superpowers/evidence/security-hardening-shutdown-guard-2026-07-19.json b/docs/superpowers/evidence/security-hardening-shutdown-guard-2026-07-19.json new file mode 100644 index 00000000..42c083f1 --- /dev/null +++ b/docs/superpowers/evidence/security-hardening-shutdown-guard-2026-07-19.json @@ -0,0 +1,29 @@ +{ + "intent": "Report the shutdown schedule as guarded rather than skipped, now that guard-file@shutdown-schedule.path is confirmed active.", + "scope": [ + "linux_configuration/tests/test_security_hardening.sh: Test 10 only", + "Non-goal: system state — the legacy units were disabled by the user, not by this change" + ], + "changes": [ + "Test 10 now accepts guard-file@shutdown-schedule.path, the guard-lib replacement that actually protects /etc/shutdown-schedule.conf today. Previously it only knew the retired shutdown-schedule-guard.path and reported a skip, which understated the real protection. The disabled-is-intentional branch is kept for hosts that have neither unit." + ], + "verification": [ + { + "command": "bash linux_configuration/tests/test_security_hardening.sh (real host)", + "result": "pass", + "evidence": "19 passed / 0 failed / 5 skipped, up from 18/0/6: 'shutdown schedule is guarded' now PASSes instead of skipping. /etc/shutdown-schedule.conf carries the immutable flag and guard-file@shutdown-schedule.path is active." + }, + { + "command": "docker run --network=none archlinux:base-devel ", + "result": "pass", + "evidence": "exit 0 — off-host behaviour unchanged." + } + ], + "risks": [ + "Same pattern as the other guard checks: if the unit is renamed again, this reports a false skip rather than a failure. The disabled-is-intentional branch is what makes that possible, and it is the deliberate trade for not failing on a host that legitimately retired the guard." + ], + "rollback": [ + "git revert this commit; Test 10 returns to skipping on this host.", + "Validate after rollback: the suite reports 18 passed / 6 skipped with 'shutdown-schedule-guard.path is active' skipped." + ] +} diff --git a/linux_configuration/tests/test_security_hardening.sh b/linux_configuration/tests/test_security_hardening.sh index a8fc5a89..fd0c9a50 100755 --- a/linux_configuration/tests/test_security_hardening.sh +++ b/linux_configuration/tests/test_security_hardening.sh @@ -201,8 +201,12 @@ fi # and never compare equal. Capture stdout and discard the exit status instead. shutdown_guard_enabled=$(systemctl is-enabled shutdown-schedule-guard.path 2>/dev/null || true) [[ -n "$shutdown_guard_enabled" ]] || shutdown_guard_enabled=unknown -if systemctl is-active --quiet shutdown-schedule-guard.path 2>/dev/null; then - test_result "shutdown-schedule-guard.path is active" "pass" +if systemctl is-active --quiet guard-file@shutdown-schedule.path 2>/dev/null || + systemctl is-active --quiet shutdown-schedule-guard.path 2>/dev/null; then + # guard-file@shutdown-schedule.path is the guard-lib replacement and is the + # unit actually protecting the schedule today, so this is a pass, not a + # concession that the schedule went unguarded. + test_result "shutdown schedule is guarded" "pass" elif [[ "$shutdown_guard_enabled" == "disabled" ]]; then test_result "shutdown-schedule-guard.path is active" "skip" \ "intentionally retired with the old poweroff flow (night lockdown replaced it)"