From e211888407db32fcec53f4fa9eb84acdbdf59f87 Mon Sep 17 00:00:00 2001 From: blake2-ppc Date: Thu, 12 Sep 2013 05:00:25 +0200 Subject: [PATCH] std::at_vec: Fix segfault on overflow when resizing ~[@T] Easy to reproduce: let mut v = ~[@1]; v.resize(-1); // success a.k.a silent failure v.push(@2); // segfault --- src/libstd/at_vec.rs | 13 ++++++++----- src/libstd/vec.rs | 8 ++++++++ 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/libstd/at_vec.rs b/src/libstd/at_vec.rs index ce8e90e1a4324..42f511f722dab 100644 --- a/src/libstd/at_vec.rs +++ b/src/libstd/at_vec.rs @@ -230,13 +230,16 @@ pub mod raw { // Implementation detail. Shouldn't be public #[allow(missing_doc)] pub fn reserve_raw(ty: *TyDesc, ptr: *mut *mut Box>, n: uint) { - + // check for `uint` overflow unsafe { - let size_in_bytes = n * (*ty).size; - if size_in_bytes > (**ptr).data.alloc { - let total_size = size_in_bytes + sys::size_of::>(); + if n > (**ptr).data.alloc / (*ty).size { + let alloc = n * (*ty).size; + let total_size = alloc + sys::size_of::>(); + if alloc / (*ty).size != n || total_size < alloc { + fail!("vector size is too large: %u", n); + } (*ptr) = local_realloc(*ptr as *(), total_size) as *mut Box>; - (**ptr).data.alloc = size_in_bytes; + (**ptr).data.alloc = alloc; } } diff --git a/src/libstd/vec.rs b/src/libstd/vec.rs index b7274d58e1bba..9fc0eaf72b14d 100644 --- a/src/libstd/vec.rs +++ b/src/libstd/vec.rs @@ -3659,6 +3659,14 @@ mod tests { v.push(2); } + #[test] + #[should_fail] + fn test_overflow_does_not_cause_segfault_managed() { + let mut v = ~[@1]; + v.reserve(-1); + v.push(@2); + } + #[test] fn test_mut_split() { let mut values = [1u8,2,3,4,5];