Skip to content

std: avoid aliasing violations when wrapping opaque C types - #160848

Open
joboet wants to merge 1 commit into
rust-lang:mainfrom
joboet:opaque_c_alias
Open

std: avoid aliasing violations when wrapping opaque C types#160848
joboet wants to merge 1 commit into
rust-lang:mainfrom
joboet:opaque_c_alias

Conversation

@joboet

@joboet joboet commented Aug 10, 2026

Copy link
Copy Markdown
Member

Fixes #160815 (and some other instances of the same problem)

See the new documentation of COpaque for a detailed description of the kinds of issues solved by this. In short: creating mutable references to the opaque types from pthread is unsound since some platforms (at least AIX) store an intrinsically list of these types and the creation of the mutable reference (e.g. in the drop glue) invalidates the other pointers to the type.

This doesn't just apply to the internal pthread Condvar and Mutex abstraction as described in the issue, but also to all other opaque types – nobody is promising us that these are not internally aliased. Hence this PR adds an internal COpaque helper type which uses a combination of UnsafePinned and MaybeUninit to relax all relevant requirements added by Rust's operational semantics.

CC @RalfJung I'd love to hear your opinion on this
r? libs

@rustbot rustbot added O-unix Operating system: Unix-like S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Aug 10, 2026
@rust-log-analyzer

This comment has been minimized.

@joboet
joboet force-pushed the opaque_c_alias branch 2 times, most recently from feb6204 to 086a6d2 Compare August 10, 2026 11:42
@rust-log-analyzer

This comment has been minimized.

@ais523

ais523 commented Aug 11, 2026

Copy link
Copy Markdown

I noticed something interesting while working on the opsem of this, and it might make sense to call it out in the documentation in order to help make the safety proofs easier to understand.

Normally in Rust, if you convert a reference into a pointer, you cannot use the pointer outside the lifetime of the reference without causing aliasing violations. It's as though raw pointers have lifetimes, and copy them from the reference they're created from (but you get UB rather than a borrow checker error if you violate them). This is the root cause behind #160815; a reference was converted to a pointer, but the pointer outlived the reference. (Although UnsafeCell often helps with this, because all the &UnsafeCell can often be inferred to have the same lifetime and thus the pointers can often last as long as the UnsafeCell does, this mechanism fails in situations where an &mut is created, like in drop.)

With UnsafePinned, and wrappers for it like COpaque, this is no longer true: if you convert a reference to it into a pointer, the pointer is opsem-usable for as long as the containing memory is not used via anything other than UnsafePinned types, and that's the reason why code like Condvar is sound after the change.

In addition to mentioning this in COpaque's documentation, it should probably be mentioned in the safety comments of the uses of the variables (i.e. "this is sound because a pointer obtained via a COpaque lasts until the memory is repurposed, we ask the OS to stop using the memory in our destructor, and because self is Pin our destructor is guaranteed to run before the memory is repurposed"). It took me a long time to understand why this is sound, so having it in a code comment would likely help other people to figure out why it is sound.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

O-unix Operating system: Unix-like S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Condvar and Mutex in std::sys::pal::unix::sync violate aliasing rules

5 participants