miri icon indicating copy to clipboard operation
miri copied to clipboard

Improve handling of failed operations in isolation mode

Open Aaron1011 opened this issue 6 years ago • 21 comments

Currently, we abort program execution when we try to access the external environment in isolation mode. However, libstd currently calls getcwd when printing out a panic backtrace. To ensure that panicking works in isolation mode, we've disabled the call to getcwd when libstd has cfg(miri) enabled.

Eventually, it would be good to remove this hack, and start returning proper error codes from disabled functions, rather than aborting the process.

See https://github.com/rust-lang/rust/pull/60026#discussion_r342257352 for more discussion

Aaron1011 avatar Nov 05 '19 04:11 Aaron1011

@oli-obk I'd be interested in your opinion here: right now we abort execution on shims that are unsupported due to isolation; if we instead continue execution pretending the function errored that might be unexpected. Though OTOH this is what "normal" sandboxes do so I think it's actually expected. We could emit a warning the first time this happens -- this might be a good test project for https://github.com/rust-lang/miri/issues/797.

RalfJung avatar Nov 05 '19 09:11 RalfJung

hmm... we do this already for all the pthread code, so we do have precedent. I'm fine with it and I don't think we'd need a warning. I would expect a sandboxed open call to error after all.

oli-obk avatar Nov 05 '19 09:11 oli-obk

If we decide to make disabled functions return an error code, I think we should have a command-line flag to opt in to the old behavior. There should be a way of running Miri such that either:

  1. The program output is identical to the output when run normally (i.e. compiled by rustc and executed), or:
  2. We terminate the program with an explicit Miri error.

Aaron1011 avatar Nov 05 '19 21:11 Aaron1011

While I personally don't see a reason for such a flag, I won't block it if there is strong desire for it.

We've been doing quite well with just having unsupported functions return even success return values and do nothing. Going a step further and reporting error return values for unsupported functions where the caller has a fallback or otherwise useful code path seems totally alright to me.

oli-obk avatar Nov 06 '19 07:11 oli-obk

While I personally don't see a reason for such a flag, I won't block it if there is strong desire for it.

Same.

The program output is identical to the output when run normally (i.e. compiled by rustc and executed)

Note that we cannot guarantee this due to things like pointer-integer casts, or libc functions that return the stack size (we just return some constant, 16k if I remember correctly). And we already don't try to be faithful for most things "implemented" in foreign_items.rs, we just make these good enough such that things work.

RalfJung avatar Nov 06 '19 10:11 RalfJung

Here's another example where it would be good if isolated operations returned failure instead of aborting execution: https://github.com/seanmonstar/num_cpus/pull/96 makes num_cpus open a file (rejected with isolation) but falls back to another way of determining the CPU count (which works in isolation).

RalfJung avatar Sep 18 '20 10:09 RalfJung

This would be great to have for my usecase. I'm wanting to add miri support to https://github.com/camshaft/bolero and wanted to read the fuzz corpus from the filesystem, if possible, otherwise fall back to only generating some random tests cases with a warning saying to disable isolation if desired.

camshaft avatar Oct 20 '20 20:10 camshaft

I'm going to try working on this.

camelid avatar Oct 24 '20 19:10 camelid

@camelid that's great. :-)

RalfJung avatar Oct 24 '20 23:10 RalfJung

@camelid Are you still working on this or can I take a shot at this?

henryboisdequin avatar Mar 03 '21 01:03 henryboisdequin

@henryboisdequin I never ended up getting to this, so you can try!

camelid avatar Mar 03 '21 18:03 camelid

Hi @RalfJung , I opened a PR fixing get and set cwd ops. Let me know what you think. Also, this is my first PR in rustc related packages. If you find something missing from the usual workflow, please let me know 🙂

atsmtat avatar May 14 '21 07:05 atsmtat

With https://github.com/rust-lang/miri/pull/1797 we now support returning EPERM for some operations when isolation is enabled, instead of aborting execution. What is left to do is do this for as many operations as possible. :) It might be good to assemble a list.

RalfJung avatar Jun 09 '21 19:06 RalfJung

I guess most of the fs operations can return EPERM.

atsmtat avatar Jun 11 '21 04:06 atsmtat

Yes, I think that would make a lot of sense.

RalfJung avatar Jun 11 '21 07:06 RalfJung

Yes, I think that would make a lot of sense.

#1838 takes care of fs shims.

atsmtat avatar Jun 16 '21 00:06 atsmtat

With https://github.com/rust-lang/miri/pull/1838 landing soon, the remaining uses of check_no_isolation seem to be

  • the shims in time.rs
  • pthread_cond_timedwait
  • FUTEX syscall with a timeout

RalfJung avatar Jul 25 '21 09:07 RalfJung

I got the above error when trying to read the input of my fuzzer from a file. I think isolation is disabled using MIRIFLAGS, and the fs.rs file seems up to date. Can I still read a file in my main.rs?

  • command ./x.py run miri --args ../../hello_world/src/main.rs

  • Error message image

  • main.rs

  • git log library/std/src/sys/unix/fs.rs (It seems up to date.)

  • MIRIFLAGS

yunji-yunji avatar Jan 09 '23 23:01 yunji-yunji

Try adding -Zmiri-disable-isolation to your args.

The -Z flags for Miri just like the -Z and -C flags for rustc are command-line arguments (Miri is basically a hacked-up rustc). MIRIFLAGS lets you pass those arguments through cargo-miri just like RUSTFLAGS lets you pass them through cargo. You aren't going through Cargo so nothing is looking at that environment variable.

saethlin avatar Jan 09 '23 23:01 saethlin

Thank you so much! The problem is solved with your support.

yunji-yunji avatar Jan 10 '23 00:01 yunji-yunji

In the future, please open a new issue unless you are sure this is the same problem as an existing one. In this case your program had nothing to do with what we are discussing in this issue.

RalfJung avatar Jan 10 '23 07:01 RalfJung