dbus setting $HOME

Simon McVittie smcv at collabora.com
Wed Aug 21 12:09:26 UTC 2019


On Wed, 21 Aug 2019 at 15:32:30 +0930, Simon Lees wrote:
> We have a long standing bug [1] where curl reads the wrong config file when
> called from packagekit when started by dbus. Given that this bug is rather
> old and no one else has been complaining before doing anything about it I
> thought I'd check if this sounds like a vaild dbus bug, or whether
> applications started through dbus should be setting this up themselves.

You appear to be talking about system services started by
`dbus-daemon --system` (the other possibility would be session/user
services started by `dbus-daemon --session`, which will inherit HOME
from their parent process on any non-pathological Unix OS).

There are two ways in which a D-Bus system services can be
started. Systems with systemd as pid 1 can do either, and in practice will
usually have a mixture, with some system services started by traditional
activation, and other system services started by systemd activation.
Systems with a different pid 1 can only do traditional activation.

* Traditional activation:
    * Whatever init implementation you are using (systemd or sysv-rc or
      Upstart or something else) starts `dbus-daemon --system`
    * `dbus-daemon --system` starts the setuid *activation helper*,
      `dbus-daemon-launch-helper`, as a direct child process
    * `dbus-daemon-launch-helper` does some checks, then execs a
      system service (like PackageKit in your case)
* systemd activation:
    * systemd starts `dbus-daemon --system`
    * `dbus-daemon --system` asks systemd to start a system service
      (like PackageKit in your case) using a D-Bus message
    * systemd starts the system service itself, the same way it would
      have started it if it had been configured to start during boot

In the systemd activation code path, dbus does not control whether the
system service gets HOME in its environment or not: it is completely
systemd's decision, exactly the same as if the system service had been
started during system boot. If you think systemd is doing the wrong
thing then you will need to talk to the systemd maintainers about it.
In the version I'm running, it appears that it sets $HOME, $LOGNAME
and $USER if and only if the systemd unit has a non-root User specified
(for example systemd-logind does not get those, but colord does).

In the traditional activation code path, neither `dbus-daemon --system`
nor `dbus-daemon-launch-helper` adds HOME to its own environment,
and even if the init system ran `dbus-daemon --system` with HOME set,
`dbus-daemon-launch-helper` will remove it (because it is setuid and
does not necessarily trust its caller, so it clears all environment
variables). As a result, traditional D-Bus system services have always run
with very minimal environment variables: they have $DBUS_STARTER_ADDRESS,
$DBUS_STARTER_BUS_TYPE, and that's all. In particular there is no $HOME,
no $PATH (!), no $USER and no $LOGNAME.

It would make sense to review what systemd does (and whether it caused any
regressions when it changed in the past), and what other init systems do,
before making any changes.

A home directory does not necessarily make much sense for system services:
even if the system service is running as uid 0, it is uid 0 in its role
as the owner of critical system services, not uid 0 in its role as a user
that you can log in as. If you modify configuration in /root, there's
an argument for wanting that to affect system services that happen to
run as uid 0, but also a valid argument for *not* wanting it to affect
system services whose assumptions might be broken by configuration that
was intended for root-as-interactive-user. So this is a balancing act.
Similarly, the home directory of non-uid-0 system services typically
either doesn't exist, or is some sort of data directory: it often doesn't
have the structure that would be expected for the home directory of a
user that can log in interactively, and isn't necessarily even owned by
the user whose home it is.

Given that dbus has had its current behaviour for more than a decade,
I'd be tempted to say that traditional activation gives system services
a minimal environment, that's just the way it is, the risks of changing
it outweigh the benefits, and if a system service wants to have more in
its environment, it should set that up itself at the beginning of main().

However, if there is consensus that system services should have
more environment variables set and the benefits outweigh the risks,
then the place to change it would be dbus-daemon-launch-helper
(bus/activation-helper.c, probably in switch_user()). If it sets HOME
then it should probably also set USER and LOGNAME.

I think I specifically don't want dbus to get into the business of setting
PATH and LANGUAGE for system services like systemd does, because the
correct defaults are operating-system-specific. Knowing what should
be in them on this particular OS is part of systemd's job, but it is not
really dbus' job.

    smcv


More information about the dbus mailing list