
WebAssembly on the Server: How System Calls Work - syrusakbary
https://christine.website/talks/webassembly-on-the-server-system-calls-2019-05-31
======
jasonzemos
I have been genuinely intrigued by WASM and have hacked on my own VM in spare
time. One thing that disappoints me is the arbitrary invention of a new binary
format for no apparent reason solving no apparent problems.

It would be better to use CBOR, or at least ELF. The former, especially, is
not too far from WASM's format (both favor compact integer representation),
and bears semblance to JSON which bears semblance to JS which bears semblance
to WASM. It only makes too much sense. But WASM didn't take that direction, so
we don't benefit from a highly extensible, simple and elegant format with
widespread support.

I hope WASM fixes this soon.

~~~
monocasa
I'm not sure ELF makes sense. ELF is all about the representation verbatim in
memory, but at least for the executable segments, that's heavily abstracted
for WASM. And describing alternate address spaces is always a hack in ELF,
just see the craziness in AVR ELFs for an example.

------
xena
Hey! Author of the talk here. Feel free to ask me anything.

~~~
tntn
How does this do anything to alleviate spectre and friends? Software isolation
doesn't work
([https://arxiv.org/abs/1902.05178](https://arxiv.org/abs/1902.05178)), so the
only protection you get is from process isolation, and I assume this doesn't
change the OS mechanisms to enforce that.

~~~
zackbloom
Another method is to limit access to timing mechanisms:
[https://www.infoq.com/presentations/cloudflare-v8](https://www.infoq.com/presentations/cloudflare-v8)

~~~
tntn
To which the V8 developers say:

> We might consider adjusting the precision of timers or removing them
> altogether as an attempt cripple the program’s ability to read timing side-
> channels.

> Unfortunately we now know that this mitigation is not comprehensive.
> Previous research [30] has shown three problems with timer mitigations: (1)
> certain techniques to reduce timer resolution are vulnerable to resolution
> recovery, (2) timers are more pervasive than previously thought and (3) a
> high resolution timer can be constructed from concurrent shared memory. The
> Amplification Lemma from Section 2.4 is the final nail in this coffin, as it
> shows (4) gadgets themselves can be amplified to increase the timing
> differences to arbitrary levels.

~~~
xena
I have been looking at doing things like arbitrarily limiting the WebAssembly
execution engine to only run an instruction per microsecond. This would then
make full execution speed something programs have to be configured to do
rather than something they get by default. I still don't know though, this
stuff gets tricky.

I think the ultimate goal for my implementation of this stuff is to remove
anything higher than seconds resolution of time unless the program actually
demonstrates a need for it. I'd like to have javascript and the browser
processes be in separate machine processes, with javascript artificially only
allowed to use 10% of the CPU time at max. Honestly I think that letting
everything run at full speed on the CPU is probably a mistake.

~~~
lioeters
> remove anything higher than seconds resolution of time unless the program
> actually demonstrates a need for it

As someone working with Web Audio, I wonder if it's even possible to tell if a
program "legitimately" needs milli/microseconds timing precision? Typically
it'd be running on its own worker/audiolet(?) thread, but I imagine it could
be exploited for some nefarious purpose.

Edit: I realized the talk is about WASM on the server, but, who knows, maybe
in the future it could also involve audio that needs high-precision timers.

~~~
xena
Yeah, my thought there is make resolution of timers a dependent capability. My
ultimate goal is to let users be able to say "no, $APP doesn't need more than
second resolution of timers", and if the user is wrong the app just has to
deal with it.

~~~
lioeters
That makes sense. In browsers there are already restrictions around
audio/video autoplay, as an example, and an application needs logic around
waiting for user permission. So I can imagine something similar, where the
default timer could be coarse, and high-resolution timing would require
elevated privileges.

Anyway, thank you for the notes/slides about WebAssembly on the server,
fascinating stuff with a bright future!

------
fulafel
The headline "Why" argument is hardware-independence, but aren't nearly all
competitors on the backend just as hardware-independent?

Ruby, Python, JVM languages (Kotlin/Clojure/Java/Scala etc), Node platform
languages (TypeScript, ClojureScript, ES5 etc)... Go comes to mind as the only
exception, delivering native binaries, but it supports cross compilation
really well.

~~~
xena
They compile from source code elegantly, sure. But you don't always have the
source code available. Removing implications of the underlying platform makes
it easier to change out hardware in the future. It's so that once the next
Intel bug comes out, you can just shed Intel CPU's in favor of ARM, RISC-V, or
even big-endian POWER.

Go also doesn't cross compile with cgo that elegantly. Having the platform run
the output of C compilers means that you can remove that from your runtime
assumptions as well.

~~~
tntn
But most of the examples in 'fulafel's comment already don't require
recompiling for a new architecture. Node, ruby, Python, JVM languages... You
just need a runtime for the desired architecture, which is still true for
WASM.

(As a sidenote, POWER has supported either endianness for a while, and
~everyone runs Linux in little-endian mode.)

Given that the point of cgo more or less is to enable calling into C code,
don't you still need to do a lot to make that work in WASM? Like cross-compile
all your C dependencies to WASM, then use cgo to interface between the go
things and the c things within the WASM runtime?

Pretty interesting ideas and I'm interested to see how it plays out, but tbh I
think I'm too old school for all this newfangled stuff and would just use
qemu.

------
gcoda
after tying wasm in cloudflare workers i started experimenting with isolated-
vm and v8env from superfly(fly.io)

it really feels like future of lambda\cloud functions

------
teabee89
Are you going to implement WASI ?

~~~
xena
It's one of the things I have on the back burner, I personally believe that
WASI doesn't go far enough. WASI limits filesystem calls to the actual
filesystem for one. I think it's better to have a homogeneous view of things
so that the only difference between local and remote resources is what the
platform does.

~~~
sunfish
WASI is in very early stage right now. We already have a start of a proposal
to unify reading/writing from file and network streams. Unifying filesystem
paths with URLs is something that's certainly in scope beyond that.

~~~
xena
How can I get involved? I don't have any major users behind what I'm doing,
but I would like to help make future standards more generic.

~~~
sunfish
The easiest way to get started is to file an issue in the issue tracker at
[https://github.com/WebAssembly/WASI/issues](https://github.com/WebAssembly/WASI/issues)
and we can start discussing it!

------
yjftsjthsd-h
... We've really reinvented the JVM. Not sure that's bad; hope we can do
better this time.

~~~
jameskilton
I like to think of it more that Javascript/WebASM will finally accomplish what
Java spent decades trying to do: be the completely ubiquitous hardware-
independent code platform.

Javascript has truly become the "Write Once, Run Anywhere" language.

[https://www.destroyallsoftware.com/talks/the-birth-and-
death...](https://www.destroyallsoftware.com/talks/the-birth-and-death-of-
javascript) (2014)

~~~
Negitivefrags
Spectre came along and ruined the awesome conclusion of that talk.

The idea was that the cost of using WASM would be entirely offset by the
speedup of removing the cost of hardware memory protection. We could do that
if everything ran in one big VM because the VM would enforce the memory
protection.

Unfortunately, now we can't rely on a VM for memory protection anymore. We
have to assume that any code running in the same address space can access any
memory in the same address space.

So we need the hardware memory protection after all. You can say goodbye to
your WASM-only future.

~~~
colordrops
I assume that new chips will address this vulnerability, correct? Couldn't the
VM detect whether the hardware is secure and decide whether to use hardware
memory protection or not?

~~~
Negitivefrags
At this point it seems practically impossible to deal with completely.

V8 at least have given up on the concept of trying to protect memory within
the same address space.

[https://v8.dev/blog/spectre](https://v8.dev/blog/spectre)

------
draw_down
> This also removes the OS from the equation for most compute tasks.

What does this mean, removing the OS from the equation?

~~~
xena
I vouched for this comment because I didn't go into detail much in the talk.
The main idea is to remove a lot of the kernel and related overhead from
application code, kind of like an exokernel. I am working on using seL4 as a
base for an OS that only runs tasks in WebAssembly. Having things implemented
such that the OS is not a fundamental linking requirement means that I can
easily port applications to the browser. I don't have a working sample at the
moment though, I somehow broke my last ones and haven't had time to fix them
yet.

