-
Notifications
You must be signed in to change notification settings - Fork 22
Open
Description
The Vec::insert method can trigger undefined behavior when called with an out-of-bounds index that is significantly larger than the vector's length. The method performs pointer arithmetic with the unchecked index before validating that index <= len, leading to an out-of-bounds pointer offset.
Vulnerability Details
Location: src/vec/mod.rs lines 1447-1469
Affected Code:
Lines 1447 to 1469 in 1644e70
| pub fn insert(&mut self, index: usize, element: T) { | |
| #[cold] | |
| #[inline(never)] | |
| fn assert_failed(index: usize, len: usize) -> ! { | |
| panic!( | |
| "insertion index (is {}) should be <= len (is {})", | |
| index, len | |
| ); | |
| } | |
| let len = self.len(); | |
| // space for the new element | |
| if len == self.buf.capacity() { | |
| self.reserve(1); | |
| } | |
| unsafe { | |
| // infallible | |
| // The spot to put the new value | |
| { | |
| let p = self.as_mut_ptr().add(index); | |
| match cmp::Ord::cmp(&index, &len) { |
Root Cause
The bounds check (index <= len) is performed after the unsafe pointer arithmetic operation self.as_mut_ptr().add(index). When index is larger than the allocation size, this causes undefined behavior before the validation can panic.
Proof of Concept
fn main() {
let mut v: Vec<u8> = Vec::new();
v.push(1);
let idx = v.capacity().saturating_mul(4).saturating_add(1);
v.insert(idx, 2);
}Miri Output
error: Undefined Behavior: in-bounds pointer arithmetic failed: attempting to offset pointer by 33 bytes, but got alloc230 which is only 8 bytes from the end of the allocation
--> /home/usr/.cargo/registry/src/index.crates.io-1949cf8c6b5b557f/allocator-api2-0.4.0/src/vec/mod.rs:1468:25
|
1468 | let p = self.as_mut_ptr().add(index);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Undefined Behavior occurred here
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels