Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 69 additions & 0 deletions crates/loom/RUSTSEC-0000-0000.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
```toml
[advisory]
id = "RUSTSEC-0000-0000"
package = "loom"
date = "2026-03-11"
url = "https://github.com/tokio-rs/loom/issues/406"
informational = "unsound"
categories = ["memory-corruption"]
keywords = ["soundness", "use-after-free", "dangling-reference", "lifetime"]

[versions]
patched = []
unaffected = []
```

# `Lazy::get` can return a dangling `&'static` reference

`loom::lazy_static::Lazy::get` returns `&'static T`, but the referenced value is
scoped to the `loom::model` execution and may be dropped when the model finishes.
Safe code can move that `'static` reference outside the model closure and use it
after teardown, which can result in a dangling reference and undefined behavior.

The issue is triggered entirely through safe APIs by storing the returned
reference and accessing it after `loom::model` returns. The issue affects the
reported version `0.7.2`, and no patched version is currently available.

## Example

```rust
use loom::lazy_static::Lazy;
use std::marker::PhantomData;
use std::sync::{Arc, Mutex};

static MALICIOUS_LAZY: Lazy<String> = Lazy {
init: || String::from("Exploit UAF"),
_p: PhantomData,
};

fn main() {
let leaked_ref = Arc::new(Mutex::new(None));
let leaked_clone = leaked_ref.clone();

loom::model(move || {
let s: &'static String = MALICIOUS_LAZY.get();
*leaked_clone.lock().unwrap() = Some(s);
});

let uaf_string: &'static String = leaked_ref.lock().unwrap().unwrap();
println!("UAF Read: {}", uaf_string);
}
```

## Result

When test example code by `cargo run`, sometimes the program panics and reports UB:

```text
❯ cargo run
Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.02s
Running `target/debug/test1`

thread 'main' (303859474) panicked at /rustc/1d23d06800271f651fad07bf22bf5e298138972e/library/alloc/src/vec/mod.rs:1637:18:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`

This indicates a bug in the program. This Undefined Behavior check is optional, and cannot be relied on for safety.
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
thread caused non-unwinding panic. aborting.
zsh: abort cargo run
```