Hacker Newsnew | past | comments | ask | show | jobs | submit | jsdfasds's commentslogin

This is precisely why I don't link with glibc anymore.

musl has its own approach to this, it's called nscd

It would have avoided the "running code as root" part, but it would still allow an attacker to control the result of the function call.

I mean, the problem being solved here isn't exactly a bad problem to try to solve. You either permanently hard-code `/etc/passwd` as the user database, and `/etc/resolv.conf` as the source of DNS server information, or you allow these to be handled in a more complex way (thus allowing YellowPages, LDAP, or whatever you can imagine).


Obviously, if you tie the ability to handle those things to your filesystem layout, either by loading dynamic libraries from whatever is /usr/lib, or by reading /etc/whatever.conf, or even providing a whole virtual mount à la /proc, chroot'ing gives you both with the ability to override the system-wide policy for yourself (pretty reasonable for DNS lookups, kinda dubious for username lookups) and the opportunity to accidentally pwn yourself.

Frankly, sometimes I feel that on Linux, root should be restricted to executing/loading only a whitelist of executables/shared objects, identified by hash of the contents, not the file paths. But then again, you'll need a allow_for_root(1) utility to maintain this whitelist, and people absolutely will call it in their setup scripts in all kinds of dubious manner.


What alternative solution do you actually propose here?

To clarify, the kernel doesn't (well, it gets complicated with things like NFSv4 but let's just ignore that since it doesn't really make or break my point) know anything about users or groups. It _only_ has the ability to manage some integers on a per-process basis and tie those into integers attached to files.

Assuming for now that we want to keep this like that, if you want to tie names to those numbers, you have to have some kind of database. If not by reading a config file, or by running some random code, or by some virtual file system (unless I misunderstood ?), what other options do you have?

Unix sockets have the same issue. There are abstract namespace sockets, but these don't exactly help solve the core problem, since now changing the network namespace can get you in the same trouble. This also covers any other kind of socket.

Even if the kernel did have the capacity to maintain this information, something would need to load it or back it, and that something could fall afoul of similar bugs.

> root should be restricted to executing/loading only a whitelist of executables/shared objects

It should already be possible to achieve this with IMA I believe?

> But then again, you'll need a allow_for_root(1) utility to maintain this whitelist, and people absolutely will call it in their setup scripts in all kinds of dubious manner.

You'd just keep the signing keys off the machine and either sign things off the host or sign them with presence detection and an HSM.


> What alternative solution do you actually propose here?

I don't, I am just saying that if you do things like e.g. user/group name resolution outside of the kernel, then they will be done in the userspace (duh) with all of the implications (crossing the trust boundaries, and philosophical discussion on what "the system [database/service/X]" even is, etc) that come with it. Doing it in the kernel has other implications, like how Windows does its SID lookups.

> what other options do you have?

Depends on whether or not you want to have the user namespaces, and how you want things across the namespace boundaries to interact. If you want to have /etc/passwd (or a more complex apparatus) of the core system to always be in effect, with no ability to override it with e.g. chroot(2) — then you can do it, with some help from the kernel side but that's both the silly idea in itself, and the kernel folks would never agree to add a do_rpc_with_global_secured_system_service(2) to the kernel anyway.

> Even if the kernel did have the capacity to maintain this information, something would need to load it or back it

During the system startup, a daemon is launched that registers itself as a "global, secured system service" providing the "resolve user/group names" functionality with the kernel. Now everyone can interact with it with the do_rpc_with_global_secured_system_service() syscall (the kernel passes the request to this specific process and routes the replies back), and there is no way to override this interaction; this service is a global singleton. I could spend pages on writing why this is a stupid idea, and I'm sure you know them as well — but it's doable, just not in the spirit of Linux at all.

P.S. A tangent, but I am always amused when people explain that execve(2) can't do PATH lookup for its first argument because the kernel doesn't have access to the process's environment variables. Of course it has, it's the third parameter! Linux just doesn't do any name resolution in the kernel, period, there is glibc for that.


I mean, regardless of how you set this up, at some point you're going to want to namespace things. The core problem here is that chrooting creates an imperfect namespace boundary (it's not really even intended as that).

Maybe we're agreeing, I'm not quite sure. But rather than having a separate concept of mapping IDs to names, you really want a unified concept of both, so that when you namespace it, you can't namespace half of it by accident.

Moreover, you want to ideally make it impossible to only namespace it and not anything which is affected by it. e.g. the filesystem where permissions are governed by user and group IDs.

The way this is currently done is with UID/GID mapping, which unless it is a 1:1 mapping to the current user, has to be done with privileges. But this restriction is a hint that the abstraction is bad.

Really what you'd want is to have the ability to also include the concept of "file owner" in the umbrella of "user namespace", so that you can have a setup where files can have arbitrary attributes settable by a user to specify that they're owned by "root" inside the namespace but by <you> outside it.

I'd say the problem is a fundamental design issue at multiple levels of the stack, exacerbated by the need to maintain backwards compatibility.

Plan9 solves this entire problem (albeit with its own trade-offs) by unifying all abstractions in the filesystem (but nothing, of course, stops you from unifying things via some IPC/RPC/whatever protocol, the filesystem in Plan 9 is just a mount of a 9P fileserver).

You literally can't get into a situation like the one described here.


Consider applying for YC's Summer 2026 batch! Applications are open till May 4

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: