Remix.run Logo
pornel a day ago

There's a hybrid approach of C -> WASM -> C compilation, which ends up controlling every OS interaction and sandboxing memory access like WASM, while technically remaining C code:

https://rlbox.dev/

jart 20 hours ago | parent | next [-]

WASM sandboxes don't do much to guarantee the soundness of your program. It can hose your memory all it wants, it can just only do so within the confines of the sandbox.

Using a sandbox also limits what you can do with a system. With stuff like SECCOMP you have to methodically define policies for all its interactions. Like you're dealing with two systems. It's very bureaucratic and the reason we do it, is because we don't trust our programs to behave.

With Fil-C you get a different approach. The language and runtime offer a stronger level of assurance your program can only behave, so you can trust it more to have unfettered access to the actual system. You also have the choice to use Fil-C with a sandbox like SECCOMP as described in the blog post, since your Fil-C binaries are just normal executables that can access powerful Linux APIs like prctl. It took Linux twenty years to invent that interface, so you'll probably have to wait ten years to get something comparable from WASI.

IshKebab 14 hours ago | parent [-]

> It can hose your memory all it wants, it can just only do so within the confines of the sandbox.

True, although as I understand it the WASI component model at least allows multiple fine-grained sandboxes, so it's somewhere in-between per-object capabilities and one big sandbox for your entire program. I haven't actually used it yet so I might be wrong about that.

> so you'll probably have to wait ten years to get something comparable from WASI

I think for many WASI use cases the capability control would be done by the host program itself, so you don't need OS-level support for it. E.g. with Wasmtime I do

  WasiCtxBuilder::new()
        .allow_tcp(false)
        .allow_udp(false)
        .allow_ip_name_lookup(false)
But yeah a standard WASI program can't itself decide to give up capabilities.
pjmlp 13 hours ago | parent [-]

WASI is basically CORBA, and DCOM, PDO for newer generations.

Or if you prefer the bytecode based evolution of them, RMI and .NET Remoting.

I don't see it going that far.

The WebAssembly development experience on the browser mostly still sucks, especially the debugging part, and on the server it is another yet another bytecode.

Finally, there is hardly any benefit over OS processes, talking over JSON-RPC (aka how REST gets mostly used), GraphQL, gRPC, or plain traditional OS IPC.

IshKebab 10 hours ago | parent [-]

> hardly any benefit over OS processes, talking over JSON-RPC

Hardly any benefit except portability and sandboxing, the main reasons WASM exists?

kllrnohj 3 hours ago | parent | next [-]

WASM sacrifices guest security & performance in order to provide mediocre host sandboxing, though. It might be a useful tradeoff sometimes, but proper process-based sandboxing is so much stronger and lets the guest also have full security & performance.

IshKebab 3 hours ago | parent [-]

