Why WebAssembly is innovative even outside the browser
tetrate.io
tetrate.io
Outside of the browser you at least have a chance of interacting with the underlying APIs in a performant enough manner to enable a wide variety of applications.
VMs existed at the time. Java was one of them, probably the most prolific of them all, and certainly had a standardized system interface.
Further WASI is a nightmare. Most projects I've personally seen disregard it completely.
Java is not a target for C++ code compiled via Clang/LLVM. Wasm is.
Expert advice done cheap.
Experts happen to know what is actually possible.
Are you going to quip that Burroughs did all this already as well?
Not Burroughs, but AS/400 TIMI (now IBM i), Microsoft MSIL, TenDRA compiler suite, if you want to talk about C++ aware bytecodes.
This still doesn't make sense to me. Cgroups are a Linux kernel feature, WASM is a VM. They do not have the same (or similar) scope of features.
You lose hypervisor speedups, kernel feature parity, introduce a whole new surface area for security exploits since you're throwing away the entirety of linux's history, and what's more, it was still possible with the JVM.
Wasm is two things, CFI and capabilities, everything else is an implementation detail.
Your definition of a container is too limited in scope. You don't understand what I or Solomon Hykes are saying wrt Wasm and isolation. I tried to help.
What's important to understand is, Docker exists because Oracle made Java too scary to touch, thanks to big ongoing lawsuits against Google, and demanding royalties just for running a JVM server. Also the JVM is fast, but it's slow enough that it's within striking distance of a full cgroup, running a full Linux kernel.
So it made sense to just create Docker, and allow people to abandon things like jruby, and just run normal Ruby in a Docker container.
WASM is what people would have wanted when Docker was created. A bytecode format like JVM, but faster, and not encumbered by big bad Oracle's coffer-rattling.
So in other words, if WASM had existed when Docker was created, people would have just recompiled their apps for WASM bytecode, and would have also recompiled things like MongoDB and MariaDB for WASM. Things like network syscalls would be replaced by traps to the webassembly runtime.
Well, it is with GraalVM with proper cross-language inlining.
This means it's in theory possible to run the same code on an embedded hardware platform, a desktop app or in the browser.
And while I'm sure there's "serious" business uses for that capability :) I'm most interested in what it enables in terms of user customisation/modding of games.
Which was my main motivation for creating a Wasmtime WASM runtime add-on for the Godot game engine: https://gitlab.com/RancidBacon/godot-wasm-engine
And also designing the "WebAssembly Calling Card" specification as a way of demonstrating how the same code could produce graphical output that is then used in 2D or 3D environments: https://wacc.rancidbacon.com
Do you have anywhere that interested people can read more about the project/progress?
Maybe want to talk to the Java guys, and ask them why this doesn't work out in practice? ;-)
Just having a common byte-code interpreter isn't enough for portability of applications.
What's your theory on why it doesn't/didn't work out in practice in Java's case?
There is one key difference in our respective wording which might point to a difference of perspective:
I referred to "the same code" and you referred to "portability of applications".
I don't really foresee "portability of applications" so much as "portability of modules/functions" (or "portability of libraries/plugins", I guess).
In which case, you're still correct when you say a common byte-code interpreter isn't enough--there also needs to be common specification/API for specific domains. (Which is where WASI is aiming for in terms of general system-level APIs; interface types are aiming for lower levels; and, other higher level domain/application-specific solutions may be developed for other situations.)
There surely is, Java, .NET were there first.
If we leave the browser out, then there are plenty of examples since the early days of 1960's.
By default, WASM is pure computing. It can't interact with the outside world. You need to allow WASM to talk to the outside world explicitly.
You have native performance. It's fast.
It's platform-independent, and multiple languages can compile to WASM.
The properties lead to some useful applications.
Serverless, FaaS. If you use WASM for Serverless you get very fast execution + cold starts. Cloudflare Workers can do 200ms cold starts and 20ms a request. Fastly Cloud@Edge not being a Chrome browser, but instead, its own runtime can do better and serve requests in 10ms. The low overhead and secure sandboxing means you can bin-pack these at a massive scale and call them with little overhead. It's much more efficient than Lambda etc. Cloudflare and Fastly as edge CDN providers allow you to deploy fast apps, globally distributed by default, piggyback off their existing caching functionality with no need for API gateways/complex plumbing etc. Fastly's C@E is especially interesting. Unfortunately, Fastly have failed to capitalise on it product-wise. As a product, Cloudflare is way ahead. The best tech doesn't win. I'm not disparaging Cloudflare here. I personally use Cloudflare over Fastly because, at this point, Cloudflare are a more complete product/ecosystem with superior pricing model.
For serverless, it's early days but WASM/WASI will probably disrupt the current FaaS providers once the rough edges are worked out. I wish Fastly had a better product/business execution team to realise C@E properly.
Outside of Serverless/FaaS it makes massive sense instead of people deploying full OS's in a Docker image on Kubernetes, instead deploy WASM modules. Wasmcloud (https://wasmcloud.dev/) looks to be one of the first here running an actor system in Kuberenetes where the Actors are WASM apps.
The other place where it has big potential is to be the Electron from hardware devices. Here's a talk for building a WebAssembly runtime for IPlayer https://www.youtube.com/watch?v=28paRXqI-Gk . They essentially made the bulk of the logic/app in Webassembly then created small shims for different devices to load it. Webassembly allowed the hardware providers to offer a portable runtime that can execute 3rd party software in a restricted runtime.
WebAssembly in the browser is the least exciting part about WebAssembly. I'm incredibly excited to see how it is used for Microservices and serverless.
That only applies to MVP 1.0, the long term roadmap hardly makes it any different from the myriad of other bytecode distribution formats.
I think Cloudflare's Workers are a good example of where things might be going with the tech, but there is room for a lot more. I would love to see something like coroutines adopted for WASM that allow for asynchronous WASM computation.
Yes and no.
Some ISAs do have real "co-instructions" that would be executed concurrently to the "main" program, for example Lisp Machines use this approach for executing bounds-checking concurrently, as well as other kinds of validation/assertions (and even had a limited form of hardware time-travel to jump-back to before a co-processor exception occurred).
This approach died out due to the complexity of implementation.
The only innovation is being more marketable.
Java rode that train in the early days of the web with applets. But the user experience wasn't good and there were security holes, and Java support was gradually removed.
A lot of other languages tried this, but didn't get wide adoption.
"Everything Old is New Again: Binary Security of WebAssembly"
https://www.usenix.org/conference/usenixsecurity20/presentat...
Other research papers are bound to appear as the security community finally starts looking into WebAssembly security claims.
Marketing is everything.
It is not duh when WebAssembly advocates use the security sales pitch.
- OS independent
- CPU independent
- Easy target for compilers
- Easily embeddable
- Code cannot modify itself in memory (which makes the point below easier)
- Easy to prove safe from accessing the host (very limited instruction set, can only access a certain address range of memory). It is hard to make a mistake implementing a VM. It's not too complex, and you can make sure every memory load/write instruction emitted is written to target "(BASE_ADDRESS<<32) | x", with x being the pointer as seen from inside the wasm, and BASE_ADDRESS being the upper 32 bits of the 4 GiB aligned range you have of virtual memory for the module
The fact that it is widely implemented by browsers helps prove all these points.
I'm sure the next big fun project for some people is gonna be writing a microkernel that runs wasm binaries in ring 0. It's that safe (of course, spectre might add a bit of overhead to context switching still).
No need to modify the code when data can be corrupted and thus be misused to influence the decisions taken by the code.
Yes, it will be probably a fun project replicating Burroughs architecture in 2021.
By the way, had Chrome the same market share in 2010 that it enjoys today, everyone would be talking how great PNaCL is.
https://leaningtech.com/cheerpj
https://leaningtech.com/cheerpx-for-flash
Enjoy
The fact that Wasm has a binary representation is orthogonal to the design. It has CFI and capabilities. CFI allows it to be compiled down to native code safely and run inside the same address space of the containing process. Capabilities control what gets in or out. You would be well served to ignore the whole bytecode aspect and just accept the Wast.
No, WA has not solved the halting problem and fixed all bugs in sandboxed programs.
Yes, it's important for people developing WA-based systems to acknowledge the above limitations.
You've been brandying about this paper for the last year as if it means something that it doesn't [1-12]. Every time someone actually reads it they come to the same conclusion that this paper says nothing about the WA-host memory barrier -- and "everyone" includes the authors themselves [13]. And every time you respond by moving the goal posts with "but but WA isn't magic security pixie dust that solves all security problems". If I sound annoyed it's because I've been pushing back on your FUD with nary a direct response that acknowledges these limitations to your narrative and I am annoyed. Also, it's been a year now, where are all these papers that break WA that you keep promising? Are you privy to WA-host memory barrier breaking results that have yet to be published (and aren't just repackaged CPU vulnerabilities)? I'm open to evaluating the claim of such a break being found in the future, but there's no evidence for it yet.
[1-12]: https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...
Just marketing, it doesn't matter that the host isn't directly exploited, when it can be affected by the behaviour of internal corrupted datastructurs inside the WASM module, just like an exploited OS process afects the surroundoing environment with its actions.
A security sales pitch used to stagnate the state of RIA during the last 10 years.
As for the papers not being there, I guess it is more fun to try to exploit other stuff than WebAssembly.
Rest assured that you will be notified when they get announced.
Where we disagree is when you refuse to acknowledge that these two isolation systems can have vastly different access. The key thing to observe is that WASM's access is configurable; yes that means it could be up to the same level of access as a process if you're an idiot and give it that, but it could also be much more locked down than a process ever could be and in fact that's the point of using WASM. A process can attack the entire kernel via all syscalls, the entire filesystem, anything accessible over the network, any devices attached to the computer, etc, etc.
If you write a game plugin architecture based on WASM and only give it access to affect entities in your game (and you're careful to treat its output as if it came from a potentially malicious remote server), there's nothing that the WASM plugin can do to break out, it can't attack arbitrary resources on your computer. Configured properly, at best you could compare WASM to a locked down SELinux process, but WASM is so much more portable that it's basically a new category of thing.
Yeah I guess a target with an attack surface that includes every web browser compiled in the last 5 years and ubiquitous cloud infrastructure that terminates half the web's TLS sessions is just too boring and low profile. Sure, that's why nobody's found a vulnerability yet.
> Rest assured that you will be notified when they get announced.
Certainly, I can read the HN front page just as well as anyone. But I suppose that means you don't have anything better either.
(Serious proposal. Please consider adopting this in your own usage, even if informally; think of it as guerilla rebranding.)
Ironically, many of the arguments against the use of JS as bytecode just got transplanted into arguments against WASM, but one common argument against WASM is "why do we need this when we can already compile to javascript?"
[0]https://news.ycombinator.com/item?id=5227274
[1]https://www.hanselman.com/blog/javascript-is-web-assembly-la...
[2]https://news.ycombinator.com/item?id=5762183
[3]https://news.ycombinator.com/item?id=3708919
[4]https://blog.izs.me/2011/09/javascript-is-not-web-assembly/
Serious question.
I read it often, but besides minified JS, most "to js compilers" try to emit readable JS and I didn't have the impression that the goal of bytecode was to be readable.
> The Hermes JavaScript engine statically compiles JS to bytecode. https://github.com/facebook/hermes
Lua pretty much does everything (minus polyglot) that wasm claims to do and has a good dev tooling system. It ll be a lot more enticing, if I could write lambda functions/serverless computing right of the bat with wasm alone.
Java is mentioned, but not the JVM, or .NET (core)?
Therefore this reads once again like an ad…
But that actually fits a scheme: Most things one can read currently about WASM are highly over-promising this technology. It's nowhere close to the established VM Runtimes until now!
Does WASM really need dishonest marketing posts so badly?
Who is actually throwing money after that marketing efforts? Who doesn't like the JVM anymore, and isn't using .NET either?
It sells better when "WebAssembly did it first".
It's much slower than native (you will need a JIT to make it reasonable fast again!), needs a considerably huge runtime with a significant memory overhead compared to native, and a complicated build setup.
Someone will say now: Sandbox.
But sandboxing native code, in a native way (using directly the facilities that the WASM runtime would use) is much simpler, cheaper, and more performant.
And for high-level languages you need anyway all the things that the JVM has build in. Also you get there instrumentation, monitoring, and debugging facilities for "free".
The only valid point of criticism I see here is the complaint about the "build in" OO semantics of the JVM. But that's nothing that couldn't be augmented by some better fitting mechanics for cases where translation to OO is very problematic. (But actually I have a hard time to think of an example for this problem. OO and FP are actually duals¹ ² of each other, and there's not much that's neither OO nor FP).
¹ https://www.cs.uoregon.edu/Reports/DRP-201905-Sullivan.pdf ² https://www.researchgate.net/publication/332248372_Codata_in...
As for the memory overhead, where have you seen that? To my knowledge the most problematic part there is that wasm currently doesn't offer any way to return memory to the OS.
The point of sandboxing is that the space allocated to wasm is well delineated and there should be no way to access the rest of your memory from the inside. For stuff like plugins, that's very valuable compared to just providing a .so with absolutely 0 isolation, in addition to having to compile the .so/.dynlib for your specific OS and architecture beforehand.
Or perhaps something like React Native, with WASM standing in for the JS runtime?
Corruption that can then be used to subvert the behaviour of functions being called.
WebGL additional validation is so good that the only way to work around exploits is to blacklist user's hardware, OS and GPU drivers. Thus rendering those nice 60 FPS scenes into a single digit FPS caused by software emulation.
Security would be so much better if liability was already thing across the industry, and not only on high integrity systems.
There are proofs of concept using shaders for security attacks.
At the (almost) most basic level a chunk of memory can be used as a framebuffer--the host application would read the pixel data which the WASM bytecode wrote and then write it to the host display via OS-level routines.
There are some plans/experiments at making a framebuffer "device" available as part of WASI.
I've written a couple of graphical WASM host applications that aren't browsers (and which don't use memory for pixel data transfer just integer values returned from a function):
The "WebAssembly Calling Card (WACC) Viewer" is implemented via the Godot game engine and an addon that integrates the Wasmtime WASM runtime with the engine: https://wacc.rancidbacon.com
(Also implemented a WACC Viewer in Rust: https://gitlab.com/RancidBacon/rusty-wacc-viewer)
WACC specifies how to transform three integer values (returned from a function in a WASM module) into a coloured triangle in order to render it on screen.
Another "host application" I implemented was a libretro compatible plugin that loads a WASM module and then feeds the module with input from libretro & retrieves framebuffer pixel data (one pixel at a time :D ) via a WASM function call & writes it to the libretro framebuffer for display.
All one would need to do (AFAIK) is ship a client for all major platforms, as is done with Electron (and web browsers themselves, and everything else.)
[0]https://github.com/appcypher/awesome-wasm-runtimes
if so, are there any plans to change that?
More here: https://en.wikipedia.org/wiki/List_of_JVM_languages
It accepts any language that compiles to JVM bytecode. Java is just one of them. Just like an x86 processor accepts any language that compiles to x86 instructions.
Have a look at Project Sulong.
You would compile
LLVM-frontend -> LLVM-IR -> LLVM-WASM-backend -> GraalVM-WASM-frontend -> GraalVM-bytecode-backend
instead of LLVM-frontend -> LLVM-IR -> GraalVM-LLVM-IR-frontend -> GraalVM-bytecode-backend
The additional transformations won't be healthy for the performance of your program, or compile times…https://en.wikipedia.org/wiki/Control-flow_integrity
https://clang.llvm.org/docs/ControlFlowIntegrity.html
It looks like it might be possible, but I really like the security properties of Wasm. It looks like I am moving the goal posts, but I am not, it is the biggest reason to use Wasm, the second one is the capabilities model.
It would be a great undergrad research project to measure the difference in those two compilation chains.
And capabilities are anyway something that belongs into the OS — and than programs need to be written accordingly. The whole point of the capability-security model is that you can't add it after the fact. That's why UNIX isn't, and never will be, a capability secure OS.
But "sanboxing" some process running on a VM is completely independent of that!
WASM won't get you anything beyond a "simple sanbox" ootb. Exactly the same as you have in the other major VM runtimes.
If you want capability-secure Rust, there is much more to that. You have to change a lot of code, and use an alternative std. lib¹. Of course you can't than use any code (or OS functionality) if it isn't also capability-secure. Otherwise the model breaks.
To be capability-secure you have actually to rewrite the world…
LLVM IR is C/C++, if you are embedding that into your Graal program w/o the same level of CFI that Wasm has, you can definitely crash your Graal program. We were literally talking about LLVM IR and you switched back to bytecode. JVM bytecode is safe, LLVM IR is not.
> WASM won't get you anything beyond a "simple sanbox" ootb.
Not true, the core tenet of Wasm is based around CFI.
https://webassembly.org/docs/security/
Wasm has capabilities everywhere, it doesn't need an OS to provide this.
Graal is so much more than JVM. The way it integrates LLVM IR absolutely matters wrt safety. If you include Wasm into a native code it doesn't reduce any of its security properties. You include LLVM IR into a JVM program and it will reduce your security properties. While LLVM has CFI it doesn't provide the same guarantees that Wasm CFI does.
How is that different from a compiler that generates JVM bytecode?
Yes, the bytecode was designed specifically for Java's needs, but running languages that weren't designed for the JVM on the JVM is still less of a stretch than compiling C to asm.js, something which has worked quite successfully. Or targeting a different CPU architecture.
That’ll be the end of frontend as we know it, and everyone will have to learn this new api. The benefits are obvious, we’ll finally have a rendering engine for apps. I suppose document-based html pages can stick around, but the rest of us can move on.
WebAssembly made us regress 10 years, and we lost the great GUI based tooling for Web page creation and 3D games that are actually hardware accelerated without browsers doing blacklists.
Even I think something like that is long overdue (as the misuse of HTML and DOM as the most horrible GUI framework for application development ever invented should stop immediately) I somehow don't like the outlook of MS Blazor becoming a thing. I hope everybody knows what that would mean: "Windows" (APIs) in the browser…
QML on the other hands side looks good (at least from the outside). But it's nowhere close to significant usage, so no hope for that, frankly.
When you do need wasm, though, then it opens up entire new possibilities, things you really couldn't do before. I like to compare wasm to the video element: not every site should use it, and it won't replace JS or CSS or HTML, but its existence makes things like YouTube and Netflix possible.
The future of code on the web is JS + wasm.
That said: I don't think you need to worry about JS receding for at least another decade, maybe two.