Kimundi / owning-ref-rs

A library for creating references that carry their owner with them.
MIT License
359 stars 50 forks source link

Unsoundness in `OwningRef::map_with_owner` and more #77

Open noamtashma opened 2 years ago

noamtashma commented 2 years ago

I found more unsoundness problems. This extends #61 .

In particular, OwningRef::map_with_owner allows creating an OwningRef that points at the owner, which can be moved.

fn unstable_address() {
    let ow_ref = OwningRef::new(Box::new(5));
    let new_ow_ref = ow_ref.map_with_owner(|owner, _my_ref| owner);
    println!("Reading memory that was moved from: {}", *new_ow_ref);
}

This by itself can be fixed by replacing map_with_owner with a method that only gives out a reference to the referent of the owner, like this:

pub fn map_with_owner<F, U: ?Sized>(self, f: F) -> OwningRef<'t, O, U>
    where O: StableAddress + Deref,
        F: for<'a> FnOnce(&'a O::Target, &'a T) -> &'a U

In addition, There's unsoundness combining a conversion from OwningRefMut to OwningRef together with methods that can read the owner of an OwningRef, like so:

fn ref_mut_to_ref() {
    use core::cell::RefCell; // `Cell` and any other kind of cell also works
    let ow_ref = OwningRefMut::new(Box::new(RefCell::new(Box::new(5))));
    let new_ow_ref = ow_ref.map(|cell| &**cell.get_mut());
    // Have to convert to `OwningRef` In order to use `OwningRef::as_owner`
    // instead of `OwningRefMut::as_owner`.
    *new_ow_ref.as_owner().borrow_mut() = Box::new(9);
    println!("Reading deallocated memory: {}", *new_ow_ref);
}

OwningRefMut::{as_owner, as_owner_mut} can also be used, as #61 shows.

There are two ways to fix this, and each choice corresponds to a small difference in the meaning and invariants of OwningRef:

Essentially, these are two distinct types, which are both sound by themselves, and a third option is to have both types.

slonik-az commented 2 years ago

This repo has not received any commits for two years (since Feb 27, 2020) and seems unmaintained. Did you try to contact the owners directly?

noamtashma commented 10 months ago

Hey everyone, since so long has passed and still the maintainer hasn't showed up and no one made a replacement crate, I decided to make my pull request into a crate.

It's available as safer_owning_ref.