bytecodealliance / wasmtime

A fast and secure runtime for WebAssembly
https://wasmtime.dev/
Apache License 2.0
15.1k stars 1.26k forks source link

Order of preopened directories matters #111

Open MarkMcCaskey opened 5 years ago

MarkMcCaskey commented 5 years ago

Hello, while investigating wasmerio/wasmer#372 I tried to reproduce what the submitter said and found:

wasmtime --dir=../ --dir=./ ~/etc/hello-wasi/copy.wasm ../LICENSE ./LICENSE
error opening input ../LICENSE: Capabilities insufficient

fails.

However, changing the order of the --dir flags to:

wasmtime --dir=./ --dir=../ ~/etc/hello-wasi/copy.wasm ../LICENSE ./LICENSE

works.

The way I'm approaching this so far for Wasmer is to canonicalize all the preopen dir paths, sort them lexicographically (ensuring parent directories come before child directories (assuming symlinks have been resolved away(1) (which is WIP currently))), then each path is reduced until it's empty or it matches a directory we've already seen and then they're connected (creating intermediate directory entries as necessary).

I'm not entirely clear on the desired behavior, but this seems correct from what I've read so far.

I'd be curious to hear your thoughts on this!

(1): which seems to be the desired behavior anyways, pre-opened FDs seem like they should be snapshotted at the moment of FS instantiation rather than relying on symlinks that could change during execution

MarkMcCaskey commented 5 years ago

One more note: it seems that Wasmtime does not support mixing relative paths with absolute paths.

If you pass --dir=. as a preopened dir, and you pass the absolute path to the program or vice versa (with --dir=<absolute path> and the argument being relative), it fails.

This seems like a tricky case to handle with disjoint directories if the intent is to hide filesystem details from the running program (that is, by connecting the lowest common ancestor in every group together, it may expose the directory structure of the host)

It seems like further specification here would be a good next step!

MarkMcCaskey commented 5 years ago

Upon further inspection it might be an issue with the libc calling in to WASI. It seems that there's an implicit assumption that fd 3 is the current directory, which explains the behavior we see with wasmtime.

I'll have to work around this because my solution sorts the passed in directories to avoid more expensive checks when connecting the pre-opened directories in to a tree.

edit: actually, that does not seem to be the case 🤔

sunfishcode commented 5 years ago

If it's a problem in WASI libc, would you mind taking a look there for the underlying bug, rather than working around it? It'd be really great for more folks to get involved on the libc side :-).

MarkMcCaskey commented 5 years ago

Sure! I'd love to help out if I can; I spent some time grepping through the wasi-sysroot before and wasn't able to identify the location, but I'll give it another go.

I now believe my previous assumption to be incorrect, it seems to be passing in the most senior directory (but I haven't fully verified this yet)