That would avoid the weird special case for SUID binaries, which looks like the sort of thing that someone is going to discover an attack on in a year or two. (And it's a special case in lots of systems, not just this one.)
That would avoid the weird special case for SUID binaries, which looks like the sort of thing that someone is going to discover an attack on in a year or two. (And it's a special case in lots of systems, not just this one.)
Those listed examples could also be could be achieved with IPC to a privileged daemon. But unfortunately not all setuid executables can be replaced that way.
The major design flaw with setuid executables is that they run in an execution environment (view of the root filesystem, Linux namespace, etc.) provided by the caller. A good explanation of this is http://maxsi.org/blog/setuid-bit-considered-harmful/
Unfortunately this is why not all setuid executables can be replaced with IPC. setuid binaries like "nsenter" allow you to run processes with a selective modification to one part of your execution environment, while still inheriting everything else unmodified. You can't achieve this with IPC to a privileged daemon because that daemon cannot inherit your current execution environment when starting new processes.
Nevertheless, getting rid of setuid is very important. Kind of baffling to me that it hasn't been done yet. The closest we've come is replacing setuid with filesystem capabilities, but those have the same fundamental design problem. I've been working on genuinely getting rid of setuid some myself. Happy to collaborate with anyone else who wants to work on this.
What if it could? An "execution environment" could be turned into some sort of kernel token object that could be passed to another process over IPC. A privileged daemon could receive one, fork(2) once, drop some privileges, and then fork(2) again, this time with the execution-environment parameter—and end up with a copy of itself running under the IPC-sender, with environment inherited from the sender but privileges inherited from the receiver (and, presumably, an address space that contains all the mappings of both parents, with the IP pointing into the receiver's code section, like a normal fork(2) would.)
One way you could do this is to heavily abuse the CRIU project. https://criu.org/Main_Page Just do the following:
1. fork
2. send a request to a privileged daemon
3. privileged daemon checkpoints your child
4. privileged daemon modifies the saved state of your child in whatever way you requested
5. privileged daemon resurrects your child (which is possible because it is privileged)
I am not really serious about this method but it is certainly a thing you could do. :)
https://lwn.net/Articles/632520/
Having CAP_SYS_ADMIN is effectively the same as running as root.
Polkit, incidentally, is another good reason to avoid all SUID binaries on your system; see CVE-2011-1485 and then CVE-2013-4288 and friends, which are all race conditions involving tricking polkit into thinking that you're root by execing a SUID binary right before it checks who you are. http://seclists.org/oss-sec/2013/q3/624
This is indisputably a security bug in polkit, but the fact that it's so non-obvious how to do the right thing (and whether the right thing is even possible) is a good reason not to tempt fate by having SUID binaries around. It's not going to be the only system that's vulnerable to this.