Add advisories: use-after-free via leaked async transfer future (zynq7000-hal, vorago-shared-hal, vorago-shared-periphs, axi-uartlite, axi-uart16550)#2965
Conversation
…bedded HAL crates)
|
If the releases for the other crates are imminent, I'd prefer to wait to issue their advisories when they are released. Maybe drop them from this PR for now? |
|
@djc Sounds good, thanks for the quick review. I've dropped zynq7000-hal, vorago-shared-hal, and vorago-shared-periphs from this PR — their fixes are merged upstream but not yet released, so I'll open a follow-up PR once the releases are out. This PR now contains only axi-uartlite and axi-uart16550, which are already fixed in the released 0.2.0. |
|
I'm still on the fence about whether this requires an advisory? Seems pretty hard to reach by accident? |
|
@djc Fair question! The bar for an advisory here isn't likelihood — it's that safe code can trigger UB. These async methods erase a borrowed buffer's lifetime into a raw slice the DMA keeps using, and lean entirely on the future's Relying on a destructor for memory safety is exactly the unsound pattern that got Agreed the likelihood is low. |
Have to agree to this. The primary issue is that safe code can trigger UB like mentioned by @kbhetrr . Whether a corner case like this really warrants putting A clean solution to this would be some way to guarantee that a destructor will run for certain data structures. Rust does not allow this, but I think there is some work going on which might allow this in the future. |
|
Don't get me wrong, I do feel like unsound code should be fixed, and if making API I don't think unsoundness that is hard to reach by accident is worth publishing an advisory for necessarily. |
Affected crate(s)
A single soundness issue shared across five embedded async HAL crates by the same
maintainer (Robin Mueller, IRS / University of Stuttgart). They share a
raw-slice/raw-bufferlifetime-erasure pattern.zynq7000-hal0.1.1 (SPI RX memory corruption + UART TX info disclosure)vorago-shared-hal0.4.0 (UART TX info disclosure + SPI RX memory corruption)vorago-shared-periphs0.1.0 (UART TX info disclosure)axi-uartlite<0.2.0 (UART TX info disclosure; patched in 0.2.0)axi-uart16550<0.2.0 (UART TX info disclosure; patched in 0.2.0)Links to upstream issue(s) or PR(s)
Reported privately to the maintainer by email on 2026-06-02; coordinated disclosure,
maintainer acknowledged and agreed to
informational = "unsound"advisories.Upstream fixes (mark the async buffer-taking APIs
unsafe, add explicit bufferlifetimes, document the leak hazard):
Severity
informational = "unsound"(soundness issue, not an exploitable CVE). Each crate exposesa safe async I/O API (
embedded_io_async::Write,embedded_hal_async::SpiBus) thataccepts a non-
'staticborrowed buffer and erases its lifetime to hand a bare pointer to aperipheral interrupt. Cancellation safety relies entirely on the returned future's
Drop.Because
core::mem::forget(and other leaks:Rc/arena cycles, leaked tasks,Box::leak)is safe and skips
Drop, safe code can leak an in-flight transfer future after its borrowedbuffer is freed/reused — the peripheral then reads freed memory (info disclosure, UART TX) or
writes into it (memory corruption, SPI RX), with no
unsafeat the call site. Neither theborrow checker nor Miri observes it (the access is outside the abstract machine and the
lifetime is erased). Severity is application-dependent; trigger is not necessarily
attacker-controlled.
Checklist
RUSTSEC-0000-0000as the IDdatefield is set to the public disclosure date