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

Miscompilation when using LLVM feature LVI CFI #77607

Closed
jethrogb opened this issue Oct 6, 2020 · 3 comments · Fixed by #77710
Closed

Miscompilation when using LLVM feature LVI CFI #77607

jethrogb opened this issue Oct 6, 2020 · 3 comments · Fixed by #77710
Labels
A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug.

Comments

@jethrogb
Copy link
Contributor

jethrogb commented Oct 6, 2020

// bug.rs
#![no_std]

#[no_mangle]
pub extern "C" fn do_error() -> i32 {
    let buf: [u8; 0] = [];
    (&buf).get(..)
        .map(|_src| {
             0x01020304050607080910111213141516u128
        })
        .map_or(true, |x| x == 0x01020304050607080910111213141516) as _
}

#[panic_handler]
fn panic(_panic: &core::panic::PanicInfo<'_>) -> ! {
    loop {}
}

do_error should always return 1. But it doesn't if you enable the lvi-cfi feature. The miscompilation only happens with opt-level=0.

Compare:

rustc -C panic=abort --crate-type=staticlib bug.rs && gcc test.c libbug.a && ./a.out
rustc -C panic=abort --crate-type=staticlib -C target-feature=+lvi-cfi bug.rs && gcc test.c libbug.a && ./a.out
// test.c
#include <assert.h>

int main() {
	assert(do_error() == 1);
}

Here's a slightly reduced LLVM IR: bug.ll.txt

Difference in llc output when adjusting the lvi-cfi feature attribute on #0: bug.diff.txt. I can't really see any obvious culprits.

I want to file an LLVM bug as well but I don't have an account.

cc @raoulstrackx @mzohreva @scottconstable

@jethrogb
Copy link
Contributor Author

jethrogb commented Oct 6, 2020

I think the Rust calling convention may be using rcx whereas LVI-CFI assumes it's unused?

@jethrogb
Copy link
Contributor Author

jethrogb commented Oct 6, 2020

Actually you can see the issue in the assembly diff I posted, lines 45-51.

@jethrogb
Copy link
Contributor Author

jethrogb commented Oct 6, 2020

I've filed an LLVM bug now based on this reduced example:

pub extern "Rust" fn ret_u64_u128() -> (u64, u128) {
    (1, 0x20000000000000003)
}

https://bugs.llvm.org/show_bug.cgi?id=47740

@camelid camelid added A-LLVM Area: Code generation parts specific to LLVM. Both correctness bugs and optimization-related issues. C-bug Category: This is a bug. labels Oct 7, 2020
@bors bors closed this as completed in d252848 Oct 9, 2020
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.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants