Can WebAssembly do IO? - io

I've been studying WebAssembly, and I have a basic (naive, probably) question. How does IO fit into the WebAssembly/host VM picture? There seem to be no WASM constructs (e.g., opcodes) for handling simple IO operations like printing something to the screen. In implementations of WASM, is there always expected to be a higher level language, like Javascript, mediating between WASM and the host VM to take care IO and such?

You are correct, WebAssembly itself has no IO capabilities. It only has access to linear memory and functions that are imported / exported by the host environment (JavaScript when hosted in the browser). It is these imported functions that allow WebAssembly modules to perform IO operations indirectly. This is by design, WebAssembly will never gain instructions that permit direct IO. However, with the host bindings proposal the mechanics of indirect IO API access will become simpler in the future.

Related

Node WASI vs spawning a child process

In the NodeJS docs it states the following:
The WASI API provides an implementation of the WebAssembly System Interface specification. WASI gives sandboxed WebAssembly applications access to the underlying operating system via a collection of POSIX-like functions.
My question is:
What is the biggest benefit of using the WASI API over, say, spawing some other child process or similar methods of running non-nodejs code?
I would have to assume it's faster than spawning a child process, or using some C code with bindings due to the native-api.
Maybe I'm simply misunderstanding the entire idea behind WASI, which is plausable, given that part of what makes WASM so amazing is the ability to use a server-side, full blown programming language on the web (mostly), like all the crazy tools we've seen with Go/Rust.
Is this more so for the benefit of running WASM in node, natively, and again, if so, what are the benefits compared to running child processes?
I ended up getting my answer from a post here that was removed.
In really high-level terms, WASI is simply an (systems) interface for WASM.
I ended up finding this short 'article', if you will, super helpful too!
Just as WebAssembly is an assembly language for a conceptual machine, WebAssembly needs a system interface for a conceptual operating system, not any single operating system. This way, it can be run across all different OSs.
This is what WASI is — a system interface for the WebAssembly platform.

What are the security risks associated with WASM?

Using Deno you can execute WASM on a server. WASM is sandboxed for the user's safety. From my understanding, WASM code cannot do HTTP requests or modify the DOM.
Is safety guaranteed server side too? I'm looking to run arbitrary Python code from user input on servers using pyodide but was concerned that I have missed some important security flaw.
Using Deno you can run WebAssembly modules on a server because the Deno wasi module provides an implementation of WASI, the WebAssembly system interface. Using Deno is just one way of running wasm modules on a server. You could choose between many other implementations of WASI, like the wasi module in Node.js, wasmtime, lucet, wasmer, etc.
Code [running] outside of a browser needs a way to talk to the system — a system interface.
As for your security concerns, keep in mind that your WebAssembly code runs in a sandboxed environment. It's not your host system that executes directly the code in your wasm module. It's the wasm runtime — that implements the WASI interface — that runs it. And as far as I know the only way for your code to produce side effects (e.g. perform a HTTP call, access files) is to go through appropriate APIs defined by WASI.

Library function that implements TPM2_MakeCredential

For remote attestation using a TPM, on the server-side I need the TPM2_MakeCredential function. Note that this function is implemented in the TPM but it is a bit off because it doesn't depend on any TPM state, it's completely stateless (unlike the TPM2_ActivateCredential function - to be run on the client-side - which critically depends on TPM keys). According to the documentation, it's provided as a convenience. That's OK but the problem is the server doesn't have (nor requires) a TPM. But I still want to use the TPM2_MakeCredential function.
Unfortunately, I haven't been able to find a library implementation of this function. There's a full-blown TPM2.0 emulator provided by Microsoft that the TPM.MSR libraries can interface to. This works, but it requires starting and managing the simulator process which sets up sockets etc. which I would rather avoid. I am wondering if there's a pure C/C++/C# implementation provided as a library? I have been working with various solutions but the function is not trivial to re-implement, and it's also not trivial to extract from the simulator.
It turns out the TPM.MSR library itself exposes this functionality (implemented purely in the library itself, not relying on a TPM) via the CreateActivationCredentials() function on TpmPublic.

How to use the epoll/kqueue enabled version of GHC/Haskell for network connections?

There is a lot of old information on the net regarding an epoll/kqueue enabled GHC. For example, the code on the Simple Servers wiki page doesn't compile anymore.
Could someone provide a basic example of how to use this feature with a modern GHC version to build, e.g. a TCP server that just responds with "Hello" on connect?
GHC's IO manager uses epoll/kqueue under the hood without any special programmer effort. Just write the naive threaded program -- that puts each concurrent blocking IO call in a separate thread -- and GHC will make sure it works out the way you want it to.

Haskell remote file IO library (like kio)?

Is there a remote file IO library for Haskell? In KDE, for example, the kio subsystem provides a URL-style interface for accessing files, so most KDE applications could open a remote file via SFTP as easily as a local one. Thanks!
There's nothing that provides a unified file-esque interface based on URLs, although you could technically hack one up with GHC's support for defining custom types of Handles (as used in knob).
But you can process streaming data from various sources in a consistent way with iteratee-style packages like conduit and enumerator. For instance, there are conduit interfaces to files, HTTP (IMO the best HTTP interface for Haskell even when not using conduits directly), FTP, raw network sockets, and so on. IMO, these are better-suited to processing data from multiple sources than a Handle-style file IO solution; things like seeking make no sense in the context of a sequential network stream.
Of course, these don't solve the problem of providing a consistent user interface to all of these; some additional work will be required. The simplest route is probably to process URIs from the standard network package, mapping them to Sources (or equivalent) appropriately. For things like files and HTTP, it should be as simple as processing the protocol and passing the rest of the URI as a string to the appropriate library.
In summary: No, but all the necessary pieces to processing local and remote data in a unified manner like this are present, and the user interface part shouldn't be overly difficult to write if you need it.

Resources