Skip to content

Final audit#820

Merged
bunnie merged 19 commits intomainfrom
final-audit
Feb 14, 2026
Merged

Final audit#820
bunnie merged 19 commits intomainfrom
final-audit

Conversation

@bunnie
Copy link
Copy Markdown
Member

@bunnie bunnie commented Feb 14, 2026

A final pass at hardening the code before the first release.

So far, the biggest improvement has been putting pointer bounds checks on all the raw pointers handed to us from the USB hardware interface.

The USB engine passes raw pointers around for DMA purposes;
most importantly, it passes *back* raw pointers and lengths.
There's no really good way to check these, and I suspect that
there may be USB protocol exploits that can be used to manipulate
these values. Thus, an assert is added on the touch points where
the raw pointers go to and from the USB hardware to check that,
at the very least, the entire buffer being referenced is strictly
within the USB hardware's memory space.
the macro will give relevant positional information when the
assert fails, whereas the function always fails in the same place
and we lose that valuable debugging info
somehow some formatting regressions snuck in despite previously
being CI-clean on formatting.

I suspect this might have to do with the Rust 1.93.1 bump
that happened just recently, sometimes new versions of Rust
introduce small formatting changes.
this prevents there being a single "hot spot" to attack for
hardened bool testing
- xor-masking of jump target moved to immediately before the jump
- mscratch csr zeroed
- anti-rollback single-update distance limited to 512: let's hope we
never even get close to having 512 security revisions in a single
generation!
- sanity check untrusted signature/add length fields - constrains
hash-checks to within the right "range", preventing abuse of the
hash reads as an oracle to leak state about other things in memory.
- check valid_key != valid_key2 invariant before returning
also fix some math regarding birthday paradoxes and the
random number checking.
strip out old stuff that doesn't work anymore -- eventually this
code may be entirely struck since it's not even been compiled
for many months.
the original stub for illegal instruction handling advances
the program counter - this was copypasta from the kernel
irq routine, where this behavior is needed to handle syscalls.

However, this behavior is contra-indicated for the purpose
of dying on a bollard - you don't want to skip past the
bollard for any reason.
if the magic numbers match, the payload size field must also
pass the sanity check for the packet to be considered for
further processing.
- improve bollards to include "die" jumps where appropriate
- cleanup warnings in unsafe-dev feature
- panic handler calls die repeatedly
- upgrade jump api
- CBW block only derived after length is validated
- write offset to disk uses checked_add, necessary
since we're compiling in release mode
- improve bollards to use the die call
- fix panic to call die
@bunnie
Copy link
Copy Markdown
Member Author

bunnie commented Feb 14, 2026

See commit log for details - lots of small papercuts and bounds checks added on data being imported from untrusted sources. Rust probably saves us from consequences on most of these issues but better to explicitly validate inputs, than not.

thus the die routine doesn't work in the bollard for
the clocks routine
@bunnie bunnie merged commit 4efe50d into main Feb 14, 2026
17 checks passed
@bunnie bunnie deleted the final-audit branch February 14, 2026 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant