[systemd-devel] RFC: user session lifetimes vs. $DISPLAY

Simon McVittie simon.mcvittie at collabora.co.uk
Wed Mar 6 07:12:07 PST 2013

On 05/03/13 21:23, Lennart Poettering wrote:
> Kay actually wants to get rid of
> the session bus entirely. My own idea was to use it only for gdm to
> support the multi-seat case, where the same gdm user might need to run
> multiple gdm sessions in parallel, one for each display. However, that
> idea is definitely flawed, and it might be better to fix this for good
> and do dynamic user ids or so for this case, so that the gdm sessions
> are actually properly isolated from each other...

Is there any security benefit in having each gdm greeter run under a
different uid, or is this just working around the conflict between "no
more than one GUI per user" and "gdm needs several GUIs"?

Presumably this would need a reasonably large UID range reserved by the
sysadmin or distribution (e.g. Debian reserves uids 60000-64999 for
allocation by the base-passwd maintainer and could reserve a sub-range
in here for its gdm), and a NSS module or something that synthesizes
appropriate user information?

How does "no more than one XDG_RUNTIME_DIR per uid" interact with uid
namespaces? :-)

> And here are our options:

Terminology: do we have a good piece of jargon for the thing represented
by a login1.User and an XDG_RUNTIME_DIR?

("Login session" for a login1.Session, PAM session or equivalent seems
uncontroversial, though.)

The fact that it's dbus-daemon --session is not particularly important,
because systemd --user's dbus.service can easily run whatever it wants
to. I think the things that are important for continuity/compatibility
are that asking for DBUS_BUS_SESSION (or the equivalent in other
libraries) gets you onto a bus that isn't a privilege boundary, can be
relied on to exist at least when you're in a "normal" X11 session (via
distributions' X11 startup scripts or X11 autolaunching), and reads
services from /usr/share/dbus-1/services (which is currently a mixture
of things that want to be login-session-scoped, and things that ought to
be login1.User-scoped - mostly the latter, probably).

Approximately in order of my preference:

> 4) Introduce --user, and always redirect --session to it. This way
>    --user would be pretty much identical to --sessin, except for where
>    the socket is stored and how it is communicated.
> Approach 4 is the arguably the "cleanest one", but current gdm is
> incompatible with it.

If you're going this route, I don't think there'd be much point in
introducing dbus-daemon --user, DBUS_BUS_USER, DBUS_USER_BUS_ADDRESS and
so on, just to be aliases for the session equivalents - just say "on
systems where it is managed by systemd, the 'session bus' is actually a
per-login1.User bus" and be done with it.

In practice, the definition of the session bus is currently something
like "one per login1.Session, except when it's not". Processes in a ssh
login session can easily "join" an X11 session's bus by setting $DISPLAY
and $DBUS_SESSION_BUS_ADDRESS; processes in an X11 session can start a
new mini-session (typically for regression tests) with dbus-launch or

In a "user bus" world, it'll still be necessary for, e.g. regression
tests to start an isolated mini-environment, the same way they currently
start an isolated D-Bus session - I'd be inclined to do that by setting
the regression test's $DBUS_SESSION_BUS_ADDRESS and $XDG_RUNTIME_DIR. I
think it's OK if doing that requires you to also reset $HOME and $XDG_*
to avoid conflicts with the real home directory - regression tests have
to do that anyway, in practice - but I'm not willing to try to enforce
the letter of the XDG_RUNTIME_DIR spec if that means we can't have sane
regression tests for D-Bus services without being root.

The remaining problems with this are:

1. Finding the X11 display: patching libX11 (well, really xcb) to try
$XDG_RUNTIME_DIR/X11-display before giving up would resolve this.

2. Multiple X11 displays: if you want to say that systemd doesn't
support this then that's your prerogative, but I don't think "this is
difficult, and in practice there are bugs" necessarily implies "we
should make it architecturally impossible to ever support this".

One way to resolve the "multiple X11 displays" issue without ruling it
out forever would be to say "if you do want to support multiple X11
displays, you'll have to make your service instanced-by-display or
something" - instancing is something systemd already knows how to do.

The AT-SPI bus-starter (org.a11y.Bus.service) is one example of a D-Bus
session service that, if multiple X11 displays are supported, really
does want one instance per X11 display.

It does occur to me that if there isn't a real security boundary between
greeters, gdm could treat each greeter as a lot like the "regression
test" use-case - separate *everything*, including HOME and
XDG_RUNTIME_DIR, while keeping the same uid. Perhaps pam_systemd could
even grow an "isolate" option which does that, including resetting HOME
to a new empty (or even inaccessible) directory? I realise that
contradicts the spec for XDG_RUNTIME_DIR, but the spec for
XDG_RUNTIME_DIR only says what it does because you wrote it that way for
a reason - and AFAICS, not sharing HOME avoids that reason.

3. Remote X11. D-Bus has some level of support for being configured to
listen on TCP on a trusted network and be used with remote X11 in
conjunction with NFS home directories (it was designed back when that
was a thing, and in particular to replace KDE's DCOP, which was
transported over X11). None of the current maintainers ever use it like
this, and even Havoc doesn't really know which use-cases are meant to
work, which in practice means that whenever we change anything, someone
pops up on the mailing list complaining that we broke their pet use-case.

I think it would be reasonable to say that D-Bus without systemd
semi-supports this (and you get to keep both pieces), but if you're
doing that, you can't use systemd --user (or alternatively, you can use
it, but you have to mask dbus.socket and dbus.service, and tell it to
pass DBUS_SESSION_BUS_ADDRESS=autolaunch: to all services).

> 2) Add dbus --user, and keep it separate from --session, i.e. thus
>    confusing developers with three distinct busses.

I'd rather not. AIUI, your assertion is that "most" D-Bus services
really want to be login1.User-scoped? I don't want to go round every
D-Bus service doing s/session/user/ for no good reason.

The combination of libdbus and dbus-glib used to have a bug in which it
sometimes had separate DBusConnection instances for the "starter bus"
and session bus, even if they were really the same bus - in Telepathy,
that led to user-visible bugs involving messages arriving in "the wrong
order" and setting up a situation that should have been impossible. (I
forget which library's fault it was.) I don't want to go back there for
the session bus vs. user bus.

> 3) Same as 2) but do actually keep it separate only for the gdm case,
>    otherwise redirect --session to --user.

I don't like the sound of this one either. If having them be separate
dbus-daemons is only used for gdm and similarly odd situations, then in
practice it won't be tested, which means in practice it won't work.


More information about the systemd-devel mailing list