←back to thread

466 points CoolCold | 6 comments | | HN request time: 0.921s | source | bottom
Show context
tommiegannert ◴[] No.40215122[source]
This is playing on the difference between hoping that sudo does the right thing juggling setuid and capabilities, and having a strict IPC boundary between privilege levels.

It sounds like a great use of systemd, for those who want to use it.

replies(1): >>40222162 #
1. AshamedCaptain ◴[] No.40222162[source]
There's like 3 components involved in making setuid safe (the kernel, the dynamic loader, and your exec), and at least one of them wasn't doing its job correctly (the dynamic loader). IPC by definition involves a superset of these components.

There's no reason to think that if you can't make a simple setuid binary safe, you can make IPC safe. IPC is an order of magnitude more involved. Specially because in order to gain any effective security you need a 3 way IPC (1st level = the client, which is completely untrusted; 2nd level = the request parser, which is trusted but runs without elevated permissions; 3rd level = the actual elevator process, which must run with elevated permissions).

replies(2): >>40228672 #>>40234699 #
2. EvanCarroll ◴[] No.40228672[source]
It's not clear why the request parser would have to be trusted. I assume you're just speaking about the call to execve running in context? That's not much of a request parser. At the point that you tell `run0` to launch a shell, you're not calling the actual commands to the shell the request parser, right?

I also think the notion of an untrusted client is kind of a hashed out thing. As said in the post itself, `run0` is an interface to `systemd-run`. `systemd-run` as a client may be more _involved_ but it doesn't seem like that has any relevance to whether or not it's more secure. It's a separate layer for the insecurity. While sudo is a single process, if it was two processes it wouldn't all have to run as root. That by necessity means something that was previously running as root isn't, which makes it more secure -- not less, right?

The actual elevator process is systemd itself which already runs as init on every machine you'll have `run0`. But by nature it's always the top of the process tree, it seems like it's _less_ complex to have systemd-init the immediate parent process. There are fewer thing that can leak into or be inherited by the spawned process.

replies(1): >>40229536 #
3. AshamedCaptain ◴[] No.40229536[source]
> It's not clear why the request parser would have to be trusted [...] I assume you're just speaking about the call to execve running in context

No, I'm talking about the part which is going to parse the command line, arguments, environment, decide whether the user is allowed the elevation or not, decide which environment, file descriptors, etc. are to be passed through, etc. All of this must NOT be in the same context as the caller, as it can simply fake all these decisions. You need to handle this from a process running in another context (suid or not).

> While sudo is a single process, if it was two processes it wouldn't all have to run as root

Yes it would ? At least one of them would need to be suid for the actual execution. But the problem is that the process which was NOT suid would be running as the same user as the caller, so by the same reason as above -- you cannot trust what it does. The only thing the non-root process would be able to do is to massage the request a bit, then forward it (IPC!) to the root/suid process which you CAN trust. We are just moving the security border, and it is not clear what would be gained by it.

In this proposal, instead of a suid binary, you have a constantly running "sudod" process (or worse, pid 1), but otherwise is the same. Everything must be IPC'd to it.

> There are fewer thing that can leak into or be inherited by the spawned process.

To have this IPC complexity just because apparently we can't figure out how to do suid without inheriting anything is bonkers.

As a trade-off you now have a user-accessible IPC system with the _gazillion_ possible vulnerabilities it entails. At least before you needed root to talk to pid1..

replies(1): >>40237229 #
4. intelfx ◴[] No.40234699[source]
> There's like 3 components involved in making setuid safe (the kernel, the dynamic loader, and your exec), and at least one of them wasn't doing its job correctly (the dynamic loader). IPC by definition involves a superset of these components

Incorrect, because nowhere in the IPC dance are these components exposed to the same untrusted environment as they are with sudo.

replies(1): >>40234857 #
5. AshamedCaptain ◴[] No.40234857[source]
Yes, they are. The kernel for obvious reasons. Second, the IPC server now has to handle (and possibly pass through data) from the untrusted environment, unless you are happy with a sudo that does not even ferry stdio. Frankly, having properly working suid (the kernel does most of the job) sounds MUCH easier than having this type of APIs exposed to arbitrary users from pid1. In fact, as per Lennart's last sudo tty bug, the issue was with how sudo was exec()ing the target binary in the _target_ context (not the original context). Having sudo as a global daemon instead of a suid exec is not going to protect you against those; actually may make them worse for all I know.
6. blucaz ◴[] No.40237229{3}[source]
> As a trade-off you now have a user-accessible IPC system with the _gazillion_ possible vulnerabilities it entails. At least before you needed root to talk to pid1..

Read the linked post again. This is all already available, and always has been, since forever.