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

Invalid equality check result for usizes obtained from function pointers #73722

Closed
Riateche opened this issue Jun 25, 2020 · 8 comments · Fixed by #80796
Closed

Invalid equality check result for usizes obtained from function pointers #73722

Riateche opened this issue Jun 25, 2020 · 8 comments · Fixed by #80796
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@Riateche
Copy link

Riateche commented Jun 25, 2020

Code:

fn main() {
    fn x() {}
    fn y() {}

    let a = x as usize;
    let b = y as usize;
    
    assert_eq!(a, b);
}

Output in release mode:

thread 'main' panicked at 'assertion failed: `(left == right)`
  left: `94740677858160`,
 right: `94740677858160`', src/main.rs:8:5

Playground

There is a similar issue about comparing function pointers, but incorrect comparison of usize may be more dangerous. For example, if unsafe code checks the equality between usize to uphold its invariant, passing values obtained this way may break the invariant, even though the unsafe code itself didn't work with function pointers.

@Riateche Riateche added the C-bug Category: This is a bug. label Jun 25, 2020
@JohnTitor JohnTitor added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jun 26, 2020
@RalfJung
Copy link
Member

RalfJung commented Aug 8, 2020

In some sense there's no bug here, this is expected: comparing function pointers should behave the same with or without the usize cast.

What is more surprising is that they print the same. This indicates that comparison is non-deterministic... which is rather problematic indeed, and could break plenty of LLVM optimizations.

@RalfJung
Copy link
Member

RalfJung commented Aug 8, 2020

Indeed this can be turned into a demonstration of non-deterministic comparison:

#[inline(never)]
fn nop(x: usize) -> usize { x }

fn main() {
    fn x() {}
    fn y() {}

    let a = x as usize;
    let b = y as usize;
    
    assert_eq!(nop(a), nop(b));
    assert_eq!(a, b);
}

The second assertion fails, the first passes (in release mode on 1.45.2). That's no good. In principle this could lead to a soundness bug, though I am not sure if that can be actually done in practice.

Cc @rust-lang/wg-unsafe-code-guidelines @rust-lang/lang

@RalfJung
Copy link
Member

This is an LLVM bug: https://bugs.llvm.org/show_bug.cgi?id=47090

@RalfJung RalfJung added the A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. label Aug 10, 2020
@RalfJung
Copy link
Member

But MIR optimizations also have to be aware that folding equality tests on functions is subtle (Cc @rust-lang/wg-mir-opt). And @oli-obk recently had to prevent me from making a similar mistake for pointer equality tests in CTFE (Cc @rust-lang/wg-const-eval).

@RalfJung
Copy link
Member

The LLVM bug has been fixed. @Mark-Simulacrum (pinging you in lieu of there being a way to ping the LLVM WG), do you usually backport such fixes or wait for the next release?

@Mark-Simulacrum
Copy link
Member

cc @cuviper @nikic @nagisa (pinging LLVM WG)

I suspect we'll want to backport the patch ourselves, and try to nominate it for LLVM 11 (since that's not yet released, and we're currently on a release candidate). https://reviews.llvm.org/D87123 is the thing to backport I think.

@RalfJung RalfJung added the I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness label Sep 17, 2020
@rustbot rustbot added the I-prioritize Issue: Indicates that prioritization has been requested for this issue. label Sep 17, 2020
@apiraino
Copy link
Contributor

Assigning P-medium as discussed as part of the Prioritization Working Group procedure and removing I-prioritize.

@apiraino apiraino added P-medium Medium priority and removed I-prioritize Issue: Indicates that prioritization has been requested for this issue. labels Sep 17, 2020
bors added a commit to rust-lang-ci/rust that referenced this issue Sep 17, 2020
…-obk

move guaranteed{ne,eq} implementation to compile-time machine

Currently, Miri needs a special hack to avoid using the core engine implementation of these intrinsics. That seems silly, so let's move them to the CTFE machine, which is the only machine that wants to use them.

I also added a reference to rust-lang#73722 as a warning to anyone who wants to adjust `guaranteed_eq`.
@cuviper
Copy link
Member

cuviper commented Sep 18, 2020

Discussion on the LLVM bug is that it's too late for 11.0.0, but could be added to 11.0.1.

If someone wants to see the fix sooner in rust's fork, I'm happy to review PRs:
https://rustc-dev-guide.rust-lang.org/backend/updating-llvm.html#bugfix-updates

@bors bors closed this as completed in 330e196 Jan 13, 2021
bors pushed a commit to rust-lang-ci/rust that referenced this issue Jan 20, 2021
Original message:
Rollup merge of rust-lang#80796 - cuviper:llvm-11.0.1, r=nikic

Update to LLVM 11.0.1

This updates to a new LLVM branch, rebased on the upstream `llvmorg-11.0.1`. All our patches applied cleanly except the fortanix unwind changes, which just needed a small adjustment in cmake files.

r? `@nikic`
Fixes rust-lang#73722
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness P-medium Medium priority T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants