fix(M1): cmd_login no longer grants credential-free admin - #15
Open
d33mobile wants to merge 1 commit into
Open
Conversation
…ey exists
cmd_login had three branches that set admin_mode = true before any
key/TOTP check, ignoring argv entirely:
- no wifi config stored -> "open mode" (won even when valid admin keys
existed)
- RTC unset and uptime past a 5-minute window -> "open mode"
(network-inducible: deny wifi assoc so the RTC never inits)
- no enabled+valid admin key -> "bootstrap mode"
Reorder and fail closed: after the storage-mounted guard, scan for any
enabled+valid admin key. If one exists the device is provisioned and a
matching key id + TOTP code is mandatory - no absent-config and no
absent-time condition may bypass it (totp_verify reads the clock and
fails while time is unknown, so an unset RTC is never an escalation).
The only credential-free path is a genuinely unprovisioned device (no
enabled admin key exists at all); it is gated strictly on any_admin ==
false and closes automatically once an admin key is added, so it is
effectively one-shot provisioning rather than a persistent fail-open
state. Removed the wifi-absent and RTC-unset admin grants and the now
unused BOOT_BYPASS_WINDOW_US.
Adds test/harness_login.c, a CI-gated regression harness that links the
REAL cmd_login against controllable storage/clock/TOTP doubles and
asserts the fail-closed contract (no-wifi / unset-clock / wrong-TOTP all
denied when an admin key exists; provisioning only when none does).
Wired into asan/valgrind/coverage. Host asan/valgrind/coverage/ci-check
all 0.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This was referenced Jul 30, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Finding (ISSUES.md M1)
The branches that existed
cmd_loginsetadmin_mode = trueand returned, before verifying any credential, in three cases:storage_wifi_get()returned false →warning: wifi not configured - open mode. This took precedence even when valid admin keys were present.clock_get_unix_time()returned false (RTC unset / NTP never synced) andtime_us_64() >= BOOT_BYPASS_WINDOW_US(5 min) →warning: RTC not set - open mode. An on-path attacker can force this by denying WiFi association so the clock never initialises, then waiting out the window.!any_admin→warning: no admin keys configured - bootstrap mode.Because branches 1 and 2 preceded the credential check, a fully provisioned device with valid admin keys could be entered with no key id and no TOTP code.
New authorization logic
After the existing
storage_is_mounted()guard (fail closed on unavailable storage),cmd_login:any_admin).any_admin == false. It closes automatically the moment an enabled admin key exists (adding one flipsany_adminto true), so it is effectively one-shot provisioning rather than a persistent fail-open state.totp_verify()reads the clock and simply fails while time is unknown, so login stays closed until time is known.Removed the wifi-absent and RTC-unset admin grants and the now-unused
BOOT_BYPASS_WINDOW_US.The "persist last-known-good unix time to flash" sub-item overlaps C3's max-time watermark (already merged) and is left as follow-up to keep this PR focused on
cmd_login's authorization logic. Physical proof-of-presence for the provisioning path is M4's territory.Host tests / regression
Added
test/harness_login.c, a CI-gated regression harness that links the realcmd_login(serial/commands_system.c) against controllable storage/clock/TOTP doubles and asserts the fail-closed contract:Wired into
make -C test asan|valgrind|coverage. All host gates pass locally:make -C test asan= 0,valgrind= 0,coverage= 0,./ci --action=check= 0. The gccasan_commandsdispatcher harness (spy-based routing) is unchanged and still passes. libFuzzerfuzz_*.charnesses untouched.Firmware-on-hardware behaviour (RTC init, NTP sync timing) = verify-on-hw.
Scope: M1 only.