User: Password:
Subscribe / Log in / New account

Removing setuid

Removing setuid

Posted Nov 23, 2010 18:59 UTC (Tue) by talex (subscriber, #19139)
Parent article: Ghosts of Unix past, part 4: High-maintenance designs

I wonder how hard it would be to eliminate setuid (including POSIX capabilities) entirely?

[ find -perm 4000 ... ]

Looks like most setuid binaries could be replaced by services (e.g. over D-BUS), running in an environment that is known and trusted. e.g. chsh, ping, mount (for cases where setuid is used), passwd, at.

su and sudo could be replaced by ssh (or telnet) localhost.

I'm not quite sure why chromium-browser-sandbox needs to be setuid, but presumably a slightly improved seccomp mode would fix that.

Is there anything that really needs to be setuid?

(Log in to post comments)

Removing setuid

Posted Nov 23, 2010 19:09 UTC (Tue) by Yorick (subscriber, #19241) [Link]

The most important user of setuid that I can think of is Nethack. It would have to run as a daemon (&).

Removing setuid

Posted Nov 23, 2010 22:09 UTC (Tue) by nix (subscriber, #2304) [Link]

& itself being one of the sickest in-jokes in nethack (which has almost too many, if that were possible).

Removing setuid

Posted Nov 24, 2010 13:18 UTC (Wed) by nye (guest, #51576) [Link]

I...never got that joke until just now.

Removing setuid

Posted Dec 1, 2010 3:30 UTC (Wed) by baldridgeec (guest, #55283) [Link]

Don't feel bad, I didn't either (even though MAIL is defined on my build!)

Removing setuid

Posted Nov 23, 2010 19:50 UTC (Tue) by zlynx (subscriber, #2285) [Link]

The sandbox is actually setuid to a lower permission level. Not what you usually see, but useful.

Removing setuid

Posted Nov 29, 2010 14:06 UTC (Mon) by talex (subscriber, #19139) [Link]

Needing to privileges to drop privileges seems quite a common problem with Linux. Unfortunately, patches to solve this problem may themselves cause more problems... by interfering with SetUID binaries:

Removing setuid

Posted Nov 23, 2010 19:56 UTC (Tue) by vonbrand (guest, #4458) [Link]

Whatever you do, the result will still be some kind of membrane that separates (but connects) two domains with different privileges. Everything that goes through it will have to be checked. Sure, there are other ways to handle this; the real question is which is the hardest to foobar...

Removing setuid

Posted Nov 29, 2010 14:36 UTC (Mon) by talex (subscriber, #19139) [Link]

OK. In the case of services, the membrane is needed only for the socket over which the user sends their messages, which hopefully the programmer is already thinking about from a security PoV.

In the case of SetUID, the membrane includes quite a lot of things the programmer probably didn't think about, besides the program's arguments, including the inherited:

* environment variables
* file descriptors (e.g. close(1); exec(setuid))
* the current directory (which may be writeable/moveable by the user)
* ulimits
* umask
* POSIX capabilities?

(those are the ones I can think of; I'm sure there are more)

Removing setuid

Posted Nov 23, 2010 23:57 UTC (Tue) by cjwatson (subscriber, #7322) [Link]

It would be nice to have a replacement for the somewhat niche use of set-id to prevent a process being ptraced. ssh-agent (at least in Debian - I don't recall the upstream setup right now) is setgid to a single-purpose group, and drops that privilege on startup, purely to prevent an attacker ptracing the agent and extract cleartext keys. It helps to have this in the filesystem so that there's no vulnerable window at startup.

(Yes, if the compromise is long-term then the attacker can just install a keylogger and wait, but sometimes attackers only have a short window of opportunity and it doesn't hurt to make them work harder.)

Removing setuid

Posted Nov 25, 2010 18:13 UTC (Thu) by talex (subscriber, #19139) [Link]

That's an interesting example.

As you say, the current situation isn't great anyway. I wonder how Capsicum deals with tracing? I assume that you'd need to have a process descriptor to ptrace a process, so by default you'd only be able to trace your children.

If a process wanted to trace something else, it would have to ask a service (e.g your session manager) for a handle to the target. The session manager could refuse to hand over the handle to the ssh-agent process (or some stricter policy, like always confirming with the user).

Removing setuid

Posted Nov 26, 2010 14:35 UTC (Fri) by Yorick (subscriber, #19241) [Link]

For a capability-based system, I would imagine tracing the user's own processes to be a question for his powerbox. I don't remember if the Capsicum papers discuss the design of a powerbox to go with the rest of the system.

Removing setuid

Posted Nov 27, 2010 2:28 UTC (Sat) by skissane (subscriber, #38675) [Link]

I think we can distinguish two uses of setuid:
- start a non-privileged process, at login, or when init starts a service
- as a deputy to enable a lesser privileged user to do some task

To start the non-privileged process, I would suggest the ideal would be something like spawnas(), which only root can call, and specifies the non-root user to start the process as. (I have never liked fork/exec, because it is too easy to accidentally pass stuff to the child process from the parent when one didn't mean to. I would prefer spawn, with explicit specification of desired child process state, by use of some extensible data structure. Fork is dumb, because copy-on-write is the rare case, the common is fork-exec which is equivalent to spawn. And with multiple threads, who ever really needs fork anyway?)

Then, all the deputy uses can just become daemons accessible over some local domain socket or some RPC/LPC protocol (maybe implemented on top of that). Maybe with the ability to pass file descriptors/handles from the daemon back to its unprivileged caller... There should be some security checking, over what handles it can pass. (Permissions on objects could by default be non-delegable, unable to be passed to another process -- an extra permission, e.g. "read" vs "delegate read", could be needed to pass the handle to another process...)

Removing setuid

Posted Nov 30, 2010 10:27 UTC (Tue) by mpr22 (subscriber, #60784) [Link]

Personally, I'd rather write if (!(child = fork())) { do_stuff(); execve(foo, bar, baz); } than ram_stuff_into_structure(&foo); child = spawn(&foo); } because the former allows me to do arbitrary stuff between fork and exec, while the latter only allows me to do things the library / kernel designers have foreseen.

As for "And with multiple threads, who ever really needs fork anyway?", how about "anyone who wants to get a useful program-readable error indication when the activity that's just been kicked off corrupts its heap, rather than having the whole kit and kaboodle come crashing down with a SEGV"?

Copyright © 2017, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds