ad_get_geometry: signed-int overflow in cylinders*heads*sectors (with u16βu8 truncation of IDENTIFY heads/sectors) corrupts total_secs into an ~16-EiB media-size lie
Summary
u16 IDENTIFY heads/sectors silently truncate into u8 softc fields, then the promoted-int product wraps for crafted geometry (65535*255*255 > INT_MAX) and sign-extends to ~1.8e19 sectors in d_media_blocks - dscheck bounds become unlimited and ad_strategy issues LBAs beyond capacity (wrong-sector IO on the hostile device; 28-bit path silently truncates). The heads 0x0100->0 truncation also enables the known DF-1883/2489 div0. 64-bit-cast+nonzero-validate fix.
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-4798 Β· 1 files| File | Type | Description | Size | |
|---|---|---|---|---|
| verdict.json | file | 1.3 KB | view raw |
Fix verification
not_testableConfirmed kernel references
Detail
Exploit chain
crafted IDENTIFY (cyl=0xFFFF, heads=0x01FF, sect=0x01FF) -> int overflow -> total_secs ~= 1.8e19 -> unlimited dscheck bounds -> OOB-capacity LBAs
Evidence (decisive lines)
findings/poc/DF-4798/ (this verdict)
Verdict
Code-certain signed-overflow geometry lie, hostile-device-gated: u16 IDENTIFY heads/sectors are silently truncated into u8 softc fields, then total_secs = cylindersheadssectors is computed in promoted int arithmetic - cylinders=65535/heads=255/sectors=255 (from truncated 0x01FF) wraps negative and sign-extends to ~1.8e19 sectors in d_media_blocks, making dscheck bounds effectively unlimited so ad_strategy issues LBAs beyond real capacity (wrong-sector IO confined to the hostile device; 28-bit command path silently truncates). The truncation of heads 0x0100->0 is also the enabler of the known DF-1883/2489 div0. Not stageable on the audit guest without a custom device model; arithmetic certain by inspection. 64-bit-cast + nonzero-validate fix (also closes the div0 route).
No comments yet.