Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BTree's insert_fit breaks pointer provenance rules #78477

Closed
RalfJung opened this issue Oct 28, 2020 · 7 comments · Fixed by #78480
Closed

BTree's insert_fit breaks pointer provenance rules #78477

RalfJung opened this issue Oct 28, 2020 · 7 comments · Fixed by #78480
Labels
A-collections Area: `std::collection` C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-medium Medium priority T-libs Relevant to the library team, which will review and decide on the PR/issue.

Comments

@RalfJung
Copy link
Member

RalfJung commented Oct 28, 2020

This code violates pointer provenance rules:

    fn insert_fit(&mut self, key: K, val: V) -> *mut V {
        debug_assert!(self.node.len() < CAPACITY);

        unsafe {
            slice_insert(self.node.keys_mut(), self.idx, key);
            slice_insert(self.node.vals_mut(), self.idx, val);
            self.node.as_leaf_mut().len += 1;

            self.node.val_mut_at(self.idx)
        }
    }

Specifically, self.node.keys_mut() returns a slice covering the previously existing elements of this node, but it is used to also access the new element one-past-the-end of the previous slice.

Either slice_insert needs to be passed a slice covering all the memory it needs to access (of type &mut [MaybeUninit<_>]), or else it needs to be passed a raw pointer (that may access the entire buffer) and a length. But keys_mut/vals_mut can only be used to access elements that already exist, not to initialize new elements.

Cc @ssomers

@ssomers
Copy link
Contributor

ssomers commented Oct 28, 2020

I was surprised when I realized that, but I think it has been like that for a long time. So I wonder if you're tightening up Miri or I should check out where we went wrong recently?

@RalfJung
Copy link
Member Author

I only found this when tightening Miri while debugging why #77187 broke BtreeMap (that PR should only break code that casts pointers to integers and back, with this code does not do AFAIK).

@ssomers
Copy link
Contributor

ssomers commented Oct 28, 2020

Ok. The fix conflicts with #78476, so maybe it's better to add it onto that PR?

@RalfJung
Copy link
Member Author

Probably, yes. I spent enough time on this for now that I should have used for the work I am paid to do. ;) So I decided to just open the issue instead of trying to fix this problem myself.

@jonas-schievink jonas-schievink added A-collections Area: `std::collection` C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Oct 28, 2020
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Oct 28, 2020
@RalfJung
Copy link
Member Author

rust-lang/miri#1603 adds a flag to Miri that lets you opt-in to that more strict tracking yourself. Note that this might reject some valid code when integer-pointer casts are involved.

@spastorino
Copy link
Member

Assigning P-high as discussed as part of the Prioritization Working Group procedure and removing I-prioritize.

@spastorino spastorino added P-high High priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Oct 28, 2020
@RalfJung
Copy link
Member Author

RalfJung commented Oct 28, 2020

FWIW, these are violations with Stacked Borrows -- but the actual impact is likely low as we barely exploit aliasing assumptions currently. So IMO there is no reason to treat this as high priority. It barely qualifies as a soundness issue, given that Stacked Borrows is purely experimental (and not RFC'd or anything).

@spastorino spastorino added P-medium Medium priority and removed P-high High priority labels Oct 29, 2020
@bors bors closed this as completed in 2187f3c Nov 10, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-collections Area: `std::collection` C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-medium Medium priority T-libs Relevant to the library team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants