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(interpreter): Stack push_slice fix and dup with pointers (#837) #837

Merged
merged 2 commits into from
Nov 7, 2023

Conversation

DaniPopes
Copy link
Collaborator

@DaniPopes DaniPopes commented Oct 25, 2023

  • get_unchecked{,_mut} is always UB if out of bounds. This is easy to overlook because it works correctly, but it's still UB. Use pointers instead.
  • Stack::push_slice (refactor: rewrite Stack::push_slice to allow arbitrary lengths #812) did not handle more than one word (32 bytes) correctly. Added simple unit tests to verify correct behavior. No performance changes.

@rakita
Copy link
Member

rakita commented Oct 26, 2023

  • get_unchecked{,_mut} is always UB if out of bounds. This is easy to overlook because it works correctly, but it's still UB. Use pointers instead.

The pointer would have the same UB behaviour, right? This is safe as to as the bounds are checked and we know the capacity of data vec.

@DaniPopes
Copy link
Collaborator Author

DaniPopes commented Oct 26, 2023

No because get_unchecked* returns a reference, which has way more requirements for validity than pointers.

get_unchecked docs say:

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.

Miri reports UB in Stack::dup on main:
image

@rakita
Copy link
Member

rakita commented Oct 27, 2023

No because get_unchecked* returns a reference, which has way more requirements for validity than pointers.

get_unchecked docs say:

Calling this method with an out-of-bounds index is undefined behavior even if the resulting reference is not used.

Miri reports UB in Stack::dup on main: image

That seems like a false positive, reference is just a sugar here.

It seems that Vec uses get_unchecked_mut from the slice that works on slice len so that is probably of reason for false positive as it does not know the capacity of the vector.

So just moving self.data.set_len(len + 1); above should fix miri

@DaniPopes
Copy link
Collaborator Author

DaniPopes commented Oct 27, 2023

It's still uninitialized memory, so a reference to that is always undefined behavior. It's not a false positive. Moving set_len might silence miri but I don't think it fixes the UB.

"it works" because we have checked the bounds of the stack allocation and it happens that the implementation detail for get_unchecked works out of bounds too (i think), but it's still out of bounds so it shouldn't be relied upon.

@rakita
Copy link
Member

rakita commented Oct 29, 2023

It's still uninitialized memory, so a reference to that is always undefined behavior. It's not a false positive. Moving set_len might silence miri but I don't think it fixes the UB.

"it works" because we have checked the bounds of the stack allocation and it happens that the implementation detail for get_unchecked works out of bounds too (i think), but it's still out of bounds so it shouldn't be relied upon.

You are right, uninit memory should be dealt with, I have spent a lot of time in cpp land so this doesn't trigger me. Uninit can be a big problem and UB when you have a type that does the Drop or possibly the padding, for U256 this is not the case so it is considered safe here and not a UB.

Good read here for exactly this: rust-lang/rust-clippy#4483
It seems MaybeUninit was made to address this: https://doc.rust-lang.org/std/mem/union.MaybeUninit.html

Copy link
Member

@rakita rakita left a comment

Choose a reason for hiding this comment

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

lgtm

@rakita rakita merged commit 50726f3 into bluealloy:main Nov 7, 2023
8 checks passed
@rakita rakita changed the title fix(interpreter): stack UB and push_slice impl fix(interpreter): Stack push_slice fix and dup with pointers (#837) Nov 7, 2023
@DaniPopes DaniPopes deleted the stack-ub branch November 7, 2023 17:46
@github-actions github-actions bot mentioned this pull request Jan 12, 2024
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.

None yet

2 participants