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

Fix UB in pop/push under Stacked Borrows #16

Merged
merged 1 commit into from
Nov 10, 2024

Conversation

ryanavella
Copy link
Contributor

cargo miri test reports that Vec32::pop and Vec32::push have UB under the Stacked Borrows model.

The UB occurs when a pointer is used to read/write out-of-bounds of the slice it was created from. This slice is conjured by auto-deref of self in both implementations.

mediumvec/src/vec32.rs

Lines 113 to 114 in 398db61

self.len -= 1;
Some(ptr::read(self.get_unchecked(self.len as usize)))

mediumvec/src/vec32.rs

Lines 101 to 103 in 398db61

let end = self.as_mut_ptr().offset(self.len as isize);
ptr::write(end, value);
self.len += 1;

In other words, we are dealing with a variant of rust-lang/unsafe-code-guidelines#134

This PR silences miri by explicitly going through pointers so that we don't accidentally retag and reduce the provenance.

…ather than a pointer derived from an intermediate auto-deref'd slice. This silences miri and fixes known UB under the Stacked Borrows model.
Copy link
Owner

@mbrubeck mbrubeck left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you!

@mbrubeck mbrubeck merged commit 28546f2 into mbrubeck:master Nov 10, 2024
@ryanavella
Copy link
Contributor Author

@mbrubeck Just had a related thought, I know it is typical for authors to yank crate versions with UB but I'm not sure if it is worth yanking here. Miri passes cleanly with -Zmiri-tree-borrows.

Interestingly though, cargo test (no miri) on old versions of mediumvec panics with the following:

thread 'vec32::tests::it_works' panicked at core\src\panicking.rs:223:5:
unsafe precondition(s) violated: slice::get_unchecked requires that the index is within the slice
stack backtrace:
...
   6: mediumvec::vec32::Vec32<i32>::pop<i32>
             at .\src\vec32.rs:114
...

I think the std folks added a new debug_assert! precondition in slice::get_unchecked? This definitely didn't panic before, but it started to introduce panics in my production code.

Again, probably not worthy of yanking old versions, but I thought I'd let you know that I'm currently locally patching mediumvec until a new release is cut.

@mbrubeck
Copy link
Owner

I have released mediumvec 1.3.1 with this fix.

I don’t see a major benefit of yanking old versions here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants