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

Shims should check ABI #1631

Closed
RalfJung opened this issue Nov 19, 2020 · 3 comments · Fixed by #1670
Closed

Shims should check ABI #1631

RalfJung opened this issue Nov 19, 2020 · 3 comments · Fixed by #1670
Labels
A-shims Area: This affects the external function shims C-enhancement Category: a PR with an enhancement or an issue tracking an accepted enhancement E-good-first-issue A good way to start contributing, mentoring is available

Comments

@RalfJung
Copy link
Member

RalfJung commented Nov 19, 2020

Our shims for missing extern functions now all check that the right number of arguments is being passed. However, they should also check that the right ABI is used.

To do this, probably first librustc_mir needs to be changed to even propagate this information to Miri's find_mir_or_eval_fn.

The goal is to reject buggy code like this:

fn main() {
    extern "Rust" { // should be "C"!
        fn malloc(size: usize) -> *mut std::ffi::c_void;
    }

    unsafe {
        let _ = malloc(0);
    };
}
@RalfJung RalfJung added A-shims Area: This affects the external function shims C-enhancement Category: a PR with an enhancement or an issue tracking an accepted enhancement E-good-first-issue A good way to start contributing, mentoring is available labels Nov 19, 2020
@unseddd
Copy link

unseddd commented Jan 8, 2021

Hi, I started looking into this issue a little, and wanted to ask for some guidance before diving too much deeper in the rabbit hole.

The check in miri/src/shims/mod.rs:44:

if this.tcx.is_foreign_item(instance.def_id())

and call to:

this.emulate_foreign_item(instance.def_id(), args, ret, unwind)

do matches on function name and OS type.

Since some ABI matching is done in latter function (and its inner calls), what other preliminary checks are needed in EvalContextExt::find_mir_or_eval_fn?

Should the arg types be matches against layouts for the target OS?

Should the OS from this.tcx.sess.target.os be checked against something supplied as an argument (or one of their inner field/values)?

Should a lookup of the function being interpreted be done with something like:

// Check foreign allocation
let alloc_id = this.machine.extern_static_alloc_id(&this.memory, instance.def.def_id())?;
match this.memory.get_fn_alloc(alloc_id) {
  Some(fn_val) => ... check fn_val matches instance?,
  None => throw error,
};

Thanks in advance for any help.

@RalfJung
Copy link
Member Author

RalfJung commented Jan 9, 2021

Since some ABI matching is done in latter function (and its inner calls), what other preliminary checks are needed in EvalContextExt::find_mir_or_eval_fn?

I am not sure if there are any other preliminary checks that can be done. It would have to be something that works uniformly for all functions.

I do not entirely understand the purpose of the checks you are proposing, or which issues they would resolve. To do the ABI check, the first step is to adjust find_mir_or_eval_fn and call_extra_fn in compiler/rustc_mir/src/interpret/machine.rs to also pass the rustc_target::spec::abi::Abi of the call to this function. This is the "ABI" that I am talking about in the issue. Then, in a separate PR on the Miri side, we can check that this ABI matches what we are expecting.

@unseddd
Copy link

unseddd commented Jan 10, 2021

I do not entirely understand the purpose of the checks you are proposing, or which issues they would resolve.

Yeah, glad I asked. Had the feeling I was going in the wrong direction 😄

To do the ABI check, the first step is to adjust find_mir_or_eval_fn and call_extra_fn in compiler/rustc_mir/src/interpret/machine.rs to also pass the rustc_target::spec::abi::Abi of the call to this function. This is the "ABI" that I am talking about in the issue. Then, in a separate PR on the Miri side, we can check that this ABI matches what we are expecting.

I'll get started on those changes, thanks for the help.

unseddd pushed a commit to unseddd/rust that referenced this issue Jan 10, 2021
Add ABI argument for called function in `find_mir_or_eval_fn` and
`call_extra_fn`. Useful for comparing with expected ABI in interpreters.

Related to [miri/1631](rust-lang/miri#1631)
JohnTitor added a commit to JohnTitor/rust that referenced this issue Jan 11, 2021
Add ABI argument to `find_mir_or_eval_fn`

Add ABI argument for called function in `find_mir_or_eval_fn` and
`call_extra_fn`. Useful for comparing with expected ABI in interpreters.

Related to [miri/1631](rust-lang/miri#1631)

r? `@RalfJung`
unseddd pushed a commit to unseddd/miri that referenced this issue Jan 11, 2021
unseddd pushed a commit to unseddd/miri that referenced this issue Jan 11, 2021
unseddd pushed a commit to unseddd/miri that referenced this issue Jan 20, 2021
unseddd pushed a commit to unseddd/miri that referenced this issue Jan 20, 2021
@bors bors closed this as completed in b38dc83 Jan 29, 2021
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-enhancement Category: a PR with an enhancement or an issue tracking an accepted enhancement 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.

2 participants