How is process-based sandboxing stronger? Also the performance penalty is not only due to sandboxing (I doubt it's even mostly due to it). Likely more significant is the portability.

jacquesm 2 hours ago | parent [-]

> How is process-based sandboxing stronger?

Because the guarantees themselves are stronger, process isolation is something we have decades of experience with, it goes wrong every now and then but those are rare instances whereas what amounts to application level isolation is much weaker in terms the guarantees it that it provides and the maturity level of the code. That suggests that if you base your isolation scheme on processes rather than 'just' sandboxing that you will come out ahead and even with all other things the same you'd have one more layer in your stack of swiss cheese slices. A VM would offer another layer of protection on top of that, one with yet stronger guarantees.

pjmlp 10 hours ago | parent | prev [-]

WASM is only portable if the only thing it does is heating up CPU, given that everything else depends on the host.

IshKebab 5 hours ago | parent [-]

No because the host can present the same interface on every platform. I do think that WASI is waaay to much "let's just copy POSIX and screw other platforms", but it does work pretty well even on Windows.

pizlonator a day ago | parent | prev [-]

That's a sandboxing technology but not a memory safety technology.

You can totally achieve weird execution inside the rlbox.

ComputerGuru 21 hours ago | parent | next [-]

Running ffmpeg compiled for wasm and watching as most codec selections lead to runtime crashes due to invalid memory accesses is fun. But, yeah, it’s runtime safety, so going to wasm as a middle step doesn’t do much.

pizlonator 21 hours ago | parent | next [-]

> Running ffmpeg compiled for wasm and watching as most codec selections lead to runtime crashes due to invalid memory accesses is fun.

For all you know that’s a bug in the wasm port of the codec.

> it’s runtime safety

So is Fil-C

The problem with wasm is that an OOBA in one C allocation in the wasm guest can still give the attacker the power to clobber any memory in the guest. All that’s protected is the host. That’s enough to achieve weird execution.

Hence why I say that wasm is a sandbox. It’s not memory safety.

ComputerGuru 20 hours ago | parent [-]

I’m not disagreeing with anything you said about wasm?

14 hours ago | parent | prev | next [-]
[deleted]
pjmlp 13 hours ago | parent | prev [-]

Finally reality is catching up with the WASM sales pitch against other bytecode formats introduced since 1958, regarding security and how great it is over anything else.

singpolyma3 10 hours ago | parent [-]

Warm was great because it was lightweight and easy to target from any language and create any custom interaction API with the host. That's becoming less true as they bolt on features no one needed (GC) and popularize standardized interfaces that contain the kitchen sink (WASI) but these things can still be treated as optional so it can still be used for much more flexible use cases than java or .net

azakai an hour ago | parent | next [-]

> features no one needed (GC)

WasmGC is absolutely necessary for languages like Dart, Kotlin, and Java, which are all using it right now successfully.

But I get that if you're compiling C or Rust then it might seem like it isn't useful.

mhjkl 5 hours ago | parent | prev | next [-]

There’s no guarantee the toolchains will support WASM “preview” forever and make the bloat optional, and even if they do you could still end up in an ecosystem where it would be unviable. At some point you’re probably better off just compiling to RISCV and using an emulator library instead.

apitman 3 hours ago | parent [-]

Fortunately core wasm is simple enough for a single person to implement an interpreter or even compiler for.

Even if the major engines continue to pile on complexity we have a pretty good escape hatch I think.

pjmlp 10 hours ago | parent | prev [-]

Since 1958 (UNCOL) there have been more options than only Java or CLR MSIL.

zozbot234 15 hours ago | parent | prev [-]

Wasm now supports multiple modules and multiple linear memories per module, so it ought to be quite possible to compile C to Wasm in a way that enforces C's object access rules, much like CHERI if perhaps not Fil-C itself.

pjmlp 10 hours ago | parent | next [-]

Some WebAssembly runtimes now do support those parts of the specification.

IshKebab 14 hours ago | parent | prev [-]

You wouldn't be able to get quite as fine-grained. One memory per object is probably horrifically slow. And I don't know about Fil-C, but CHERI at least allows capabilities (pointers with bounds) to overlap and subset each other. I.e. you could allocate an arena and get a capability for that, and then allocate an object inside that arena and get a smaller capability for that, and then get a pointer to a field in that object and get capability just for that field.

Findecanor 9 hours ago | parent | next [-]

Fil-C has like one "linear memory" per object and each capability gives read/write access to the whole object.

But Fil-C has its compiler which does analysis passes for eliding bounds-checks where they are not needed, and I think it could theoretically do a better job at that than a WASM compiler with multi-memories, because C source code could contain more information. Unlike WASM, but like CHERI, every pointer in memory is also tagged, and would lose its pointer status if overwritten by an integer, so it is still more memory-safe in that way.

IshKebab 7 hours ago | parent [-]

It has a separate address space for each object? That seems unlikely. Is it not pretty much a software implementation of CHERI?

zozbot234 10 hours ago | parent | prev [-]

One would probably just need to define WASM extensions that allow for such subsetting. Performance will probably be competitive with software implementations of CHERI (perhaps with varying levels of hardware acceleration down the road) which isn't that bad.