You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Hi there, we (Rust group @sslab-gatech) are scanning crates on crates.io for potential soundness bugs. We noticed a potential issue in the provided insert_many implementation / impl_veclike! macro. Namely, impl_veclike pushes elements over for insertion using ptr::copy here:
ptr::copy(start_ptr, start_ptr.offset(num_items asisize), len - index asusize);
for i in 0..num_items {
let item = iter.next().expect("ExactSizeIterator produced too few items.");
ptr::write(start_ptr.offset(i asisize), item);
}
$s.set_len(len + num_items);
}
This can duplicate items in the Vec, after which it calls iter.next(), which can potentially panic. This means that during this panic the copied elements can be dropped twice. Here's a quick example of this issue:
#![forbid(unsafe_code)]use insert_many::InsertMany;structDropDetector(u32);implDropforDropDetector{fndrop(&mutself){println!("Dropping {}",self.0);}}// A type with an iterator that panics.// -----structMyCollection();implIntoIteratorforMyCollection{typeItem = DropDetector;typeIntoIter = PanickingIterator;fninto_iter(self) -> Self::IntoIter{PanickingIterator()}}structPanickingIterator();implIteratorforPanickingIterator{typeItem = DropDetector;fnnext(&mutself) -> Option<Self::Item>{panic!("Iterator panicked");}}implExactSizeIteratorforPanickingIterator{fnlen(&self) -> usize{1}}// -----fnmain(){letmut v = vec![DropDetector(1),DropDetector(2)];// Inserting many elements from a panicking iterator will cause a double-drop.
v.insert_many(0,MyCollection());}
This outputs:
thread 'main' panicked at 'Iterator panicked', src/main.rs:43:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
Dropping 1
Dropping 1
Return code 101
What's happening here is:
v = [DropDetector(1), DropDetector(2)], length = 2
Insert many called.
v = [DropDetector(1), DropDetector(2), RESERVED], length = 2
ptr::copy(start_ptr, start_ptr.offset(num_items as isize), len - index as usize);
v = [DropDetector(1), DropDetector(1), DropDetector(2)], length = 2
iter.next() panics
DropDetector(1) gets dropped twice.
We'd recommend wrapping the vector in ManuallyDrop while performing these operations to avoid this issue.
The text was updated successfully, but these errors were encountered:
Once a fix is released to crates.io, please open a pull request to update the advisory with the patched version, or file an issue on the advisory database repository.
Hi there, we (Rust group @sslab-gatech) are scanning crates on crates.io for potential soundness bugs. We noticed a potential issue in the provided
insert_many
implementation /impl_veclike!
macro. Namely,impl_veclike
pushes elements over for insertion usingptr::copy
here:insert_many/src/lib.rs
Lines 37 to 47 in 697ec9f
This can duplicate items in the Vec, after which it calls
iter.next()
, which can potentially panic. This means that during this panic the copied elements can be dropped twice. Here's a quick example of this issue:This outputs:
What's happening here is:
[DropDetector(1), DropDetector(2)]
, length = 2[DropDetector(1), DropDetector(2), RESERVED]
, length = 2ptr::copy(start_ptr, start_ptr.offset(num_items as isize), len - index as usize);
[DropDetector(1), DropDetector(1), DropDetector(2)]
, length = 2iter.next()
panicsDropDetector(1)
gets dropped twice.We'd recommend wrapping the vector in
ManuallyDrop
while performing these operations to avoid this issue.The text was updated successfully, but these errors were encountered: