-
Notifications
You must be signed in to change notification settings - Fork 10
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 when calling get()
after clear()
for InlineStableVec
#45
Conversation
worth mentioning this doesn't manage to fix all the UB from Adding something like |
I spent some time digging into the other miri failure I was seeing
|
@@ -162,7 +162,7 @@ impl<T> Core<T> for OptionCore<T> { | |||
unsafe fn has_element_at(&self, idx: usize) -> bool { | |||
debug_assert!(idx < self.cap()); | |||
|
|||
self.data.get_unchecked(idx).is_some() | |||
idx < self.len() && self.data.get_unchecked(idx).is_some() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think perhaps this should instead be checked in the safe function StableVecFacade::has_element_at
by changing the following check to self.len()
, however running into some miri failures under tree-borrows with that change in place.
Line 550 in 7e6d29c
if index >= self.core.cap() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that my comment above is wrong and the patch as is probably right as-is in that it seems to make it match the behavior of the other *Core
implementations, but those can implement has_element_at
in a way that don't cause an uninitialized read.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that it would be better if the safe method checks for len
and we change the pre-condition of the unsafe has_element_at
to idx <= len
. But that would be a breaking change and I certainly want to release this as a patch version. And the patch as presented isn't bad, the worst case would be that the idx
is checked against cap
first and then against len
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, I made a long attempt at that, between those two comments, the main thing is there are a lot of other cases mostly the find_empty_slot*
ones that also call has_element_at
, and so all those need to be updated too.
It much more involved at least than I had initially imagined in the first comment.
Ouch, thanks a lot for catching and fixing this. I somehow never considered miri getting better over time and that I should rerun the tests. Disappointing to see that despite me cautions, there is another memory unsafety issue with this crate. Meh. |
This one actually was what caused me to look into miri, because I ran into the UB from entirely safe code. |
The test added here was failing, this adds manual bounds checking on
has_element_at
,for reasons I don't yet understand this manual bounds checking is not equivalent to
self.data.get(idx).is_some()
,which appears to actually just break everything.