6 ms·
Syscall Call-From Verification
- basementcat 7y agoLooks like this may break some JIT's? Or is the workaround to have the JIT'ed code call libc instead of making direct syscalls?
- jchw 7y agoHmm. Do any JITs actually emit syscalls directly? I would’ve guessed most JITs won’t even emit direct libc calls directly, since there tends to be layers of abstraction between it and the software.
- notaplumber 7y agoIndeed. This appears to be the case for stuff encountered thus far.
- pm215 7y agoQEMU does for its user-mode-only code, but not in JITted code. We have a little shim that directly executes a syscall instruction because we want to be able to wind the PC forward/backward across it to avoid a race condition with a signal arriving after the guest thinks it's made the syscall but before we've made the syscall in the host. But that's currently only done by linux-user; bsd-user should ideally have a similar mechanism but is basically dead/dying for lack of maintainers who care about the BSDs. In any case, that falls under "in the binary's text segment" rather than JIT output. (code at https://git.qemu.org/?p=qemu.git;a=blob;f=linux-user/host/x86_64/safe-syscall.inc.S;h=f36992daa34e0f59c621d506bdda00e281e437be;hb=HEAD https://git.qemu.org/?p=qemu.git;a=blob;f=linux-user/host/x8... )
- notaplumber 7y agoOpenBSD already prevents syscalls from writable pages. It did not break JITs, in fact, to quote Theo de Raadt, it brings over an aspect of W^X to JITs that haven't been adapted to work with mandatory W^X. https://marc.info/?l=openbsd-cvs&m=155942895309114&w=2 https://marc.info/?l=openbsd-cvs&m=155942895309114&w=2 This means it's forced to use the libc stubs for syscalls. Any direct syscall from a JIT is suspect.
- jchw 7y agoMy only question: does making Go use libc stubs require Cgo? One property of Go that is really nice is that you can cross compile effortlessly without needing to build a cross compilation toolchain. Cgo negates this because it requires a C toolchain for the target...
- Gaelan 7y agoIIRC macOS only supports syscalls via dynamically linked libc (libsystem)—there's no guarantee of a stable ABI for direct syscalls. Assuming go uses libsystem on macOS, is should be able to do something similar for BSD.
- jchw 7y agoI guess it actually should be doable. In theory, all it has to do is link to the correct symbols in libc.so (or the respective library.) That doesn't seem like it would require a C compiler, so as long as the ABI is guaranteed to be stable, and the Go linker is capable of handling it. Though one unfortunate aspect of this is even despite that, once they DO flip the switch, all old Go binaries will stop working. (Though really, Go binaries don't have a long shelf life, because you have to recompile them when new security patches are released anyway. So maybe that is a non-issue.)
- clarry 7y agoOpenBSD binaries in general don't have a long shelf life. They will break ABI when they want to move forward.
- notaplumber 7y agoFrom my dupe submission: https://news.ycombinator.com/item?id=21653796 https://news.ycombinator.com/item?id=21653796 This new proposed mitigation builds upon other work, such as libc/ld.so random re-linking at boot, and opportunistic enforcement of syscalls from only un-writable pages by default. https://www.openbsd.org/innovations.html https://www.openbsd.org/innovations.html
- Reelin 7y agoThe description says to program to the API instead of the ABI. I'm not very familiar with low level work and exploits, but aren't syscalls the API for the kernel itself? As far as I'm able to understand, it seems like the proposed mitigation blocks access to the kernel unless your code is either preauthorized (msyscall) or goes through a layer of indirection (libc) that undergoes randomized re-linking at boot. That seems to make sense to me, since it significantly reduces an adversary's knowledge about internals they are presumably targeting. A few questions: * Is it possible to authorize arbitrary code, or is access to msyscall (via libc or otherwise) restricted outside of boot? * It seems that the kernel itself also undergoes randomized re-linking at boot (https://www.openbsd.org/innovations.html https://www.openbsd.org/innovations.html). So what does forcing everything through libc gain us? * Is equivalent hardening likely to make it to the Linux world in the foreseeable future? * What sort of attacks is this likely to prevent in practice? * What have I misunderstood, and would someone mind explaining?
- mike_hock 7y agosyscall numbers are constant (part of the ABI!) regardless of the kernel's address space layout. Conversely, addresses of libc functions or any other code in the program are randomized at load time, so are unpredictable to an attacker.
- saagarjha 7y agoDoes OpenBSD stabilize the system call API?
- justincormack 7y agoNot like Linux, it is stable for a few releases but not forever in the BSDs, for openbsd I think its fairly short.
- Reelin 7y agoI don't usually think of integer constants passed as an argument to a function as an ABI, but given that they're hard coded at kernel compile time, fair enough. What I'm struggling to understand is why an additional layer of indirection is required to facilitate randomization in this case. It seems I must have a fundamental misunderstanding of how some part of the system works at this low level. I'm also wondering what (if anything) is being lost to this mitigation - the syscall(2) manpage (http://man7.org/linux/man-pages/man2/syscall.2.html http://man7.org/linux/man-pages/man2/syscall.2.html) seems to imply that not all system calls necessarily have matching wrapper functions in the platform's C library.
- jeffrallen 7y agoDamn, OpenBSD is good.
- jacobush 7y agoDefense in depth, this is not unbreakable, but it adds another layer of difficulty an attacker must bridge.