diff --git a/crates/axi-uart16550/RUSTSEC-0000-0000.md b/crates/axi-uart16550/RUSTSEC-0000-0000.md new file mode 100644 index 000000000..a9ab79a83 --- /dev/null +++ b/crates/axi-uart16550/RUSTSEC-0000-0000.md @@ -0,0 +1,49 @@ +```toml +[advisory] +id = "RUSTSEC-0000-0000" +package = "axi-uart16550" +date = "2026-06-13" +informational = "unsound" +references = [ + "https://egit.irs.uni-stuttgart.de/rust/axi-uart16550", + "https://crates.io/crates/axi-uart16550", +] +keywords = ["async", "use-after-free", "soundness", "embedded", "uart"] + +[versions] +patched = [">=0.2.0"] +``` + +# axi-uart16550: information disclosure via leaking an in-flight async UART TX future + +`axi-uart16550` before 0.2.0 exposes a **safe** asynchronous UART transmit API +(`impl embedded_io_async::Write for TxAsync`, `src/tx_async.rs`) that accepts a **non-`'static` +borrowed buffer** and erases its lifetime (via `raw-slice`/`raw-buffer`) to hand a bare pointer to +the TX interrupt. Cancellation safety relies **entirely** on the returned future's `Drop` to disable +the interrupt, laundered through the safe `Write` trait impl. + +Because `core::mem::forget` is **safe** and skips `Drop` — as are other leaks (`Rc`/arena reference +cycles, a leaked/aborted task, `Box::leak`) — safe code can leak an **in-flight** transmit future +(polled at least once, so the TX interrupt is armed) while the borrow of the user buffer ends and +its storage is freed or reused. The TX interrupt then keeps **reading the freed buffer and +transmitting its bytes on the wire** — an **information disclosure** of adjacent freed memory, +reachable with no `unsafe` in the caller. + +Neither the borrow checker nor Miri flags it (the interrupt access is outside the abstract machine +and the lifetime is erased). Normal cancellation (dropping the future) runs `Drop` and is handled; +only *leaking* an in-flight future triggers it. Severity is application-dependent, but the API is +**unsound** (safe code can cause UB). + +## Remediation + +Version 0.2.0 marks the `TxFuture` constructor `unsafe` and requires the future to borrow the +buffer for its lifetime, addressing the inherent API path. The `embedded_io_async::Write` trait +implementation retains a theoretical gap (the trait mandates borrowed buffers that cannot be +lifetime-constrained in the return type), which is documented in the crate. The underlying +`raw-buffer` crate's safety notes were also updated to document this obligation for HAL authors. + +Upgrade to `axi-uart16550 >= 0.2.0`. + +--- +Reported by Kyounghwan Kim (Pusan National University, kbhetrr@gmail.com); coordinated with the +maintainer prior to publication. diff --git a/crates/axi-uartlite/RUSTSEC-0000-0000.md b/crates/axi-uartlite/RUSTSEC-0000-0000.md new file mode 100644 index 000000000..8f32af611 --- /dev/null +++ b/crates/axi-uartlite/RUSTSEC-0000-0000.md @@ -0,0 +1,49 @@ +```toml +[advisory] +id = "RUSTSEC-0000-0000" +package = "axi-uartlite" +date = "2026-06-13" +informational = "unsound" +references = [ + "https://egit.irs.uni-stuttgart.de/rust/axi-uartlite", + "https://crates.io/crates/axi-uartlite", +] +keywords = ["async", "use-after-free", "soundness", "embedded", "uart"] + +[versions] +patched = [">=0.2.0"] +``` + +# axi-uartlite: information disclosure via leaking an in-flight async UART TX future + +`axi-uartlite` before 0.2.0 exposes a **safe** asynchronous UART transmit API +(`impl embedded_io_async::Write for TxAsync`, `src/tx_async.rs`) that accepts a **non-`'static` +borrowed buffer** and erases its lifetime (via `raw-slice`/`raw-buffer`) to hand a bare pointer to +the TX interrupt. Cancellation safety relies on the returned future's `Drop`, laundered through the +safe `Write` trait impl. In this crate `TxFuture::drop` additionally **cannot disable the +interrupt** (commented "We can not disable interrupts, might be active for RX as well"), so even +ordinary cancellation is weaker here. + +Because `core::mem::forget` is **safe** and skips `Drop` — as are other leaks (`Rc`/arena reference +cycles, a leaked/aborted task, `Box::leak`) — safe code can leak an **in-flight** transmit future +while the borrow of the user buffer ends and its storage is freed or reused. The TX interrupt then +keeps **reading the freed buffer and transmitting its bytes on the wire** — an **information +disclosure** of adjacent freed memory, reachable with no `unsafe` in the caller. + +Neither the borrow checker nor Miri flags it (the interrupt access is outside the abstract machine +and the lifetime is erased). Severity is application-dependent, but the API is **unsound** (safe +code can cause UB). + +## Remediation + +Version 0.2.0 marks the `TxFuture` constructor `unsafe` and requires the future to borrow the +buffer for its lifetime, addressing the inherent API path. The `embedded_io_async::Write` trait +implementation retains a theoretical gap (the trait mandates borrowed buffers that cannot be +lifetime-constrained in the return type), which is documented in the crate. The underlying +`raw-buffer` crate's safety notes were also updated to document this obligation for HAL authors. + +Upgrade to `axi-uartlite >= 0.2.0`. + +--- +Reported by Kyounghwan Kim (Pusan National University, kbhetrr@gmail.com); coordinated with the +maintainer prior to publication.