Hi there!
We scanned the most popular libraries on crates.io and found a memory safety bugs in this library.
<ffi::DartCObject as std::ops::Drop>::drop
Dropping a DartCObject with ty=DartString unconditionally reconstructs ownership over self.value.as_string via CString::from_raw. Since DartCObject is publicly constructible/mutable and no runtime checks enforce that as_string was produced by CString::into_raw exactly once (and is non-null), an external caller (or untrusted FFI payload) can supply an arbitrary pointer. This can trigger allocator corruption or double-free when the reconstructed CString is dropped, and can also cause immediate UB if the pointer is null or not a valid C string allocation from Rust's allocator.
PoC
use allo_isolate::ffi::{DartCObject, DartCObjectType};
use std::ffi::CString;
fn main() {
let p = CString::new("hi").unwrap().into_raw();
let a = DartCObject {
ty: DartCObjectType::DartString,
value: allo_isolate::ffi::DartCObjectValue { as_string: p },
};
let b = DartCObject {
ty: DartCObjectType::DartString,
value: allo_isolate::ffi::DartCObjectValue { as_string: p },
};
// Explicitly trigger <ffi::DartCObject as Drop>::drop twice on the same raw pointer.
drop(a); // first CString::from_raw(p) + drop => frees
drop(b); // second CString::from_raw(p) + drop => double-free (UB)
}
Miri Output
error: Undefined Behavior: memory access failed: alloc379 has been freed, so this pointer is dangling
--> /home/ccuu/.rustup/toolchains/nightly-2025-10-09-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/ffi/c_str.rs:408:23
|
408 | let len = strlen(ptr) + 1; // Including the NUL byte
| ^^^^^^^^^^^ Undefined Behavior occurred here
|
= help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
= help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
help: alloc379 was allocated here:
--> src/main.rs:10:13
|
10 | let p = CString::new("hi").unwrap().into_raw();
| ^^^^^^^^^^^^^^^^^^
help: alloc379 was deallocated here:
--> src/main.rs:22:5
|
22 | drop(a); // first CString::from_raw(p) + drop => frees
| ^^^^^^^
= note: BACKTRACE (of the first span):
= note: inside `std::ffi::CString::from_raw` at /home/ccuu/.rustup/toolchains/nightly-2025-10-09-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/alloc/src/ffi/c_str.rs:408:23: 408:34
= note: inside `<allo_isolate::ffi::DartCObject as std::ops::Drop>::drop` at /home/ccuu/Desktop/llm-detector/experiments/cache/crates_src/allo-isolate/0.1.27/allo-isolate-0.1.27/src/ffi.rs:176:34: 176:73
= note: inside `std::ptr::drop_in_place::<allo_isolate::ffi::DartCObject> - shim(Some(allo_isolate::ffi::DartCObject))` at /home/ccuu/.rustup/toolchains/nightly-2025-10-09-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ptr/mod.rs:804:1: 804:62
= note: inside `std::mem::drop::<allo_isolate::ffi::DartCObject>` at /home/ccuu/.rustup/toolchains/nightly-2025-10-09-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/mem/mod.rs:962:24: 962:25
note: inside `main`
--> src/main.rs:23:5
|
23 | drop(b); // second CString::from_raw(p) + drop => double-free (UB)
| ^^^^^^^
note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
error: aborting due to 1 previous error
We appreciate your work on this crate and hope this report helps improve its safety.
Hi there!
We scanned the most popular libraries on crates.io and found a memory safety bugs in this library.
<ffi::DartCObject as std::ops::Drop>::drop
Dropping a DartCObject with ty=DartString unconditionally reconstructs ownership over self.value.as_string via CString::from_raw. Since DartCObject is publicly constructible/mutable and no runtime checks enforce that as_string was produced by CString::into_raw exactly once (and is non-null), an external caller (or untrusted FFI payload) can supply an arbitrary pointer. This can trigger allocator corruption or double-free when the reconstructed CString is dropped, and can also cause immediate UB if the pointer is null or not a valid C string allocation from Rust's allocator.
PoC
Miri Output
We appreciate your work on this crate and hope this report helps improve its safety.