Open
Description
Hello 🦀 ,
we (Rust group @sslab-gatech) found a memory-safety/soundness issue in this crate while scanning Rust code on crates.io for potential vulnerabilities.
Issue Description
common::Slice::<T, H>::new
Drop uninitialized memory upon panic withinT::default()
.
Lines 73 to 89 in f931efb
common::SliceVec::<T, H>::resize_with
double free upon panic withinT::drop
in line 438.
Lines 417 to 443 in f931efb
common::SliceVec::<T, H>::resize
double free upon panic withinT::drop
in line 466.
Lines 445 to 471 in f931efb
Proof of Concept
Example program below exhibits a double drop on the same object.
// tested with rustc 1.50.0-nightly (7f9c43cf9 2020-12-23) on Ubuntu 18.04
use arenavec::rc::{Arena, SliceVec};
use arenavec::ArenaBacking;
use std::sync::atomic::{
AtomicBool,
Ordering::SeqCst,
};
#[derive(Clone)]
struct Foo(usize, Option<u64>);
impl Drop for Foo {
fn drop(&mut self) {
println!("Dropping {:?}", self.0);
if self.0 == 1 && ATOMIC_TRUE.compare_and_swap(true, false, SeqCst) {
println!("THIS WILL PANIC {:?}", self.1.as_ref().unwrap());
}
}
}
static ATOMIC_TRUE: AtomicBool = AtomicBool::new(true);
const DEFAULT_CAPACITY: usize = 4096 << 8;
fn main() {
let arena = Arena::init_capacity(ArenaBacking::SystemAllocation, DEFAULT_CAPACITY).unwrap();
let mut vec: SliceVec<Foo> = SliceVec::new(arena.inner());
vec.push(Foo(0, Some(12)));
vec.push(Foo(1, None));
assert_eq!(vec.len(), 2);
vec.resize(1, Foo(99, Some(78)));
}
Program Output
The message Dropping 1
is printed twice, indicating the same object was dropped twice.
Dropping 1
thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', examples/arenavec.rs:14:62
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Dropping 99
Dropping 0
Dropping 1
Suggested Fix
common::Slice::<T, H>::new
:
Moveres.len = len;
to after all writes are done.common::SliceVec::<T, H>::resize_with
&common::SliceVec::<T, H>::resize
:
Moveself.slice.len = len;
to beforedrop_in_place()
.
Thank you for checking out this issue!
Metadata
Metadata
Assignees
Labels
No labels