strake/containers.rs

panic safety: double drop may happen within `util::{mutate, mutate2}`

Closed this issue ยท 3 comments

Hello ๐Ÿฆ€ ,
we (Rust group @sslab-gatech) found a memory-safety/soundness issue in this crate while scanning Rust code on crates.io for potential vulnerabilities.

Issue Description

#[inline]
pub fn mutate<T, F: FnOnce(T) -> T>(p: &mut T, f: F) { unsafe { ptr::write(p, f(ptr::read(p))) } }
#[inline]
pub fn mutate2<S, T, F: FnOnce(S, T) -> (S, T)>(p: &mut S, q: &mut T, f: F) { unsafe {
let (x, y) = f(ptr::read(p), ptr::read(q));
ptr::write(p, x);
ptr::write(q, y);
} }

Functions mutate & mutate2 temporarily duplicate the ownership of an item using the given p (and q).
In case the given function f panics, the duplicated item will be dropped twice.

Proof of Concept

The given program below exhibits a double free error.
fn mutate() is invoked within btree.insert_with().

// Tested with `rustc 1.50.0-nightly (7f9c43cf9 2020-12-23)` on Ubuntu 18.04
use containers::collections::b_tree::BTree; // containers = "0.9.10"
use default_allocator::Heap; // default_allocator = "0.3"
use rel::Core; // rel = "0.2"

fn main() {
    if let Some(mut btree) = BTree::<i32, Box<u64>, Core, Heap>::new(Core, 20) {
        if btree.insert(2, Box::new(1)).is_ok() {
            while btree
                .insert_with(2, |x| {
                    let ret = match x {
                        Some(str) => str,
                        None => Box::new(0),
                    };
                    None::<Option<u64>>.unwrap();
                    return ret;
                })
                .is_err()
            {}
        }
    }
}

Program Output

thread 'main' panicked at 'called `Option::unwrap()` on a `None` value', examples/containers.rs:15:41
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
free(): double free detected in tcache 2
Aborted (core dumped)

Thank you for checking out this issue ๐Ÿ‘

Thanks for the report! Should be unbroken since 7389a24 (in the new version 0.9.11).

By the way, what tools are you scanning with? I'd like to know more about this project.

Thank you for your quick feedback!
We are working to submit a paper to a conference using the tool, and we'll probably release it once our work gets accepted :)

I see you have published a new release containing the fix!
Thank you for your response, and I will close the issue now ๐Ÿ‘