From 79db1a182696ad696af8f09ee9b8b9efa36beab5 Mon Sep 17 00:00:00 2001 From: acrogenesis Date: Tue, 15 Sep 2026 14:06:32 -0600 Subject: [PATCH] Allow USB authorization setup with an empty device inventory --- install/helpers/usb-authorization.sh | 14 ++++++++--- test/shell.d/usb-authorization-test.sh | 32 +++++++++++++++++++++++++- 2 files changed, 42 insertions(+), 4 deletions(-) diff --git a/install/helpers/usb-authorization.sh b/install/helpers/usb-authorization.sh index 219a8e5b..a99fbfb9 100644 --- a/install/helpers/usb-authorization.sh +++ b/install/helpers/usb-authorization.sh @@ -59,11 +59,19 @@ usb_authorization_require_secure_settings() { usb_authorization_generate_policy() { local policy="$1" - usbguard generate-policy >"$policy" - if [[ ! -s $policy ]] || ! grep -q '^allow ' "$policy"; then - echo "USBGuard did not generate a usable policy; nothing was enabled." >&2 + if ! usbguard generate-policy >"$policy"; then + echo "USBGuard could not enumerate devices; nothing was enabled." >&2 return 1 fi + if ! grep -q '^allow ' "$policy"; then + if grep -q '^[[:space:]]*[^#[:space:]]' "$policy"; then + echo "USBGuard did not generate a usable policy; nothing was enabled." >&2 + return 1 + fi + # A successful empty inventory is valid on machines without USB controllers. + # Keep the file nonempty so re-enabling preserves this default-deny policy. + echo '# No USB devices were present during enrollment.' >>"$policy" + fi } usb_authorization_add_user() { diff --git a/test/shell.d/usb-authorization-test.sh b/test/shell.d/usb-authorization-test.sh index 784906de..fd05258d 100755 --- a/test/shell.d/usb-authorization-test.sh +++ b/test/shell.d/usb-authorization-test.sh @@ -60,7 +60,10 @@ cat >"$stub_bin/usbguard" <<'STUB' case "$1" in generate-policy) echo 'usbguard ' >>"$CALLS" - echo 'allow id 1d6b:0002 name "Linux Foundation root hub" hash "root"' + [[ ${GENERATE_FAIL:-0} == 0 ]] || exit 1 + if [[ ${GENERATE_EMPTY:-0} == 0 ]]; then + echo 'allow id 1d6b:0002 name "Linux Foundation root hub" hash "root"' + fi ;; list-devices) if [[ ${2:-} == "--blocked" ]]; then @@ -168,6 +171,21 @@ generate_count_after=$(grep -c '^usbguard $' "$calls") (( generate_count_after == generate_count )) || fail "re-enabling preserves the existing trusted-device policy" pass "USB authorization setup preserves an existing policy" +: >"$rules" +GENERATE_EMPTY=1 "$ROOT/bin/omarchy-setup-security-usb-authorization" --yes >"$scratch/setup-empty-output" +[[ -s $rules ]] || fail "empty USB inventory must persist an initialized policy" +! grep -q '^allow ' "$rules" || fail "empty inventory must not add permissive rules" +generate_count=$(grep -c '^usbguard $' "$calls") +"$ROOT/bin/omarchy-setup-security-usb-authorization" --yes >"$scratch/setup-empty-again-output" +[[ $(grep -c '^usbguard $' "$calls") == "$generate_count" ]] || + fail "re-enabling an empty policy must not enroll newly attached devices" +: >"$rules" +if GENERATE_FAIL=1 "$ROOT/bin/omarchy-setup-security-usb-authorization" --yes >"$scratch/setup-failed-output" 2>&1; then + fail "enumeration failure must not be accepted as an empty USB inventory" +fi +[[ ! -s $rules ]] || fail "failed enumeration must not install a policy" +pass "USB setup accepts an empty inventory while rejecting enumeration failure" + : >"$calls" "$ROOT/bin/omarchy-setup-security-usb-authorization" --boot --yes >"$scratch/setup-boot-output" grep -Fqx 'usbguard <--permanent> <4>' "$calls" || @@ -350,6 +368,18 @@ grep -Fqx 'systemctl ' "$calls" || fail "fresh installation enables USBGuard for the first boot" pass "USB authorization is the default for fresh and existing installations" +: >"$rules" +GENERATE_EMPTY=1 bash -euo pipefail -c 'source "$OMARCHY_INSTALL/config/usb-authorization.sh"' >"$scratch/install-empty-output" +[[ -s $rules ]] || fail "fresh install accepts a successful empty USB inventory" +! grep -q '^allow ' "$rules" || fail "empty fresh-install inventory stays default-deny" +: >"$rules" +: >"$calls" +if GENERATE_FAIL=1 bash -euo pipefail -c 'source "$OMARCHY_INSTALL/config/usb-authorization.sh"' >"$scratch/install-enumeration-failed" 2>&1; then + fail "fresh install must reject a generator failure" +fi +! grep -Fq 'systemctl ' "$calls" || fail "failed enumeration must not enable USBGuard" +pass "fresh installation distinguishes no USB hardware from enumeration failure" + malicious_rule='block id 07a6:8513 name "$(touch '"$scratch"'/injected)" hash "attacker" with-interface 02:06:00' export BLOCKED_DEVICE_RULE="$malicious_rule" notification_count=$(grep -c '^notification' "$calls" || true)