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

Too many syscalls in wasi? #87

Closed
eugene2k opened this issue Mar 30, 2019 · 6 comments
Closed

Too many syscalls in wasi? #87

eugene2k opened this issue Mar 30, 2019 · 6 comments
Labels
wasi:api Issues pertaining to the WASI API, not necessarily specific to Wasmtime.

Comments

@eugene2k
Copy link

I'm a big fan of Plan9 and its short list of system calls. Is there any reason why wasi has more system calls than Plan9? It seems redundant to have system calls for things that could be made available through the virtual filesystem, such as environment variables and rng as well as syscalls like sock_send and sock_recv that basically duplicate write and read

@sunfishcode sunfishcode added the wasi:api Issues pertaining to the WASI API, not necessarily specific to Wasmtime. label Mar 30, 2019
@sunfishcode
Copy link
Member

I agree about sock_send/sock_recv vs fd_write/fd_read 😄. As it turns out, I'm currently working on a plan to unify them (brief mention here). There are some subtle issues involved, such as the handling of zero-length datagrams in read, so I'm proceeding carefully, but I believe it's doable.

Concerning "everything is a file" more broadly, there are two sides to it, which in WASI terms translate to: "should every capability be initiated through path_open?" and "should every capability be accessed through fd_read/fd_write?". I myself don't presently have an opinion about this, but I can provide some current thoughts.

Should every capability be initiated through path_open?

One issue is that WASI's capability system means that it has no global namespace. /proc/self/cmdline doesn't easily translate because there are no absolute paths. We could conceivably add a preopened capability representing a /proc-like directory, although depending on what we'll eventually want to put in that directory, it may be better to add preopened capabilities for the individual things inside it instead.

Another is that file descriptors are a limited resource. Operating systems have been moving away from /dev/random and /dev/urandom for obtaining random bytes, and toward dedicated system calls, since opening device files requires obtaining file descriptors, and an attacker can, in some situations, cause applications to exhaust the number of available file descriptors, causing a subsequent open to fail, making random numbers unavailable in situations where they otherwise would be available. We could conceivably add randomness a preopened capability though.

We've also heard feedback from others that want to move all filesystem path handling out of Core, because they otherwise have no use for a filesystem concept.

Should every capability be accessed through fd_read/fd_write?

For things which are naturally byte streams, I agree that this makes sense. As I mentioned above I'd like to merge sock_recv/sock_send with fd_read/fd_write.

Should random_get be fd_read? This may make sense, but there are a few things we'd need to figure out first. First, it would probably want randomness to be a preopened capability, for the reasons discussed above. But if we make it a preopened capability, and random_get gets replaced by fd_read, then there's no distinct random_get import, or anything else which statically indicates that a wasm module actually needs randomness. And that's unfortunate, because it's useful to be able to inspect a wasm module and determine whether it needs randomness or not.

A possible path forward for randomness is to introduce the idea of a "WASI manifest", which is something I have some ideas about, but haven't yet had time to fully design. A WASI manifest would be something that could be embedded within a wasm module, either in a custom section, or via specially-named imports, that would effectively request certain preopened file descriptors. If we had that, then we could say that applications only get a randomness capability if they explicitly request it. And then it might make sense to replace random_get with fd_read.

More broadly, a property of WASI that some people find useful is that static imports (and the manifest, when we have such a thing) of a module can be thought of as representing its static capabilities. This concern tends to favor creating more, fine-grained system calls, rather than fewer more generic ones. That said, this is just one consideration among many, and not always the most important one.

One other consideration is typed interfaces. random_get is relatively simple because it does just return a sequence of bytes. For APIs that consume or return typed data, a dedicated system call can be preferable to serializing data into bytes, whether it's text or binary, because dedicated system calls can have a signature which is statically type-checked, eliminating a class of possible runtime failures.

@eugene2k
Copy link
Author

eugene2k commented Apr 1, 2019

We've also heard feedback from others that want to move all filesystem path handling out of Core, because they otherwise have no use for a filesystem concept.

I've noticed in a different thread @npmccallum requested more of the socket interface to be exposed as system calls, so the runtime they are working on might not need a path interface not because they only need file descriptors, but because the applications they foresee running on it don't need to open files or directories on the host system. Making access to the network available through path may affect @npmccallum's requirements.

A more elegant approach, I think, is to let each wasi application have a root namespace through which services (that use standardized names) would be made available to it and to embed a manifest that would indicate to the runtime which services the application expects. I don't know how many hoops the runtime would need to jump to do this, however, and if it's worth it in the end, unfortunately.

@npmccallum
Copy link
Member

@eugene2k If you look at #74 , my preference is actually to have a more modular approach.

One alternative could be to encapsulate filesystem (including read()/write()) into one module and sockets (including recv()/send()) into another. This allows a clear conceptual distinction while also maintaining compatibility with existing applications and libraries (that might be shallow-ported to WASM).

@camshaft
Copy link

camshaft commented Apr 1, 2019

I tried experimenting with the "everything is a file" model in my ABI designs and ended up switching to separate wasm modules for each concern. This makes statically analyzing the syscall requirements of a wasm binary very straightforward. With a file-based interface it makes syscall resolution a runtime error. This can be solved with additional tooling and custom sections but it seems to be redoing what the wasm module system already has in place.

@eugene2k
Copy link
Author

eugene2k commented Apr 1, 2019

After a bit of deliberation, I have to agree: the modular wasi approach seems like the way to go.

My initial concern was that wasi will end up growing more and more because the more people use wasi the more use cases they will have and the more interfaces they will want standardized, until, eventually, wasi ends up with a .NET/CLR of its own. My reasoning was that if wasi offered these interfaces through an IPC mechanism, the runtime wouldn't have to get bloated. However, if the host doesn't follow "everything is a file" philosophy, the runtime will get bloated anyway and, sadly, the world doesn't follow this philosophy. Thanks for your time and answers, everyone!

@sunfishcode
Copy link
Member

Sounds good.

One additional thing I want to mention here is that WASI APIs don't need to be implemented in the wasm runtime. They're just wasm imports, and so could just as well be implemented by other regular wasm modules. This is actually another reason why modularization as @npmccallum suggests will be useful.

Closing this issue as the original question is answered, but feel free to open new issues if there are any followup questions or ideas!

grishasobol pushed a commit to grishasobol/wasmtime that referenced this issue Nov 29, 2021
* Preserve signalling bit in NaNs

* Fix warnings
howjmay pushed a commit to howjmay/wasmtime that referenced this issue Jan 24, 2022
`readlink -f` is not existing in macOS, so this commit uses another way
to get an absolute path for wasmtime build directory.

Fixes bytecodealliance#87
pchickey added a commit to pchickey/wasmtime that referenced this issue May 12, 2023
…ode/update-wasi

Update wasi-filesystem, wasi-clocks, wasi-io, and wasi-poll.
pchickey added a commit to pchickey/wasmtime that referenced this issue May 16, 2023
…ode/update-wasi

Update wasi-filesystem, wasi-clocks, wasi-io, and wasi-poll.
mooori pushed a commit to mooori/wasmtime that referenced this issue Dec 20, 2023
Rename test-zk-64.sh -> test-zkasm.sh
dhil added a commit to dhil/wasmtime that referenced this issue Jan 30, 2024
Notable changes: 
* Use recent wasm(fx)-tools release.
* Rename `WasmType` to `WasmValType`.

Also, this patch disables CI checks for unsupported platforms.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
wasi:api Issues pertaining to the WASI API, not necessarily specific to Wasmtime.
Projects
None yet
Development

No branches or pull requests

4 participants