Taking another quick tour of wasm runtimes, the thing that strikes me the most is how so few of them seem to aim for a first-class experience that prioritizes security over speed.
-
Taking another quick tour of wasm runtimes, the thing that strikes me the most is how so few of them seem to aim for a first-class experience that prioritizes security over speed.
No, I don't want you to JIT my code, no I don't want cranelift involved. There is known state of the art for building fast interpreters, please may I have a fast interpreter in a memory-safe language, wherein the wasm blob doesn't immediately get free reign over the host process if your JIT has a bug
-
I feel like I'm taking crazy pills or something, because literally the first thing I think of when I see wasm is "oh cool a lua-like experience where I can shove code in a sandbox with execution I can trust and a bidirectional FFI over which I have total control"
And yet every project I see steers you towards "lol we generate native code and jmp to it" and "here run this to load the entire WASIX ABI, now the untrusted code has full filesystem and network access, cool right?"
-
and like I get it, a .NET CLR but make it web flavored is neat too, but I already have a thing for running code I trust it's called a computer with software compiled for it. The thing I don't have is a way to do controlled execution of fully untrusted code that's _fast enough_, but secure to the level of "you need bugs in this safe language's runtime to get anywhere". And I can't possibly be the only one who needs this, and yet all the wasm hosts are like "lol check out this unsafe cast"
-
d@nny "disc@" mcClanahanreplied to Dave Anderson last edited by
@danderson people seem to really just want it to replace the C ABI instead of all the stuff it's advertised to address and ostensibly designed around very annoying
-
Dave Andersonreplied to d@nny "disc@" mcClanahan last edited by
@hipsterelectron And yet, WASI seems to be marching full steam into lifting posix into wasm, which... Okay now you truly have rebuilt a worse .NET CLR, but we already had one of those
-
@hipsterelectron I dunno I wish people well I guess, I'm just truly befuddled at how much the first thing I think of when I see wasm, and the first thing everyone else apparently thinks of are at complete opposite ends of the design space. Not even a little bit off, antimatter-level opposite.
-
@danderson yeah. i think wazero, the go one, is just an interpreter, i don't know about it's feature support. I think last I looked a lot of the rust interpreters were no longer keeping up with the standards
-
@raggi wazero has a JIT now, and defaults to it on supported platforms. It blasts machine code into a page, makes it executable, and jmps to it.
The interpreter's still there, but the mere presence of a JIT in the same neighborhood makes me very worried about what the interpreter might get up to, and how much effort may or may not be going into making it as fast as interpreters can be.
Same issue as lisps that acquire a JIT, the interpreter rapidly gets much worse than it _could_ be.
-
@raggi The API surface also weirds me out a bit, because it's much easier to accidentally give the guest code full FS/socket access than it is to expose a sandboxed instance of the API surface, which feels extremely backwards to me. It should be _harder_ to grant the guest code host-grade privileges, that's the option that should take more typing!
I keep feeling befuddled at how utterly opposite my priorities seem to be to those of the ecosystem. I'm genuinely curious how I end up that far off.
-
@danderson that's a shame, i guess we need some reinvestment going on. i wonder how much work it is to fill in gaps in wain
-
@danderson i don't know how far concerned i'd be with a well tested JIT honestly. I'd still be sandboxing heavily a the host layer regardless (because rowhammer and so on), and maybe add some basic tripwires that are hooked up to a process lock.
-
@raggi I have to assume it's either feeling the pressure from wasmtime and their cranelift-based JIT, or being pushed in a particular direction by a customer base.
I also don't begrudge doing JIT in addition to interpreting, it's a natural stepping stone as a project matures. I just... I dunno, once you introduce the things a JIT needs, I expect to have a lot of reading material available about how carefully it's being developed and thought about. But again I seem to be an outlier
-
@danderson use case matters ofc, how many layers of defense can you put in place in a particular deployment. a lot of the edge compute interest can quite easily have several other layers of defense and limited intertenant and escalation access at more fundamental levels, but in these use cases startup time and runtime are very important obviously
-
@raggi yeah it can be mitigated, certainly. But that's the sort of thing where I'm looking for docs that sit me down and go "okay, real talk, here's the tradeoffs, the risks, how we try to mitigate them, other things you should consider doing on your end" and so forth. Instead the tutorial tells you to run the constructor that uses a JIT under the hood, and I dunno I guess trust the code?
Maybe the disconnect is that I have trust issues
-
@raggi Good point about deployment. When the commercial backers of this ecosystem are happy to sell you a place to run the thing that provides the extra layering, the tradeoffs happening here fall out fairly naturally. Ease of getting started and how quickly the customer function gets off CPU so you can rent it to someone else is the driver.
-
Brian Swetlandreplied to Dave Anderson last edited by
@danderson There are a lot of design features in WASM that make it much easier to generate safe code, especially on 64bit architectures, than many bytecodes, etc. Things like the way memory is limited to (currently 1) linear array, references are through handles, etc.
My main grumble with it remains that I find the specification/documentation really annoyingly laid out and hard to follow.
-
Brian Swetlandreplied to Brian Swetland last edited by
@danderson I feel like, similar to how the Lua virtual machine with its "word code" packing arguments in with opcodes to simplify fetch and decode making a fast interpreter implementation straightforward, WASM's design was very specifically built with safe-as-possible AOT/JIT code generation in mind, intentionally trying to simplify high performance implementations especially on modern 64bit architectures.
-
Dave Andersonreplied to Brian Swetland last edited by
@swetland That's good to know! I still have trust issues somewhat, because JITs are parked in the same bucket in my brain as cryptographic code: everyone is welcome to write the stuff, but I would really like to see the author's license to wrangle untrusted inputs before I let it into my process.
Designing to make fast execution possible is great, I just don't know the people in this space well enough to go "oh, Anna wrote the JIT, that's fine I can absolutely trust it to be solid"
-
Brian Swetlandreplied to Dave Anderson last edited by
@danderson Fair! And you can certainly build unsafe WASM runtimes. The design doesn't guarantee safety in the face of sloppy or incorrect implementations, it just has a lot of features that make building a safe AOT/JIT runtime much easier and more straightforward than a lot of other representations I've seen over the years.
-
Dave Andersonreplied to Brian Swetland last edited by
@swetland Yeah that's definitely reassuring! Perhaps a trait of what I was exposed to over the years, but when I think JIT I think Native Client, and how eyewateringly tricky that was to make safe; and the browser javascript JITs, and similarly eyewatering amounts of effort poured into raising the bar up to requiring _two_ tricky 0days to pwn a machine. But both of those are trying to retrofit JIT onto a hostile universe, I can see how wasm would have a leg up.