Repository navigation
Replace default-on device approval with opt-in USB protection while locked - #14937
acrogenesis wants to merge 1 commit into
Conversation
b9360ff to
e14c0c4
Compare
e14c0c4 to
b397975
Compare
b397975 to
97aa7b0
Compare
|
| local action=$1 inventory line rule policy first | ||
| [[ $action == "lock" || $action == "unlock" ]] || return 64 | ||
| if [[ ! -e $USB_LOCK_ENABLED ]]; then echo off; return 0; fi | ||
| systemctl is-active --quiet "$USB_LOCK_SERVICE" || return 1 |
There was a problem hiding this comment.
usb_lock_change exits immediately when omarchy-usb-lock.service is inactive. If a restart leaves the service failed—for example, after repeated startup failures hit systemd's restart limit—every later lock or unlock retry exits here without trying to start it. Even after the startup problem is fixed, USB devices can remain blocked after unlock until someone manually starts the service.
Let retries recover the service while preserving the frozen policy.
| elif [[ $1 == "restart" ]]; then | ||
| [[ $failure != "restart" ]] || return 1 | ||
| cp "$USB_LOCK_DIR/rules.conf" "$scratch/loaded" | ||
| elif [[ $1 == "disable" ]]; then | ||
| [[ $failure != "stop" ]] || return 1 | ||
| active=0 | ||
| fi | ||
| } | ||
| omarchy-usb-authorization-restore-default() { echo restore-default >>"$calls"; } | ||
|
|
||
| device='allow id 046d:c53a serial "" name "USB Receiver" hash "KCUFt1MumW4Pfs/8YXWzGQB6Hsnm8qkDqFVjfY0NIBY=" parent-hash "m7yTNWlczwBbYn+uRP6TRsY5AceKmAZ0Et6mgy58+/o=" via-port "3-1.1.2.1" with-interface { 03:01:01 03:01:02 03:00:00 } with-connect-type "unknown"' | ||
| printf '7: %s\n8: block id 1234:5678 name "Blocked"\n' "$device" >"$device_inventory_file" | ||
| : >"$calls" |
There was a problem hiding this comment.
Setup relies on omarchy-usb-lock.service and 40-omarchy-usb-lock.rules already being installed, but this test mocks systemctl and never checks that either file ships. The existing package checks cover a fixed file list and user services, not these new files. A packaging omission could therefore pass the tests while leaving setup or lock transitions unusable.
Add package coverage checks for both required files.
Proposal
Standalone alternative to #14936, based directly on
quattroin one commit. This PR replaces the default-on device approval rollout from #11874 with an opt-in preview under Setup > Security > USB While Locked. It can merge on its own; #14936 does not need to merge first. Nothing enables the preview automatically on installation or update. Product review with David is required before considering a new default.The change includes withdrawal of automatic USB/Thunderbolt enrollment, removal of the old enablement migrations and menus, and its own cleanup migration for machines already enrolled by Omarchy. Cleanup restores normal USB access, removes optional boot restrictions through the existing verified removal path, and restores the previous Bolt policy while preserving manual rules and saved identities. Failures remain pending with recovery tools installed. Once the migration completes, users can explicitly enable the new lock-screen workflow.
A separate USBGuard service uses a root-only policy under
/run, preserving the frozen identity list across daemon and shell restarts but resetting to permissive after reboot. Existing/etc/usbguardpolicy is left alone. Protected Bash entrypoints and a narrow Polkit action handle lock transitions; setup/removal require sudo. The screen locks immediately, USB transitions retry on failure, and suspend waits for both acknowledgements within its existing budget.Machine-wide cleanup runs through one protected Bash root helper under a shared lock. It recovers saved Thunderbolt setup/boot state even when enrollment markers are missing, starts an inactive Bolt daemon before policy inspection, and keeps failed recovery pending. Each user retires the exact watcher links, including dangling wants/requires links that systemd reports as not-found. Factory snapshot repair follows #14938: remove old enrollment hooks and migrations, preserve the original Bolt mode and read-only state across retries, and publish complete files atomically.
USB ownership requires current enrollment evidence. A historical migration-completed marker alone does not trigger removal: those markers survive opt-out and are also stamped by fresh-install provisioning. The lifecycle regression runs the actual removal file cleanup, then configures an independent USBGuard policy and verifies that repeated rollback preserves its service, rules and blocked-device state. Current enrollment and saved recovery still run through the full user-to-root cleanup path.
Validation
quattroat04b374a9. The current shared cleanup passes 40 rollback groups, with regression mutations proving the cleanup bugs and both stale-ownership scenarios are detected. USB authorization, boot archive/enrollment, CLI, menu/guards and factory reset suites pass; this branch also passes lock policy and suspend checks. First-run, owner keyboard/regdom, LUKS rekey and native USBGuard matcher checks passed before the cleanup-only changes.authorized=0), while the existing tablet remained allowed. The decision survived a USBGuard restart and killing/recovering the shell while locked. Graphical password unlock allowed the waiting mouse (authorized=1). A full reboot from the locked state reset policy toallowand allowed both devices before the desktop shell started. Removal restored controller defaults and connected-device authorization; the first attempt exposed a missing installed legacy helper in the development guest, and succeeded after installing that package-provided dependency.The current cleanup refactor was tested with isolated failure fixtures and focused suites, without another Lab or physical firmware run. The lock-screen implementation exercised in the Lab remains unchanged.
Draft limits
This is not a Pegasus driver fix and does not protect an unlocked machine or authenticate forgeable USB identities. USB enforcement follows the visible screen lock, so there is a transition window. Newly appearing controllers during a daemon outage are not boot-level protected. The active local user can request policy transitions; this does not defend against a compromised user session.
Physical docking, real suspend/resume, multiple seats/sessions, and interrupted requests across session/process boundaries need further review and validation before rollout. The Lab exercises simulated USB hardware, not a fresh ISO or physical Thunderbolt/DMA behavior. The prototype remains opt-in and draft for these decisions.
Implementation details: USB while locked.