Skip to content

Commit

Permalink
Fix potential buffer overflow in insert_many
Browse files Browse the repository at this point in the history
Fixes #252.
  • Loading branch information
mbrubeck committed Jan 8, 2021
1 parent 0b2b4e5 commit 85593a4
Show file tree
Hide file tree
Showing 2 changed files with 26 additions and 1 deletion.
12 changes: 11 additions & 1 deletion src/lib.rs
Expand Up @@ -1041,14 +1041,24 @@ impl<A: Array> SmallVec<A> {
let mut cur = ptr.add(num_added);
if num_added >= lower_size_bound {
// Iterator provided more elements than the hint. Move trailing items again.

// `reserve` needs `len` to be accurate.
self.set_len(old_len + num_added);
let guard_len = guard.len;
guard.len = 0; // in case `reserve` panics, don't double-free in guard.drop().

// Grow the vector by 1.
self.reserve(1);

let start = self.as_mut_ptr();
ptr = start.add(index);
cur = ptr.add(num_added);
ptr::copy(cur, cur.add(1), old_len - index);

// Restore the guard.
self.set_len(0);
guard.start = start;
guard.len += 1;
guard.len = guard_len + 1;
guard.skip.end += 1;
}
ptr::write(cur, element);
Expand Down
15 changes: 15 additions & 0 deletions src/tests.rs
Expand Up @@ -905,3 +905,18 @@ fn empty_macro() {
fn zero_size_items() {
SmallVec::<[(); 0]>::new().push(());
}

#[test]
fn test_insert_many_overflow() {
let mut v: SmallVec<[u8; 0]> = SmallVec::new();

// Spill on heap
v.push(123);

// Prepare an iterator with small lower bound
let iter = (0u8..=255).filter(|n| n % 2 == 0);
assert_eq!(iter.size_hint().0, 0);

// Triggering the bug
v.insert_many(0, iter);
}

0 comments on commit 85593a4

Please sign in to comment.