5 ms·
So that means ntdll.dll and family can never be statically linked? I guess that makes sense if the only responsibility of the dll is to expose syscalls, but do
by ninkendo 7y ago
So that means ntdll.dll and family can never be statically linked? I guess that makes sense if the only responsibility of the dll is to expose syscalls, but does ntdll expose any other functionality? Functionality that may want to be overridden by a different implementation, etc?
In the Linux world, since syscalls are exposed by libc, other non-C runtimes (for example, Go) end up needing to make system calls on their own without the libc wrappers. Is such a system just not a thing in Windows?
- slovenlyrobot 7y agoIt's exactly the same deal on OS X. There is no stable system call interface that is not the C library, and it's one of the main reasons they don't allow static linking there either
- mehrdadn 7y ago> In the Linux world, since syscalls are exposed by libc, other non-C runtimes (for example, Go) end up needing to make system calls on their own without the libc wrappers. Is such a system just not a thing in Windows? Yeah, it's not a thing. You just import functions from ntdll the same way you import from anything else. The OS program loader reads your program's import table and loads them for you. > does ntdll expose any other functionality? Functionality that may want to be overridden by a different implementation, etc? It exposes lots of other stuff (DLL loading, memory heap, etc.) that you may want to do differently, but you can hook those at runtime if you really want to. It's not as convenient as just linking another library, but on the other hand, it makes it easier to replace them at runtime instead of at compile-time -- say, if you want a shared library to override a syscall.
- jcranmer 7y ago> In the Linux world, since syscalls are exposed by libc, other non-C runtimes (for example, Go) end up needing to make system calls on their own without the libc wrappers. Is such a system just not a thing in Windows? Linux is pretty much the only operating system that considers the actual system call ABI to be stable. The BSDs and OS X all want you to use the platform libc instead to access system calls, while Windows uses kernel32.dll et al. as its stable interface.
- aaron_m04 7y ago> Linux is pretty much the only operating system that considers the actual system call ABI to be stable. What about MS-DOS? :P
- quotemstr 7y agoGo doesn't need to bypass libc on Linux. There's no technical reason to do that. Go doesn't bypass libc on other operating systems. Go going straight to the kernel is just a fashion statement, a symbol repudiation of C, not something that makes actual life better for users.
- brianpgordon 7y agoHm, I thought there was some issue with glibc not wanting to provide wrappers for certain Linux syscalls. What if the Go runtime wanted to use one of those syscalls for some reason? It seems like then it'd be forced to go straight to the kernel.
- quotemstr 7y agoYes, it'd have to bypass libc for those system calls, just like any C program would. How is that an excuse for bypassing libc for things like read(2)? No, making system call interposition harder isn't a security feature. A user who can LD_PRELOAD you can already do arbitrary things to your program.
- jart 7y agoSometimes when folks talk to the kernel, they want to know they're talking to the actual kernel. glibc by design lets random stuff on the system MiTM symbols like read (even security critical ones like getrandom) and the LGPL effectively forbids many projects from using static linking as an escape hatch. The Chrome guys had to write a whole system call library from scratch because of it. On Windows it tends to get much more intense, where dynamic symbol interposition is brought to its logical conclusion, and you've layers upon layers of antivirus hooks and spyware sitting between you and the system. There, pretty much the only thing you can do is just SSL the heck out of everything.
- dooglius 7y ago> glibc by design lets random stuff on the system MiTM symbols like read Can you elaborate on this? I'm aware of things like LD_PRELOAD, but if an adversary controls the environment, he could just change PATH to point to a rooted version of chrome anyway. That also has to do with the capabilities of the system linker, not glibc. >the LGPL effectively forbids many projects from using static linking as an escape hatch The LGPL explicitly allows static linking, that's the main difference versus the GPL.
- saagarjha 7y agoGo actually stopped making syscalls directly on macOS, since the interface is subject to change: https://golang.org/doc/go1.12 https://golang.org/doc/go1.12
- masklinn 7y ago> In the Linux world, since syscalls are exposed by libc, other non-C runtimes (for example, Go) end up needing to make system calls on their own without the libc wrappers. They didn't need to, they wanted to, and it can break at any moment on any platform other than Linux. In fact a few versions back they finally back-pedalled and started going through libSystem on OSX. > Is such a system just not a thing in Windows? It's not a thing anywhere other than Linux. Go's developers were told time and again that they were supposed to dynamically link to and go through the platform's libc on OSX and BSDs. They finally relented on OSX after Go broke multiple times during the Sierra beta, but IIRC that's not the case yet for other BSDs (I was thinking it was also the reason why Go 1.11 is required on OpenBSD 6.4, it is but not entirely: OpenBSD requires that stack memory be mapped with MAP_STACK or syscalls will terminate the calling process, so that's an artefact of Go doing userland stacks / threads rather than doing raw syscalls).