Skip to content

use-after-free when growing to the same size #148

Closed
@ehuss

Description

@ehuss

Attempting to call grow on a spilled SmallVec with a value equal to the current capacity causes it to free the existing data.

let mut v: SmallVec<[u8; 2]> = SmallVec::new();
v.push(0);
v.push(1);
// Cause it to spill.
v.push(2);
assert_eq!(v.capacity(), 4);
// grow with the same capacity
v.grow(4);
// The backing storage is now freed, here be dragons.
println!("{:?}", v);

In the grow method it falls through to deallocate.

I believe something like the following is the fix:

diff --git a/lib.rs b/lib.rs
index 5af32ba..b81b35a 100644
--- a/lib.rs
+++ b/lib.rs
@@ -664,6 +664,8 @@ impl<A: Array> SmallVec<A> {
                 if unspilled {
                     return;
                 }
+            } else {
+                return;
             }
             deallocate(ptr, cap);
         }

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions