miri icon indicating copy to clipboard operation
miri copied to clipboard

Miri should warn or error when accessing file at `/proc/self/fd/X`

Open stevenengler opened this issue 11 months ago • 8 comments

If your program attempts to open and read from a file in /proc/self/fd/, then cargo miri run (with isolation disabled) hangs.

use std::os::fd::AsRawFd;
use std::fs::File;
use std::io::{Read, Seek, Write};

fn main() {
    let mut file = tempfile::tempfile().unwrap();
    file.write_all(b"hello").unwrap();
    file.rewind().unwrap();

    // opening and reading from /proc cause miri to become stuck
    let mut new_file = File::open(format!("/proc/self/fd/{}", file.as_raw_fd())).unwrap();
    //let mut new_file = file;

    let mut buf = Vec::new();
    new_file.read_to_end(&mut buf).unwrap();
    println!("{buf:?}");
}
$ cargo --version
cargo 1.85.0-nightly (769f622e1 2024-12-14)
$ MIRIFLAGS=-Zmiri-disable-isolation cargo miri run
    Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.01s
     Running `/home/steve/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/bin/cargo-miri runner target/miri/x86_64-unknown-linux-gnu/debug/miri-test`

This is also reproducible at: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2021&gist=d05155bb1f3c7aff5e705b0e2904d21c

I'm guessing that miri virtualizes filesystem operations in some way, and maybe files in /proc just aren't supported?

stevenengler avatar Dec 16 '24 00:12 stevenengler

Miri virtualizes file descriptors, so the FD number you see may have nothing to do with the FD numbers in /proc.

So I am inclined to close this as not-a-bug; we don't support bypassing Miri and directly accessing the underlying OS. You will run into similar issues trying to access /proc/self/mem. Maybe we should print a warning or even halt execution when we detect a path in /proc, but that would just be a best-effort check.

RalfJung avatar Dec 16 '24 07:12 RalfJung

Is there a general guideline about what Linux features Miri emulates (or wants to emulate) and which ones it doesn't? For example Miri is emulating Linux file descriptor handles (and I'm guessing some syscalls), but is not emulating /proc.

I think it sounds fine to not support /proc, but it would be nice if a warning was shown when possible. Running tests in miri can already take ~20 minutes for some projects, and having a correct test which can block indefinitely under miri can be a bit difficult to debug.

On the other hand, I believe that some glibc functions read from files in /proc, so it might be noisy showing warnings for all file accesses in /proc. Maybe the filter could be a bit more specific than just /proc.

stevenengler avatar Dec 16 '24 13:12 stevenengler

On the other hand, I believe that some glibc functions read from files in /proc, so it might be noisy showing warnings for all file accesses in /proc. Maybe the filter could be a bit more specific than just /proc.

Miri doesn't run glibc. Instead it emulates the api surface exposed by glibc, so any accesses to /proc that glibc would do are irrelevant.

bjorn3 avatar Dec 16 '24 14:12 bjorn3

Is there a general guideline about what Linux features Miri emulates (or wants to emulate) and which ones it doesn't?

Generally we throw an error when you hit something we can't emulate. But we didn't consider the interactions with /proc...

RalfJung avatar Dec 16 '24 15:12 RalfJung

That should be fairly easy to do: in the code for open, check for some bad paths. It won't catch everything but we can catch the obvious ones.

RalfJung avatar Dec 16 '24 15:12 RalfJung

Actually should reading from symlink works in miri? I realised most of the stuff in proc/self/fd seems to be symlink.

If it doesn't, maybe we can throw an error when it tries to read from symlink.

I slightly looked into this, this seems to be the place where miri hangs: https://github.com/rust-lang/miri/blob/b9a24fc85858c662c2aeea67655464bce386d1f7/src/shims/unix/fs.rs#L33-L49

and self.file happens to be a symlink, that's why I have the question above.

tiif avatar Dec 16 '24 15:12 tiif

Symlinks are fine. It will just read through them transparently.

oli-obk avatar Dec 16 '24 16:12 oli-obk

EDIT:

oh this should be a symlink, is_symlink seems to be always false when retrieving from File::metadata. But since symlinks are fine, this is not relevant now.

tiif avatar Dec 16 '24 16:12 tiif