Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I like s6! One of the key differences here is that s6-sudo builds on, rather than replaces, the standard unix permissions model.

s6-sudod listens on a unix domain socket. Unix domain sockets are just files, so they have an owner, group and mode bits. The answer to "who is potentially allowed to run a differently-privileged command?" is just `ls -l /path/to.sock`.

For finer-grained access control, a unix domain socket listener can call `getpeereuid()` or `getsockopt(..., SO_PEERCRED, ...)` to learn who it's talking to. You can build powerful – but still relatively simple, and importantly, readily-inspectable – access control policy on top of these basic unix primitives. That's what s6 does. Look at how simple rule definition is. [0]

Or, you could throw all that out the window and build something much more complex and much less inspectable, which is the systemd approach. The answer to "who is potentially allowed to run a differently-privileged command?" under `run0` is to...spend the evening reading through polkit xml rules, I guess?

I realize systemd uses D-Bus, and D-Bus uses a unix domain socket. But that socket is writable by world. We're trusting polkit and complex policy xml and probably a constellation of other services to get things right after the SO_PEERCRED check.

Maybe that's fine for desktop apps, but a reminder that we're talking about sudo here.

Complexity is the enemy of security. The complexity of the systemd ecosystem broadly writ is how we get CVEs like this polkit privesc, which took 12 years to notice [1].

Addendum: it's possible to regard systemd as dangerously complex AND sudo as dangerously complex. OpenBSD as usual had the right idea with `doas`.

[0] https://skarnet.org/software/s6/s6-accessrules-cdb-from-fs.h...

[1] https://www.cvedetails.com/cve/CVE-2021-4034/



Like many other things in Unix, SO_PEERCRED and getpeereid are half-implemented hacks that should not be used for security. They both only return the uid that was used at the time of calling connect(). Meaning you have to be incredibly careful what you do when creating the socket and you cannot really pass any sockets off to other processes if you want to try to do security that way because they will still inherit the wrong credentials. Also the usual complexities apply of how to interpret that when interacting with a process in a container.

I have a pretty low opinion of s6 because of things like this, you pretty much have to create a more complex system like polkit and systemd if you want this stuff to actually work. You don't have to use XML and javascipt like polkit does but you do have to do more than what s6 is trying to do. (Also, I personally don't find the "random collection of ad-hoc text files" style they do to be any less complex than systemd, but that's a different conversation)


You do realize D-Bus also uses SO_PEERCRED right? And transitively polkit, systemd, and everything in that ecosystem.

https://gitlab.freedesktop.org/dbus/dbus/-/blob/master/dbus/...

> Meaning you have to be incredibly careful what you do when creating the socket and you cannot really pass any sockets off to other processes if you want to try to do security that way because they will still inherit the wrong credentials.

I see nothing new here beyond "handle privileged resources with care." Don't overshare. Got an open pipe to `sh` running as root? Maybe you oughtta set O_CLOEXEC on that fd before you exec and overshare with a child. Got a socket that's been peer authed? The same.

This is pretty basic unix stuff. If you stick to the basics and avoid the siren call of complexity, the security properties remain relatively easy to reason about. Most privileged resources are fds. Mind your fds.

I'm not a huge fan of sending file descriptors over sockets – maybe we agree on that part.


> Unix domain sockets are just files, so they have an owner, group and mode bits. The answer to "who is potentially allowed to run a differently-privileged command?" is just `ls -l /path/to.sock`.

Yeah, except that is not true. To quote unix(7):

       On Linux, connecting to a stream socket object requires write permission on that socket; sending
       a datagram to a datagram socket likewise requires write permission on that socket.   POSIX  does
       not make any statement about the effect of the permissions on a socket file, and on some systems
       (e.g.,  older  BSDs),  the socket permissions are ignored.  Portable programs should not rely on
       this feature for security.
So s6 just has a wide, easily exploitable security hole there. Or is not portable, contrary to its claims.


Lol okay man. Maybe if you're running FreeBSD 4.2 or HP-UX or some BSD derivative from the 90s. All unix systems from about 2000 on will honor unix domain socket permissions.




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

Search: