4 ms·
Again, it's not really 'native binary' vs wasm. The binary can only really tell the os what it expects it to do. It is more of 'operating system' vs wasm. By n
by eyberg 3y ago
Again, it's not really 'native binary' vs wasm. The binary can only really tell the os what it expects it to do. It is more of 'operating system' vs wasm.
By no means an authoritative list and I've not brought up the sandbox at all - that's completely out of scope for this argument but:
* wasm has no aslr - making it incredibly easy to figure out where something lives - you can run the same wasm payload again and again again and get the same result, for instance on linux:
me@box:~/w/zz/aslr$ ./aslr
Library functions: 00007faebfc9f3f0, Heap: 0000562a103c12a0, Stack: 00007ffeea5d8fec, Binary: 0000562a0f1cf179
me@box:~/w/zz/aslr$ ./aslr
Library functions: 00007ff2eda9f3f0, Heap: 000056509ae012a0, Stack: 00007fff849209bc, Binary: 000056509a92d179
~/w/wasi-sdk-20.0+threads/bin/clang --sysroot ~/w/wasi-sdk-20.0+threads/share/wasi-sysroot/ aslr.c -o aslr.wasm
and on wasm... Nothing changes:
me@box:~/w/zz/aslr$ wasmer aslr.wasm
Library functions: 0000000000000002, Heap: 0000000000011500, Stack: 00000000000114b4, Binary: 0000000000000001
me@box:~/w/zz/aslr$ wasmer aslr.wasm
Library functions: 0000000000000002, Heap: 0000000000011500, Stack: 00000000000114b4, Binary: 0000000000000001
(btw - all of this works on all wasm runtimes)
* wasm can write directly to 0x0 - meaning I can just initialize variables to all sorts of random bad values (eg: overriding functions that might return an expected value or perhaps I have a user_id from a database or worse an 'admin' flag or something, these are just a few examples - it gets way worse in other languages that depend on this)
* wasm can easily overflow buffers (despite claims to the contrary) - that claim really should be taken down from the website - it is totally false
* doesn't have the concept of read-only memory
These are all issues that linux hasn't really had to deal with for 20? years now.
- junon 3y ago> wasm has no aslr Many systems don't employ ASLR. There's a long history of very smart people questioning if ASLR is even a good deterrent. This dissent even extends to KASLR. ASLR is also not unbreakable, don't fool yourself about this. Also, ASLR only works if your code is compiled as position-independent, which isn't always the case. There's also (sometimes) a performance hit with it. Finally, I don't see how the ASLR argument here is anything but moving the goalposts away from your original argument. > wasm can write directly to 0x0 Again, this is not a guarantee, either. Nothing is stopping an OS from mapping in something at virtual page 0 either. It's just a specification from C (perhaps before) that's been adopted by a lot of other languages, so much so that OS developers tend not to map anything there as a rule. On many Microcontrollers for example, 0x0 is usually a perfectly valid memory address, and not allowing something there means you lose at least <required alignment> bytes of usable memory. > wasm can easily overflow buffers Not sure what you mean by this. > that claim really should be taken down from the website Can you quote the claim? Bonus points for linking to it so we have some context. > doesn't have the concept of read-only memory So? Again, as many others have pointed out, neither do OSes unless you can somehow guarantee they're mapping memory in with an MMU or MPU with flags lacking X/W. You're still trusting the OS to do it right, the linker to do it right, and the language to place symbols in the right sections. > These are all issues that linux hasn't really had to deal with for 20? years now. Of course it has, what are you talking about?
- eyberg 3y ago> So? Again, as many others have pointed out, neither do OSes unless you can somehow guarantee they're mapping memory in with an MMU or MPU with flags lacking X/W. You're still trusting the OS to do it right, the linker to do it right, and the language to place symbols in the right sections. If you don't care/understand about the concept of read-only memory I'm not going to be able to convince you of anything. I'll just state that there's a few tens of thousands of people descending on Vegas next week and the longer the wasm community doesn't deal with these issues the louder those people are going to get.
- junon 3y agoHaha, alright.
- josephg 3y agoThanks! These claims are really interesting. - WASM has no ASLR. If I understand correctly, the attack vector here is that if a buffer overrun lets you modify a function pointer, you could replace that function pointer with another pointer to have the program execute different code. As you say, this is hard in native linux programs because of ASLR. You need a pointer to some code thats loaded in memory and you need to know where it is. In wasm, the "pointer" isn't a pointer at all. indirect_call takes an index into the jump table. Yes, this makes it easier to find other valid function pointers. But wasm also has some advantages here. Unlike in native code, you can't "call" arbitrary locations in memory. And indirect_call is also runtime typechecked. So you can't call functions with an unexpected type signature. Also (I think) the jump table itself can't be edited by the running wasm module. So there's no way to inject code into the module and run it. You only have access to call the already-loaded functions that are in the jump table. And amongst those, you can only substitute one with a matching type signature. I agree - ASLR could help here. But it still doesn't sound super easy to exploit. That said, it might be much easier to exploit this with wasi when the function table is filled with unix syscalls. Docs: https://developer.mozilla.org/en-US/docs/WebAssembly/Understanding_the_text_format#webassembly_tables https://developer.mozilla.org/en-US/docs/WebAssembly/Underst... - WASM allows writing to 0x0. You're probably right about this. To be clear, it means if pointers are set to 0 then dereferenced, the program might continue before crashing. And the memory around 0 may be overwritten by an attacker. How bad this is in practice depends on the prevelance of use-after-free bugs (common in C / C++) and what ends up near 0 in memory. In rust, these sort of software bugs seem incredibly rare. And I wouldn't be surprised if wasm compilers for C/C++ start making a memory deadzone here - if they aren't doing that already. - wasm can easily overflow buffers Sure, but so can native C code. And unlike native code, wasm can't overflow buffers outside of the data section. So you can't overwrite methods or modify the memory of any other loaded modules. So on net, wasm is still marginally safer than native code here. If you're worried about buffer overflows, use a safer language. - wasm doesn't have the concept of read-only memory Interesting! I can see this definitely being useful for system libraries like mmap. This would definitely be nice to have, and it looks like the wasm authors agree with you. https://github.com/WebAssembly/multi-memory/issues/15 https://github.com/WebAssembly/multi-memory/issues/15