20 ms·
OpenBSD: Removing syscall(2) from libc and kernel
- brynet 3y agoFollow-up mail from Theo showing what the full removal looks like. https://marc.info/?l=openbsd-tech&m=169842095809570&w=2 https://marc.info/?l=openbsd-tech&m=169842095809570&w=2
- __turbobrew__ 3y agoIt looks like golang is going to have to deal with — again — OpenBSD treating libc as the interface with the kernel instead of syscalls being the interface with the kernel. I wonder if there could be some way to sign a dynamic library to allow it to create direct system calls and then pass that as a kernel command line argument at boot?
- CHY872 3y agoOpenBSD’s position is far from unique. It’s shared with MacOS (and iOS).
- steveklabnik 3y agoAnd Windows, in a sense: not that libc is the interface, but that the assembly-level API is not the interface.
- masklinn 3y agoAnd windows. And that's just the platforms which technically enforce it. Linux is essentially the only platform which actually supports raw syscalls, in the sense that it's considered a normal system API.
- irdc 3y ago> I wonder if there could be some way to sign a dynamic library to allow it to create direct system calls and then pass that as a kernel command line argument at boot? That sounds like an additional knob to tweak. The OpenBSD project is famously opposed to such knobs.
- matheusmoreira 3y agoOpenBSD is certainly taking it quite far. They want to disallow system calls from all non-libc code segments so that only whitelisted code can interface with it. It is not the only operating system in the "unstable kernel interface" group though. Linux is actually the only one with a stable system call interface. I've written somewhat at length about this: https://www.matheusmoreira.com/articles/linux-system-calls https://www.matheusmoreira.com/articles/linux-system-calls
- masklinn 3y agoFWIW your website is unusable on desktop: the font is unreadably huge. And while Firefox's reader mode does seem to mitigate the issue correctly, Safari's cuts off at the second paragraph.
- matheusmoreira 3y agoThank you. I'll try to fix it. I gotta get better at this.
- matheusmoreira 3y agoI reduced the font size to 24px. Does it read better despite the margins? I appreciate the feedback. My intention was to maximize the use of space with big fonts even on the desktop but there's no point if the resulting text is unreadable.
- matheusmoreira 3y agoImproved the look of the site as well while I was at it.
- deleted 3y ago[deleted]
- LegionMammal978 3y ago> It is not the only operating system in the "unstable kernel interface" group though. Linux is actually the only one with a stable system call interface. It's wrong to say that Linux stands alone in having a stable syscall interface. FreeBSD [0] and NetBSD [1] both retain syscall compatibility for old binaries (the former apparently with some exceptions permitted); DragonFly BSD also appears to keep old syscalls in place. In fact, I only know of Windows, OpenBSD, and presumably macOS as mainstream desktop OSes without mostly-stable syscalls. [0] https://wiki.freebsd.org/AddingSyscalls#Backward_compatibily https://wiki.freebsd.org/AddingSyscalls#Backward_compatibily [1] https://www.netbsd.org/docs/internals/en/chap-processes.html#syscall_versioning https://www.netbsd.org/docs/internals/en/chap-processes.html...
- masklinn 3y ago> It looks like golang is going to have to deal with — again — OpenBSD treating libc as the interface with the kernel instead of syscalls being the interface with the kernel. Something they wouldn't have to do if they'd heeded the warnings they got since they first started going raw syscalls on non linux systems. But as usual, go is uniquely american, only doing the right thing after it has tried everything else.
- PrimeMcFly 3y ago> go is uniquely american, doing the right thing after it has tried everything else. That doesn't seem like anything common to an American way of doing things. What an odd statement.
- kstrauser 3y agoIt's a play on a quote often attributed to Winston Churchill: https://quoteinvestigator.com/2012/11/11/exhaust-alternatives/ https://quoteinvestigator.com/2012/11/11/exhaust-alternative...
- arp242 3y agoBizarre nationalistic "they're doing it because they're Americans" rantings are still not okay even if they're a "play on a quote". I can "play" with all sorts of quotes to say all sorts of idiotic things.
- kstrauser 3y agoI guess. I'm proudly American and I thought it was funny, but everyone has different tolerances.
- tadfisher 3y agoYou could also describe it as doing the sane thing (avoiding hardcoding against the libc ABI through FFI) until the only sane option is removed. Did you know many libc APIs are preprocessor macros?
- bregma 3y agoWhat about OSes that are not built around monolithic kernels and the syscall() paradigm?
- saagarjha 3y agoI am sure Cosmopolitan is going to love this change.
- masklinn 3y agoI would assume they already have ways to bounce through a dynamically linked system library since cosmopolitan works on macos, and even more so windows.
- Conscat 3y agoThat's true, but it's a point of pride in Cosmo's marketing that it produces statically linked binaries acroscreate, least several operating systems. It can dynamically link the system32 DLLs in Windows and probably could OpenBSD's crt, but dynamic linking in general doesn't work. `dlopen` is no-op, and this has made Cosmo graphics extremely difficult so far.
- actionfromafar 3y agoIs that a self-imposed limitation? It sounds eminently possible to add some kind of work-around for dynamic linking. Maybe not for a general case, but for creating a GUI for instance.
- Conscat 3y agoYes, there actually is a to-be merged fork of Cosmopolitan that makes Dear ImGui work, but no dynamic linking is generally a big limitation for GPU acceleration.
- blueflow 3y ago> OpenBSD treating libc as the interface with the kernel instead of syscalls being the interface with the kernel Which is a reasonable thing, given that the libc interface is defined by a widely used IEEE standard while the kernel interface is not.
- Conscat 3y agolibC is an extremely leaky abstraction. Programming to it assumes you have a runtime that supports constructor functions, POSIX errno and locale, a global heap allocator singleton, and more. The design space of _Hello World_ is massively constrained by libC.
- LanzVonL 3y ago[dead]
- ahoka 3y agoJust remove the kernel from the base install already?
- tiffanyh 3y agoCan someone explain the significance.
- monocasa 3y agoOpenBSD has been putting in a lot of work lately to harden the syscall ABI; a large component of that work has been constricting how a syscall is invoked from user space as a defense in depth technique to make shell code style exploits more difficult. That's previously taken the form of techniques like only allowing syscalls to be invoked from the libc .text section. This work is removing a very indirect morph of syscall where the arguments/sysnum are in a struct in memory, making it harder for exploits to invoke weird versions of syscalls on their own terms.
- krackers 3y agoBut aren't shellcode style exploits already fairly rare with W^X, so most end up using return-to-libc style attacks? Wouldn't CFI be a much better solution?
- monocasa 3y agoIt's defense in depth. Removing a function like syscall(2) that's a "whatever syscall you want" function that is ostensibly white listed works very well when combined with CFI, and strengthens security of systems without hardware support for CFI.
- saagarjha 3y agoOpenBSD users mostly don’t use systems with strong hardware CFI, so they make do with stuff like this.
- eikenberry 3y agoWhy aren't these changes made in kernel to keep the syscall ABI standardized and safe instead of requiring the use of an unsafe language wrapper? We should be discouraging more use of unsafe languages, not forcing it.
- kstrauser 3y agoI don't know a lot about this corner of the OS. Why are syscalls in libc, instead of something like a libsyscall? I could see why a language might want not to depend on what's at least notionally the C runtime. Is the fact that the kernel interface is in libc an accident of Unix being written in C, or is there something more fundamental there?
- monocasa 3y agoIt's that libc is considered the stable interface for userland in general on openbsd.
- kstrauser 3y agoIs that different from Linux/Mac/etc?
- masklinn 3y agoIt is not different on mac (although there libc is just a subset of the wider libSystem). It is different, uniquely so, on linux: on most unices the kernel and libc are developed as two sides of an entire system, both being updated in lockstep when the system is updated. As such there is no real concern about keeping the syscalls stable, if you need to change it on the kernel side you update it to match on the libc side and you're done, everybody is supposed to use the libc. Not so on linux, the kernel and the libc (most commonly glibc) are developed by entirely different groups which don't necessarily like or communicate with one another. As a result, on linux syscalls are a stable API, and direct syscalls are an officially supported method of interaction. In fact its sometimes necessary as the libc might decide not to expose a syscall.
- kstrauser 3y agoThanks for that. So although the name is "libc", it's more like "lib-how-to-use-the-kernel", too?
- 3y ago
- PrimeMcFly 3y ago> Piece by piece, I've been trying to remove the easiest of the terminal-actions that exploit code uses (ie. getting to execve, or performing other system calls, etc). > I recognize we can never completely remove all mechanisms they use. However, I hope I am forcing attack coders into using increasingly more complicated methods It's honestly so ridiculous an OS that claims to have security a a focus refuses to add even some sort of basic MAC/RBAC implementation. Even both OSX and Windows have had something for ages now.
- LanzVonL 3y ago[dead]
- actionfromafar 3y agoThese things are kind of orthogonal. OpenBSD maybe gets there eventually. OpenBSD is like a very hardened safe, made of steel and huge bolts and locks. Very polished, very smooth and hard surface. MAC/RBAC is like having security officers, interviews, checking of IDs, filling in forms and getting an OK from ones boss before performing work someplace in the building and so on. Both these things can be good. But OpenBSD was always about making a small system as hardened as possible. Evidently, they aren't completely done yet with making the core as hardened as possible. Windows has great architecture, but lacks instead severerly this hardness which OpenBSD possesses. What use is MAC/RBAC if someone can gain kernel access with a 0 day exploit?
- PrimeMcFly 3y ago> OpenBSD maybe gets there eventually. Nah they won't. The devs have an irrational resistance to the very idea. I disagree with your analogies. OpenBSD has a focus on auditing to remove all bugs, which is great, but they provide very little to help prevent what can be done if a bug is exploited, and they've certainly had no shortage of serious bugs. > What use is MAC/RBAC if someone can gain kernel access with a 0 day exploit? Kernel exploits are pretty rare. Most exploits are in userland.
- 3y ago
- saagarjha 3y agoWhy not remove syscall instructions altogether? When libc wants to do something, it traps on an undefined instruction and then the kernel looks at the program counter to see what it should do. Seems like this would be the ultimate application of this line of thought…
- nine_k 3y agoAre there any performance implications on such traps on x64 or ARM? IIRC, PDP11 and VAX used traps as the way to call the supervisor, and it was pretty cheap.
- monocasa 3y agoI don't think that helps much. OpenBSD already only allows syscalls originating out of the libc .text section, so whether the trap itself comes from a syscall instruction or some other trap mechanism doesn't really improve security AFAICT.
- throw2022110401 3y agoFor language runtimes that don't normally have to deal with C baggage having to drag libc into your address space and going through libc code for syscalls makes this a less secure platform.
- eikenberry 3y ago+1.. Why not create a standard/stable syscall interface instead of pushing an anachronistic libc interface.
- notaplumber1 3y agoOpenBSD developers are making a serious effort to kill off indirect syscalls, the base system is completely clean, take a look at the work Andrew Fresh did to adapt Perl. He wrote a complete syscall "dispatcher" or emulator for the Perl syscall function so that it calls the libc stubs. https://github.com/openbsd/src/commit/312e26c80be876012ae9792d4323a301329d66ae https://github.com/openbsd/src/commit/312e26c80be876012ae979... The ports tree is being cleansed of syscall(2) usage, until they're all gone. msyscall, pinsyscall, recent mandatory IBT/BTI, xonly. OpenBSD is making some waves, but people aren't really seeing them yet.
- pizlonator 3y agoA+ This is awesome. Also, it’s rarely used in my experience. I wonder what kind of code would even notice?
- actionfromafar 3y agoExploits, I guess is the concern.
- saagarjha 3y agoCode that uses syscalls that aren’t in libc but doesn’t want to have to drop to inline assembly?
- pizlonator 3y agoRight, so exploits.
- saagarjha 3y agoExploits are more than happy to drop to inline assembly.
- pizlonator 3y agoTheo already prevented you from making the syscall by using the trap instruction directly because of in kernel checking that you got to the kernel via the right point in libc.
- kazinator 3y agoIt is security theatre. The instruction pattern by which a system call is invoked is not a security attribute. You can't trust something just because it looks like a libc call.
- samus 3y agoIt's an indicator whether they instruction sequence was concerned together by an exploit or whether it's normal code execution. Attackers will have to use more complicated and brittle mechanisms to still achieve their goal. It's an arms race, but so is security in general.
- deleted 3y ago[deleted]
- kazinator 3y agoHow I would design it would be to have a system call which registers the addresses, in user space, where system calls are allowed to come from. After that, any system call not coming from an address in that list will fail. The list would be editable, but there would be an operation which seals it from further editing. With this feature, we could load a new plugin into a C program with dlopen, and it would not be able to make syscalls of its own, other than through the existing C library, no matter how prim and proper its call sequences look like. Possibly, ranges could be used instead: syscalls can originate from several registered address ranges, and that's it. Programs that create dynamic code on the fly, which can make system calls, could allocate trampolines in a registered area, for that purpose.