Panic safety: OwnedAlloc::drop_in_place double-frees on a panicking element Drop
OwnedAlloc::drop_in_place has a panic-safety unsoundness. It destroys the contained value with drop_in_place, then commits the ownership transfer with mem::forget(self) — which lives inside into_raw. T::drop is user-controlled and can panic; if it does, into_raw is never reached, the forget is skipped, and the still-live OwnedAlloc is dropped during unwinding. Its Drop runs drop_in_place on the same T a second time and then deallocs. For a T that owns an allocation, that's a double-free (CWE-415) reachable from safe Rust.
src/owned.rs:
pub fn drop_in_place(self) -> UninitAlloc<T> {
unsafe {
self.nnptr.as_ptr().drop_in_place(); // T::drop() may panic
UninitAlloc::from_raw(self.into_raw()) // mem::forget skipped on panic
}
}The destructor also reads the already-destroyed value through Layout::for_value(self.nnptr.as_ref()) before deallocating.
MaybeUninitAlloc::drop_in_place delegates here, so both public APIs are affected. OwnedAlloc::new with a T whose Drop panics is enough — no particular element type beyond one that owns a heap allocation, so the second free is observable. With a String field followed by a one-shot panicking Drop, the PoC reports attempting double-free under AddressSanitizer.
Suggested fix: take the marker before destroying, the way init and init_in_place in this crate already do.
let raw = self.into_raw(); // mem::forget, cannot panic
raw.as_ptr().drop_in_place();
UninitAlloc::from_raw(raw)A panicking Drop then leaks the allocation rather than freeing it twice.
Confirmed on 0.2.0.