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

Windows: Prevent pointer provenance "optimization" #72

Merged

Conversation

jrose-signal
Copy link
Contributor

@jrose-signal jrose-signal commented Oct 6, 2023

On Windows, we can't just use extern symbols for our "start" and "end" pointers; we have to define them within the module. The current implementation uses a zero-length array for that. However, the compiler can track uses of that pointer through the creation of the distributed slice, and will optimize out accesses that are "out of bounds". Pass the pointer through core::mem::black_box to prevent this.

Potentially a fix for #67, which has similar symptoms. Our project likewise failed under LTO and passed normally, but this test change fails for me without the fix even with LTO turned off.

On Windows, we can't just use extern symbols for our "start" and "end"
pointers; we have to define them within the module. The current
implementation uses a zero-length array for that. However, the compiler
can track uses of that pointer through the creation of the distributed
slice, and will optimize out accesses that are "out of bounds". Pass the
pointer through core::mem::black_box to prevent this.
Copy link
Owner

@dtolnay dtolnay 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! Nice find.

@dtolnay dtolnay merged commit c0ff555 into dtolnay:master Oct 6, 2023
13 checks passed
@jrose-signal jrose-signal deleted the windows-pointer-provenance-fix branch October 6, 2023 22:41
@dtolnay
Copy link
Owner

dtolnay commented Oct 6, 2023

Published in linkme 0.3.16.

@nvzqz
Copy link
Contributor

nvzqz commented Oct 8, 2023

I'm very concerned about this change with regard to the documentation of black_box. Sure this change works today, but it's not a guarantee.

Programs cannot rely on black_box for correctness, beyond it behaving as the identity function

@jrose-signal
Copy link
Contributor Author

Yeah, that's a fair point. I don't know of a 100% formally correct way to do this operation in current Rust (stable or nightly), because it involves taking an address (from a reference) and using it to construct a pointer with different provenance. (Even if the START addresses referred to non-zero-sized values, you'd still have this problem.) I tried spelling that start as usize as *const T and it did not fix the problem, and the nightly-only strict_provenance APIs don't formally help either because we are deliberately violating strict provenance based on external information (the linker behavior).

One of us could bring this up on users.rust-lang.org, perhaps. Still, black_box cannot make things any worse than they were before.

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.

3 participants