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

Calling a C function with a wrong type from Miri results in panic #1355

Closed
kpp opened this issue Apr 22, 2020 · 6 comments · Fixed by #1370
Closed

Calling a C function with a wrong type from Miri results in panic #1355

kpp opened this issue Apr 22, 2020 · 6 comments · Fixed by #1370
Labels
A-shims Area: This affects the external function shims C-bug Category: This is a bug. E-good-first-issue A good way to start contributing, mentoring is available

Comments

@kpp
Copy link

kpp commented Apr 22, 2020

Code

extern "C" {
    fn malloc(size: u32) -> *mut std::ffi::c_void;
}

fn main() {
    unsafe { malloc(42) };
}

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=c161d6b819c07b126414739cf6e32274

Meta

rustc 1.44.0-nightly (3712e11a8 2020-04-12) running on x86_64-unknown-linux-gnu

Error output

thread 'rustc' panicked at 'assertion failed: `(left == right)`
  left: `8`,
 right: `4`', /rustc/3712e11a828af2eea273a3e7300115e65833fbc5/src/libstd/macros.rs:16:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace

error: internal compiler error: unexpected panic

note: the compiler unexpectedly panicked. this is a bug.

note: we would appreciate a bug report: https://github.com/rust-lang/rust/blob/master/CONTRIBUTING.md#bug-reports

note: rustc 1.44.0-nightly (3712e11a8 2020-04-12) running on x86_64-unknown-linux-gnu

note: compiler flags: -Z always-encode-mir -Z mir-emit-retag -Z mir-opt-level=0 -C debug-assertions=on -C codegen-units=1 -C debuginfo=2 --crate-type bin

note: some of the compiler flags provided by cargo are hidden

error: could not compile `playground`.

To learn more, run the command again with --verbose.

@RalfJung RalfJung transferred this issue from rust-lang/rust Apr 22, 2020
@RalfJung
Copy link
Member

RalfJung commented Apr 22, 2020

Thanks for the report! I moved this to the Miri tracker.

This is conceptually close to #1272, but much harder to fix than that. We'd need variants of our to_usize etc methods that raise UB instead of ICEing when the size does not match. Then we have to use them everywhere. And we have to do that without making all the shim code even less readable.

The good news is that I don't think this issue can hide UB, it just leads to bad error messages.

@RalfJung RalfJung added A-shims Area: This affects the external function shims C-bug Category: This is a bug. labels Apr 22, 2020
@RalfJung
Copy link
Member

Well I guess an alternative might be to adjust our existing Scalar::to_* methods to replace the assertion that the size matches, with raising UB when it does not match. In some cases that could be false UB and actually indicate a bug in Miri, but I am not sure if it's worth spending the effort to tease those cases apart. @oli-obk what do you think?

@oli-obk
Copy link
Contributor

oli-obk commented Apr 22, 2020

So basically rustc will always be fine with the panicking variants, but miri needs non-panicking variants? I guess we could play with extension traits to get such behaviour differences between miri and ctfe/engine but that would be very confusing.

I'm fine with just making all the methods return results, even if most/all of the errors reported on these mean bugs in ctfe/engine, but it may make debugging harder if we actually have bugs again there. Similar to the size field on Scalar::Bits

@RalfJung
Copy link
Member

It may actually also make debugging easier because errors, unlike assertions, point to the MIR span that was evaluated when they got triggered. ;)

@RalfJung RalfJung added the E-good-first-issue A good way to start contributing, mentoring is available label Apr 24, 2020
@samrat
Copy link
Contributor

samrat commented Apr 25, 2020

I'd like to work on this issue.

@RalfJung
Copy link
Member

@samrat great. :)

This issue will mostly (maybe entirely) require work on rustc, where the assertions that we are hitting lie.

The first step (and maybe the only step) is to turn this assertion into raising an appropriate interpreter error instead:

https://github.com/rust-lang/rust/blob/40008dcb494a00571123b7d59115068a200ebe34/src/librustc_middle/mir/interpret/value.rs#L396

Probably a new variant should be added to this enum for that purpose:

https://github.com/rust-lang/rust/blob/40008dcb494a00571123b7d59115068a200ebe34/src/librustc_middle/mir/interpret/error.rs#L309

Once that fix lands on rustc, a testcase should be added to Miri.

Dylan-DPC-zz pushed a commit to Dylan-DPC-zz/rust that referenced this issue Apr 26, 2020
…RalfJung

[miri] Throw UB if target size and data size don't match

Issue: rust-lang/miri#1355

If an extern C function is defined as

```
extern "C" {
    fn malloc(size: u32) -> *mut std::ffi::c_void;
}
```

on a 64-bit machine(ie. pointer sizes don't match), return undefined behaviour from Miri when [converting the argument into machine_usize](https://github.com/rust-lang/miri/blob/master/src/shims/foreign_items.rs#L200)
@bors bors closed this as completed in 4556daa Apr 27, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-shims Area: This affects the external function shims C-bug Category: This is a bug. E-good-first-issue A good way to start contributing, mentoring is available
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants