set user id for service ?
david at fubar.dk
Fri Sep 15 01:57:02 PDT 2006
On Thu, 2006-09-14 at 21:29 -0400, Havoc Pennington wrote:
> Not clear to me that having a random custom bus running as root that
> starts services using a mechanism designed for desktop user sessions is
> particularly elegant either ;-) in fact I have no real idea why this
> would be a sensible way to implement anything, though I'm willing to
> admit it might be, someone would have to step back and explain the whole
> problem and possible alternatives and what the dbus feature would be
> like, how it would work, how it's more secure than existing approaches, etc.
OK, I'll give it a shot. First, see pages 24 - 52 of
for a detailed explanation of why this is important. Sorry about just
pointing you to a presentation but it sums up what I think - the
alternative would be several badly written paragraphs saying the same
thing. Let me know if I need to elaborate.
Second, your comment about making the bus run as root in order to do
this is not accurate. One (classic?) approach is to make dbus-daemon
start a helper early (e.g. before it drop privileges) and have a private
channel (pipe, socket, D-BUS, whatever) to talk to said helper. Then you
dbus-daemon (running as uid messagebus)
| communications channel
dbus-daemon-helper (runner as uid 0)
You'd then use the privileged helper for activation. You want an
extremely simple interface, e.g. perhaps just Helper.ActivateService (IN
string name) and the helper would parse the configuration files, fork,
change uid to the appropriate uid/gid and then exec the appropriate
The reason you want a simple interface is that you want the helper to be
as little code as possible so it's easier to audit.
You need the configuration file parsing, though - the trust model would
be that the helper would be that the helper would assume that the bus
daemon would be compromised. As such, an interface like Helper.RunBinary
(IN string path, IN int uid) would be broken.
Also, you probably don't want to pull in libdbus and I don't think you
need it either given the simple interface.
For the record, this is exactly what we do in HAL to make most of the
code run unprivileged.
Why is this better than just doing what Thiago proposes, e.g. just put
your the setuid'ed binary into a 500 messagebus-owner directory? Because
1. While setuid can be useful and secure it's generally frowned upon
2. It makes packaging harder.. and easier to screw up
Surely people will argue 1. and 2. is less important. The important one
for me however is,
3. assume the bus daemon is compromised. Now it can suddenly execute
a lot of services and exploit one of those to gain privileges.
Of course, this would require a security hole in one of those
services (the attack would include tampering with arguments
passed or the environment etc. etc.), but basically it extends the
trust model to include these.
If you use a privileged helper, at least the bus daemon cannot do
this if compromised. Clearly this requires you to trust the
privileged helper but that should be OK - it will be a lot less code
than the bus daemon itself. Hence, the amount of code needed to
audit to avoid a root exploit is substantially smaller.
To summarize, with setuid you have a root exploit when
- the bus daemon is compromised
- any service that can be activated as root is compromised
With the helper you have a root exploit only if the bus daemon
and the helper is compromised.
To me this is much safer. Of course, most people's trust model assumes
the bus daemon is secure, but if we (the D-Bus developers) starts
telling people to use setuid binaries... then this might change this
perception (for better or worse) as such practices are generally frowned
So... is this adequate enough to justify what the original poster
requested? E.g. a field in the .service file for specifying what uid to
launch the service on the system bus as? In other words, will you accept
patches for this?
More information about the dbus