Repository navigation
sxverity: identify the SpaceX dm-verity container (#55) - #60
Merged
Merged
Conversation
moria had no signature for the sxverity container, so on images that use it it named only the inner romfs payload and left the 4 KiB structured header as an unnamed gap (reported neither as a finding nor, by default, as an unidentified region). sxverity is SpaceX's wrapper around the Linux dm-verity feature, used on Starlink User Terminal firmware. The container is a 4 KiB preamble of four 1024-byte records (the ASCII magic "sxverity" starts each one at 0x000 / 0x400 / 0x800 / 0xC00), each carrying a dm-verity root hash, a public key, and an ed25519 signature; the protected payload (a big-endian romfs) follows at 0x1000. Documented by Quarkslab, "Diving into Starlink's User Terminal Firmware". Add an identify-only signature + validator (like verity/luks; the romfs payload is already extractable on its own). The validator confirms the four records and the romfs payload, then sizes the finding to the 4 KiB record table, so the header is named and the romfs surfaces as its own finding. It rejects a stray "sxverity" string that lacks the structure, which matters because the romfs volume name is itself "sxverity". Reaches the consistent tier (magic + full record table + payload cross-check). The 8-byte ASCII magic plus the required four-record-and-payload structure is low false-positive: a sweep over a firmware corpus of 1127 files produced two sxverity findings, both the real Starlink partitions, and nothing else. On the real partitions the summary goes from "romfs" to "sxverity, romfs", the 4 KiB header is a consistent-tier finding and no longer an unnamed gap, and the romfs is still reported and extractable at 0x1000. Note on the format: the record's +0x0c and +0x14 fields are not fixed constants (across the two sample partitions +0x0c is a size that ranges from 2 KiB to ~23 MB and +0x14 varies, likely verity block counts), so the validator keys on the stable structure rather than those fields. The record body carries the root hash / public key / signature, but their slots are not cleanly aligned, so they are not surfaced as byte-level evidence here. Tests: a synthetic container fixture + MANIFEST entry (satisfies the coverage gate), and tests/test_sxverity.py (identify at offset 0 sized to the record table, the romfs payload at 0x1000, embedded-at-offset, false-positive guards for a lone magic / missing payload / single record, and a round-trip against the real Starlink partitions that self-skips when they are absent). Full suite green; ASan/UBSan clean on the real partitions and the fixtures.
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.
Summary
Fixes #55. moria had no signature for the
sxveritycontainer, so on images that use it, it named only the innerromfspayload and left the 4 KiB structured header as an unnamed gap (reported neither as a finding nor, by default, as an unidentified region).sxverityis SpaceX's wrapper around the Linux dm-verity feature, used on Starlink User Terminal firmware. The container is a 4 KiB preamble of four 1024-byte records (the ASCII magicsxveritystarts each one at0x000/0x400/0x800/0xC00), each carrying a dm-verity root hash, a public key, and an ed25519 signature; the protected payload (a big-endian romfs) follows at0x1000. Publicly documented by Quarkslab, "Diving into Starlink's User Terminal Firmware".Approach
Identify-only signature + validator, in the style of
verityandluks(no extractor — the romfs payload is already extractable on its own). The validator confirms the four records and the romfs payload, then sizes the finding to the 4 KiB record table, so the header is named and the romfs surfaces as its own finding at0x1000. It rejects a straysxveritystring that lacks the structure, which matters because the romfs volume name is itselfsxverity. Reaches theconsistenttier (magic + full record table + payload cross-check).Notes on the format
The record's
+0x0cand+0x14fields are not fixed constants — across the two sample partitions,+0x0cis a size that ranges from 2 KiB to ~23 MB and+0x14varies (likely verity block counts) — so the validator keys on the stable structure (four records + romfs) rather than those fields. The record body carries the root hash / public key / signature, but their slots are not cleanly aligned, so they are not surfaced as byte-level evidence here.Results
romfstosxverity, romfs, the 4 KiB header is aconsistent-tier finding and no longer an unnamed gap, and the romfs is still reported and extractable at0x1000.Tests
A synthetic container fixture + MANIFEST entry (satisfies the coverage gate), and
tests/test_sxverity.py: identify at offset 0 sized to the record table, the romfs payload at0x1000, embedded-at-offset, false-positive guards (a lone magic, four records with no payload, a single record), and an opt-in round-trip against real images via$MORIA_SXVERITY_SAMPLESthat self-skips when unset, so CI stays self-contained.