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

add collection of deliberate cases of UB #448

Merged
merged 7 commits into from
Aug 19, 2023

Conversation

RalfJung
Copy link
Member

Fixes #158

@RalfJung RalfJung force-pushed the deliberate-ub branch 2 times, most recently from e868b0a to 05daf0a Compare August 13, 2023 13:55
Copy link

@CAD97 CAD97 left a comment

Choose a reason for hiding this comment

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

LGTM, though two potential future refinements:

  • Differentiate somehow between cases which cause LLVM UB and which are UB in the frontend but not in the backend yet; the former is more pressing than the latter, which could be argued as "just" relying on implementation details.
  • Add some examples of patterns that SB considers UB but people want to do anyway (e.g. &Header, probably "work in progress" given TB resolves it).

But this is useful even without, and these both are more about the "potentially UB" class than the "definite UB" class that this is more about.

resources/deliberate-ub.md Outdated Show resolved Hide resolved
To fix this we need to be able to perform atomic loads at type `MaybeUninit<u32>`.
* Similar to the previous case, the `atomic-memcpy` crate uses the [standard `Atomic*` types to load potential padding or pointer bytes](https://github.com/taiki-e/atomic-memcpy/blob/b7b82bface0f24c5a9171f2d0626871c61302152/src/lib.rs#L323).
This is a user-space attempt to implement bytewise atomic memcpy, so [adding that as a native operation](https://github.com/rust-lang/rfcs/pull/3301) should fix this.
* `bytes` does [a non-atomic plain load that races](https://github.com/tokio-rs/bytes/blob/dea868a4b0eec28877e9013702c0ae12dbc40c4b/src/bytes.rs#L2508),
Copy link
Member

Choose a reason for hiding this comment

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

IIRC, this no longer exists in the latest version of bytes.

Copy link
Member Author

@RalfJung RalfJung Aug 13, 2023

Choose a reason for hiding this comment

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

Interesting, I can't find it in current versions either. Do you know what they are doing instead? I can't find any atomics in BytesMut, did they just give up on having the mutable version be thread-safe?

Copy link
Member Author

Choose a reason for hiding this comment

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

This seems to have happened with a big refactor. @seanmonstar is the old problem with atomics in BytesMut::kind completely gone or is that now just somehow moved somewhere else?

@RalfJung
Copy link
Member Author

Add some examples of patterns that SB considers UB but people want to do anyway (e.g. &Header, probably "work in progress" given TB resolves it).

We already have an issue open for that, so not sure it's worth also going out and hunting for examples. Other people can make PRs after this one lands. :)

@RalfJung
Copy link
Member Author

If the bytes issue is truly resolved, then it looks like every item in the list has a least an RFC that would resolve it -- except for needing to do atomic loads at types like MaybeUninit<i32>.


* crossbeam's `AtomicCell` implements an SeqLock, which [is well-known to not be compatible with the C++ memory model](http://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf).
Specifically the problem is [this non-atomic volatile read](https://github.com/crossbeam-rs/crossbeam/blob/5d07fe43540d7f21517a51813acd9332744e90cb/crossbeam-utils/src/atomic/atomic_cell.rs#L980) which can cause data races and hence UB.
This would be fine if we either (a) adopted LLVM's handling of memory races (then the problematic read would merely return `undef` instead of UB due to a data race), or (b) added [bytewise atomic memcpy](https://github.com/rust-lang/rfcs/pull/3301) and used that instead of the non-atomic volatile load.
Copy link
Member Author

Choose a reason for hiding this comment

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

@taiki-e if I have you around anyway, could you briefly say if this is correct -- if Rust gets atomic bytewise memcpy, then AtomicCell could use them?

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, RFC 3301 should be enough to fix it.

That said, I think we will likely fix it by adopting "(c) use inline assembly instead of the non-atomic volatile load" before using the implementation of RFC 3301.

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, inline assembly is always an option, though usually not a nice one.

@RalfJung
Copy link
Member Author

I explored bytes a bit more and I'm fairly sure the problematic code is completely gone, as part of a change describes as "Removed ability to mutate the underlying memory from the Bytes type". So I removed this item from the list. The smol-rs crates are now using inline assembly instead of relying on compare_exchange having the effects of a fence, so that is fixed, too. That leaves only the AtomicCell issues, both for the fast path and the fallback path. :)

I'll merge this now, we can always edit this further later. This was definitely a useful update!

@RalfJung RalfJung merged commit 2b1b843 into rust-lang:master Aug 19, 2023
@RalfJung RalfJung deleted the deliberate-ub branch August 19, 2023 21:14

### Cases related to concurrency

* crossbeam's `AtomicCell` "fallback path" uses a SeqLock, which [is well-known to not be compatible with the C++ memory model](http://www.hpl.hp.com/techreports/2012/HPL-2012-68.pdf).
Copy link

Choose a reason for hiding this comment

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

This link doesn't load for me, I think because of the http:// rather than https://.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good catch, I'll fix it in the repo. (My browser is in https-always mode so even the http link works 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.

Collection of cases of deliberate UB
4 participants