News for hackers. Stuff that matters.
Re:WebAssembly doesn’t make unsafe languages safe by dmitrygr on Sunday November 25, 2018 @02:35PM (#18528523)
this is complete nonsense. A normal c program running on a modern operating system has the mmu control what memory it can access. So, Web assembly's "just a block of memory" is no better - it is the same.
Re:WebAssembly doesn’t make unsafe languages safe by sitkack on Sunday November 25, 2018 @02:49PM (#18528614)
Correct.

A normal C program has full reign over the entire process memory space.

A wasm program only has access to the call interface provided to it and its linear memory region allocated to it.

The guarantees are much different and greatly in favor of wasm. In wasm the stack and the code segments are off limits.

Re:WebAssembly doesn’t make unsafe languages safe by kllrnohj on Sunday November 25, 2018 @03:32PM (#18528849)
You missed the author's point by miles.

C only has access to its process space as does WASM. WASM's only improvement is it makes stack smashing bugs harder (which ironically makes real security worse as it means you can't use retpoline, but let's ignore that for now)

HOWEVER it gives up on using guard pages and address randomization (systemic preventions against common bugs like buffer overflows), making WASM in practice less safe than C.

WASM is only safer for the host embedding untrusted code. For trusted code, though, it's across the board worse in every way - including security. Which shouldn't be all that contentious of a statement since WASM had no goals or intentions to ever replace trusted native code execution. That's not a thing it tries to do, and it shouldn't be a surprise that it didn't do it.

Re:WebAssembly doesn’t make unsafe languages safe by monocasa on Sunday November 25, 2018 @05:41PM (#18529541)
> which ironically makes real security worse as it means you can't use retpoline

Why wouldn't the WASM JIT retpoline all code (probably only if the underlying processor needs it) rather than relying on the guest programs to do it themselves.

> HOWEVER it gives up on using guard pages and address randomization (systemic preventions against common bugs like buffer overflows), making WASM in practice less safe than C.

Once again, wouldn't the JIT be able to enforce this at runtime?

It's not like WASM binaries are referencing raw address offsets.

Re:WebAssembly doesn’t make unsafe languages safe by kllrnohj on Sunday November 25, 2018 @07:41PM (#18530093)
> Why wouldn't the WASM JIT retpoline all code (probably only if the underlying processor needs it) rather than relying on the guest programs to do it themselves.

Possible, but is that then a runtime option in the WASM header? How does it know if the program needs the cost of retpoline or not? And how can a program ensure that it's getting such mitigations when it needs them?

> Once again, wouldn't the JIT be able to enforce this at runtime?

The JIT has no insight into the app's malloc/free usage, so no, it can't. There is no system allocator in WASM, just a big chunk of linear memory that the app does whatever it wants with.

For an actual case study in why this is risky all you have to do is look at OpenSSL's heartbleed. If it had been using the system's malloc/free (which WASM doesn't have) instead of using its internal free lists then heartbleed largely wouldn't have existed on platforms like OpenBSD.

Re:WebAssembly doesn’t make unsafe languages safe by monocasa on Sunday November 25, 2018 @09:00PM (#18530463)
> Possible, but is that then a runtime option in the WASM header? How does it know if the program needs the cost of retpoline or not? And how can a program ensure that it's getting such mitigations when it needs them?

You're looking at it the wrong way. Untrusted code doesn't have a "I pinky promise that I'm safe" bit they can twiddle in their header. If the code running is untrusted, it doesn't get to make that decision, all code under that context needs to be retpolined. (V8 already does this https://chromium.googlesource.com/v8/v8/+/7d356ac4927e9da3e0... )

> The JIT has no insight into the app's malloc/free usage, so no, it can't. There is no system allocator in WASM, just a big chunk of linear memory that the app does whatever it wants with.

It can retarget the code so that the virtual base address of the linear region isn't fixed. That's about all ASLR does anyway.

> For an actual case study in why this is risky all you have to do is look at OpenSSL's heartbleed. If it had been using the system's malloc/free (which WASM doesn't have) instead of using its internal free lists then heartbleed largely wouldn't have existed on platforms like OpenBSD.

You can implement all of the malloc protection strategies that OpenBSD uses in user space. It's completely legitimate to use your own malloc in those circumstances, libc's malloc isn't magically special, and it makes sense that they'd want to rely on memory allocation with additional guarantees than libc gives you. OpenSSL's sin wasn't re-implementing malloc; it was re-implementing it poorly (and not bounds checking input from attacker controlled packets).

Re:WebAssembly doesn’t make unsafe languages safe by kllrnohj on Monday November 26, 2018 @01:53PM (#18535807)
> You're looking at it the wrong way. Untrusted code doesn't have a "I pinky promise that I'm safe" bit they can twiddle in their header. If the code running is untrusted, it doesn't get to make that decision, all code under that context needs to be retpolined. (V8 already does this https://chromium.googlesource.com/v8/v8/+/7d356ac4927e9da3e0.... )

No, you're not understanding.

retpoline doesn't keep you from attacking others, it keeps you from being attacked. But not everything handles sensitive data and thus doesn't care about being attacked, and doesn't want to pay the cost of the retpoline that they didn't need at all.

How can a WASM app signal "I need retpoline because I have secrets to protect" from "I don't give a damn about retpoline because there's no secret data in my process space at all"?

That's not a decision WASM can unanimously make on behalf of others.

> You can implement all of the malloc protection strategies that OpenBSD uses in user space.

No, you literally can't. WASM doesn't have the APIs necessary to do that. It doesn't have mmap & mprotect. Those are in the "proposals we might consider" future section of WASM. But WASM today cannot implement a malloc/free on-par with those in actual libc implementations on major platforms. To say nothing of debug tools like valgrind.

> OpenSSL's sin wasn't re-implementing malloc; it was re-implementing it poorly (and not bounds checking input from attacker controlled packets).

So the solution to people re-implementing malloc badly is to force everyone to re-implement malloc? How does that follow at all?

I get WASM doesn't want to include malloc/free, but the problem is it didn't include paging-based allocation APIs. It used a nonsense linear growth heap design that doesn't match anything about how memory works on any platform and has been obsolete for 20+ years.

This isn't a big deal in the hyper specific context that WASM is actually targeting, but it is a big deal if you're talking about shoving WASM in places it never had any intention of being.

Re:WebAssembly doesn’t make unsafe languages safe by monocasa on Monday November 26, 2018 @04:46PM (#18537105)
> That's not a decision WASM can unanimously make on behalf of others.

I literally linked to the commit where V8 is indeed unanimously making that decision. If you clear the indirect branch table when transitioning to and from all untrusted programs, what's your threat model again?

> I get WASM doesn't want to include malloc/free, but the problem is it didn't include paging-based allocation APIs. It used a nonsense linear growth heap design that doesn't match anything about how memory works on any platform and has been obsolete for 20+ years.

Go read the WASM spec. It's explicitly is designed for multiple linear regions, just how mmap works. It just didn't make it into the MVP.

Re:WebAssembly doesn’t make unsafe languages safe by kllrnohj on Tuesday November 27, 2018 @12:03AM (#18539555)
> I literally linked to the commit where V8 is indeed unanimously making that decision.

And for things where retpoline isn't needed it's unambiguously wrong (wrong in that runtime is slower than it should be for no gain). What are you not getting about that? They made a decision that when it's wrong it's still safe, but it's still going to be wrong for a non-trivial amount of users.

> Go read the WASM spec. [...] It just didn't make it into the MVP.

Yes, I know, that's why I said what I said. Which was correct and supported by both the spec and your statement just now...?

We're not talking about hypothetical future WASM, we're talking about WASM as it exists today and what problems it can/can't effectively handle.

Re:WebAssembly doesn’t make unsafe languages safe by brynet on Monday November 26, 2018 @12:35PM (#18535103)
This is ignoring an important benefit of the libc implementations of malloc/free on OpenBSD, free pages are being opportunistically munmap'd at random. This catches actual bugs.

Otto Moerbeek has a great recent Twitter thread on the topic: https://twitter.com/ottom6k/status/1065594523559096321

https://twitter.com/ottom6k/status/1063118597160091648

> The JIT has no insight into the app's malloc/free usage, so no, it can't. There is no system allocator in WASM, just a big chunk of linear memory that the app does whatever it wants with.

This point by kllrnohj illustrates a pretty significant weakness.

Re:WebAssembly doesn’t make unsafe languages safe by monocasa on Monday November 26, 2018 @01:38PM (#18535694)
I figured kllrnohj was referencing the fact that OpenBSD clears data when it's allocated. That you can do from WASM pretty easily.

Additionally WASM is moving towards multiple linear regions, which should allow mmap/munmap like functionality.

And in the context of OpenSSL, this kind of fanciness in some libc's that'll make all sorts of syscalls randomly is exactly why they wrote their own allocator.

Re:WebAssembly doesn’t make unsafe languages safe by brynet on Monday November 26, 2018 @02:16PM (#18535991)
The Heartbleed bug would have been found then fixed by the munmap, as the process would have crashed. This has nothing to do with clearing data, it would not have found this.

> And in the context of OpenSSL, this kind of fanciness in some libc's that'll make all sorts of syscalls randomly is exactly why they wrote their own allocator.

"web asm -- if it was good enough for openssl!"

Re:WebAssembly doesn’t make unsafe languages safe by monocasa on Monday November 26, 2018 @04:40PM (#18537053)
Heartbleed fully allocated the larger buffer. It wouldn't have crashed. It was just uninitialized memory being read out. Yes, munmap and remap would have cleared that ram, but so would the malloc clearing.

> "web asm -- if it was good enough for openssl!"

More like, "OpenBSD, so slow that people feel the need to write their own malloc".

Re:WebAssembly doesn’t make unsafe languages safe by sitkack on Sunday November 25, 2018 @06:20PM (#18529736)
Please write an essay on how to attack WASM based code and how to structure your codebase to mitigate the outlined flaws.

[edit this was not snark, I believe the parent has important insights]

I believe it is possible, but the severity seems orders of magnitude less than native code.

The host controls the VM interface boundary. Native code can only get this partially via process isolation.

Re:WebAssembly doesn’t make unsafe languages safe by repsilat on Sunday November 25, 2018 @03:00PM (#18528689)
"Full rein".

And the C heap is typically a linear memory region (that grows monotonically) isn't it?

Re:WebAssembly doesn’t make unsafe languages safe by slededit on Sunday November 25, 2018 @03:28PM (#18528830)
brk does grow linearly (a holdover from the days of segmentation). But malloc may well allocate chunks of virtual memory for large allocations. Windows doesn't have a brk equivalent and the underlying heap is fully implemented via VirtualAlloc.
Re:WebAssembly doesn’t make unsafe languages safe by floatboth on Sunday November 25, 2018 @06:25PM (#18529757)
Pretty much only glibc malloc still uses brk. GNU being GNU I guess. Modern mallocs like jemalloc use mmap exclusively.

FreeBSD straight up did not implement sbrk at all for aarch64 and riscv – very very few things broke because of that (one of the things that did break was, IIRC, GNU Emacs).

Re:WebAssembly doesn’t make unsafe languages safe by repsilat on Sunday November 25, 2018 @06:22PM (#18529740)
Fair, but I think this all amounts to "A linear patch of memory is fine primitive to build an allocator or standard library on."

The "not faulting on address zero" thing is interesting but not crazy -- only broken programs will break.

Re:WebAssembly doesn’t make unsafe languages safe by slededit on Sunday November 25, 2018 @06:37PM (#18529804)
While you can build it that way it is not at all a good way to do it. You lose all the benefits of paging when handling fragmentation - you basically will never be able to shrink the data segment on most practical programs - and therefore never be able to return memory to the operating system.

brk is an ancient holdover from when memory protection was done via segmentation. Paging eliminates the need for this historical misfeature. I'm a bit sad WASM propagated it further into modern systems.

Re:WebAssembly doesn’t make unsafe languages safe by repsilat on Sunday November 25, 2018 @07:08PM (#18529940)
Isn't paging orthogonal to using brk? Or is "paging" something more specific than "virtual memory is handled by the OS in big chunks"?

I guess your allocator can try its best to prevent fragmentation, but you're right that returning memory to the OS isn't going to happen without explicit compaction (which nobody in native code is going to do.) Dunno if anyone ever expects memory use to go down though.

(Is less true than it used to be? -- I guess we used to make big swap files and now that's less fashionable.)

I guess if it's not too much more of a burden on the OS to make it keep track of a Swiss cheese virtual memory allocation then it is useful.

Re:WebAssembly doesn’t make unsafe languages safe by slededit on Sunday November 25, 2018 @07:14PM (#18529973)
The OS implements brk under the hood with "swiss cheese virtual memory" so you don't get any real optimizations here. On AMD64 paging is mandatory. It does have a cost but the MMU hardware accelerates this to make it mostly not noticeable.

The brk system call places an unnecessary restriction on how the memory is used that is not imposed by the hardware. Back in the 70s when segmentation was a thing and virtual memory hadn't taken hold this would be different - but virtual memory has won.

Re:WebAssembly doesn’t make unsafe languages safe by conradev on Sunday November 25, 2018 @03:27PM (#18528827)
The process’ address space includes more than just malloc zones: it includes the code of the running process, the stacks for all of the running threads, linked libraries and their imported functions, etc.