4 ms·
I 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.
by Reelin 7y ago
I 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.
- ben_bai 7y agoYou are referencing a Linux manpage. But if it's also true for OpenBSD those syscalls will get deleted or a libc wrapper will be introduced.
- clarry 7y ago> What I'm struggling to understand is why an additional layer of indirection is required to facilitate randomization in this case. You can't randomize the integer constants without rebuilding the kernel and everything that depends on those constants. It would be very inconvenient, and the amount of randomization would likely be limited by the number of syscalls (because you want to pack them tight in a lookup table instead of having sparse numbers that are expensive to look up). If the number of syscalls is known, randomization can at best make you call the wrong one. By contrast, address randomization means the program will probably crash (instead of executing some random syscall) unless it can figure out the address of the function it wants. Randomizing addresses can be done on the fly in the runtime linker, without rebuilding binaries. Additional randomness can be introduced by relinking binaries with a randomizing linker, which is much simpler than running a full build. > 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. syscall(2) lives in libc.
- Reelin 7y agoAfter a bit more reading, it seems I hadn't realized just how low level direct system calls actually are (https://en.wikibooks.org/wiki/X86_Assembly/Interfacing_with_Linux https://en.wikibooks.org/wiki/X86_Assembly/Interfacing_with_...). Apparently it's either a software interrupt or dedicated instruction, with the constant in a register. ASLR requires more abstraction than that (obviously), and there's no point to it if an exploit can just use the front door instead.
- mike_hock 7y agoI don't know where you draw your lines, but a syscall (on Linux and amd64, but it should work pretty much the same on BSD and other architectures) looks like mov rax, <syscall number> ; Depending on the syscall, it expects its parameters ; in various other registers syscall ; this is an actual instruction So yes, it is very much part of the ABI. It selects which function to call. The extra indirection, AFAIK, is needed because you couldn't just call a kernel function from userspace and have it run with kernel privileges. That's what the syscall instruction is for, to put the processor back in ring 0 so the syscall handler runs in kernel space. As for what's lost, well, for example, a sane language-agnostic kernel ABI is lost to a C-centric libc API. I don't know if the syscall wrapper support in libc is as incomplete on BSD as it is on Linux, but they could add the missing wrappers, of course. A cleaner approach might have been to have a separate libsyscall that only wraps syscalls and is mapped into the "blessed" address space that is allowed to issue syscalls. But then libc would have to wrap the wrappers, and they probably didn't want that extra indirection.