www.cendio.com

Bug 5950

Summary: many applications fail to start with new systemd (common dbus)
Product: ThinLinc Reporter: Pierre Ossman <ossman@cendio.se>
Component: Server OSAssignee: Pierre Ossman <ossman@cendio.se>
Status: CLOSED FIXED QA Contact: Bugzilla mail exporter <bugzilla-qa@cendio.se>
Severity: Normal    
Priority: P2 CC: hean01@cendio.se, samuel@cendio.se
Version: pre-1.0Keywords: relnotes, samuel_tester
Target Milestone: 4.10.0   
Hardware: PC   
OS: Unknown   
Acceptance Criteria:
* We should not start a new dbus if $XDG_RUNTIME_DIR/bus exists (even if $DBUS_SESSION_BUS_ADDRESS isn't set) * dbus or systemd activated user programs on older systems (lacking dbus-update-activation-environment) should get the environment from when dbus-launch was run (generally from tl-dbus-launch.sh) * dbus or systemd activated user programs should get the correct $DISPLAY and $XAUTHORITY between tl-dbus-launch.sh and tl-run-profile * dbus or systemd activated user programs started after tl-run-profile should get the same environment as the program started by tl-run-profile * Both profiles and $TLCOMMAND should get this export * The export should happen even without the help of the desktop environment * Session specific variables should not be exported ($XDG_SEAT, $XDG_SESSION_ID, $XDG_VTNR) * Variables not matching the filter rules should not be exported (see comment #20)
Bug Depends on:    
Bug Blocks: 6190    
Attachments: patch
patch

Description From cendio 2016-07-08 15:55:47
They've moved the session D-Bus in to one that is shared between all sessions
for a user. This seems to wreak havoc with Gnome that has many D-Bus activated
programs. E.g. gnome-terminal and nautilus no longer work.

This was seen on Fedora 24.

Upstream bug:

https://bugzilla.redhat.com/show_bug.cgi?id=1353953
------- Comment #1 From cendio 2016-07-08 16:09:15 -------
Hacking this in to the start of tl-dbus-launch.sh seems to solve the issue:

if [ "${DBUS_SESSION_BUS_ADDRESS}" = "unix:path=/run/user/`id -u`/bus" ]; then
    DBUS_SESSION_BUS_ADDRESS=""
fi
------- Comment #2 From cendio 2016-07-08 16:28:27 -------
An alternative approach is suggested here:

https://bugzilla.redhat.com/show_bug.cgi?id=1281675

The workaround they've come up with to fix the problem of sharing
systemd/dbus-daemon between sessions is to send it information about how env
should look like.

Looking at Fedora 24 I can see them running this when a session is started:

systemctl --user import-environment DISPLAY XAUTHORITY

if which dbus-update-activation-environment >/dev/null 2>&1; then
        dbus-update-activation-environment DISPLAY XAUTHORITY
fi

Running that in ThinLinc also fixes things.
------- Comment #3 From cendio 2016-07-11 11:00:40 -------
Note that this is currently broken even without ThinLinc so upstream may revert
this lunacy. See the upstream bug.
------- Comment #4 From cendio 2016-07-11 11:36:19 -------
See also this bug and the upstream bugs it refers to:

https://bugzilla.redhat.com/show_bug.cgi?id=1353723
------- Comment #5 From cendio 2016-08-25 10:17:08 -------
We'll have a look if this affects Ubuntu 16.04.
------- Comment #6 From cendio 2016-08-25 17:08:21 -------
(In reply to comment #5)
> We'll have a look if this affects Ubuntu 16.04.

Ubuntu 16.04 is not affected by this from what I can tell. I can use
gnome-terminals, gedits and nautilus in multiple sessions independently.
DBUS_SESSION_BUS_ADDRESS is unique across two (one local, one ThinLinc)
simultanous sessions for the same user.
------- Comment #7 From cendio 2017-02-27 15:52:48 -------
Also affects xfce. tl-notify fails to work because Xfce's notification daemon
isn't properly spawned from dbus:

> Feb 27 15:48:49 ossman.lkpg.cendio.se dbus-daemon[18959]: [session uid=1016 pid=18959] Activating via systemd: service name='org.freedesktop.Notifications' unit='xfce4-notifyd.service' requested by ':1.60' (uid=1016 pid=19709 comm="/usr/bin/python3 /bin/d-feet " label="unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023")
> Feb 27 15:48:49 ossman.lkpg.cendio.se systemd[18763]: Starting XFCE notifications service...
> Feb 27 15:48:49 ossman.lkpg.cendio.se xfce4-notifyd[19886]: Unable to init server: Could not connect: Connection refused
> Feb 27 15:48:49 ossman.lkpg.cendio.se xfce4-notifyd[19886]: cannot open display: 
> Feb 27 15:48:49 ossman.lkpg.cendio.se systemd[18763]: xfce4-notifyd.service: Main process exited, code=exited, status=1/FAILURE
> Feb 27 15:48:49 ossman.lkpg.cendio.se systemd[18763]: Failed to start XFCE notifications service.
> Feb 27 15:48:49 ossman.lkpg.cendio.se systemd[18763]: xfce4-notifyd.service: Unit entered failed state.
> Feb 27 15:48:49 ossman.lkpg.cendio.se systemd[18763]: xfce4-notifyd.service: Failed with result 'exit-code'.
> Feb 27 15:50:49 ossman.lkpg.cendio.se dbus-daemon[18959]: [session uid=1016 pid=18959] Failed to activate service 'org.freedesktop.Notifications': timed out (service_start_timeout=120000ms)
------- Comment #8 From cendio 2017-02-27 16:08:34 -------
Filed a new bug for xfce:

https://bugzilla.redhat.com/show_bug.cgi?id=1427197
------- Comment #9 From cendio 2017-03-09 15:18:41 -------
Ubuntu is now affected, see bug 6190.
------- Comment #10 From cendio 2017-08-02 09:50:55 -------
Also affects OpenSUSE.
------- Comment #13 From cendio 2018-05-09 13:54:53 -------
Reopening for discussion.
------- Comment #15 From cendio 2018-07-02 10:56:27 -------
It seems like things are converging on the following pattern:

 - Update DISPLAY and XAUTHORITY in dbus/systemd early in the session startup

 - Update *everything* just before starting the desktop environment

Fedora assumes the latter is done by the DE:s themselves, which is true in some
cases (dont in gnome-session, startkde). But it isn't true in every case
(unity, xfce, gnome-flashback). Ubuntu has therefore put it in the general
session startup.

It is also crucial that the XDG environment variables (e.g. DESKTOP_SESSION)
are pushed to dbus/systemd. We set these up in tl-run-profile, which means we
cannot update the environment properly before that.
------- Comment #16 From cendio 2018-07-02 13:07:20 -------
Created an attachment (id=876) [details]
patch

Suggested patch that does the above.
------- Comment #17 From cendio 2018-07-04 15:41:08 -------
Created an attachment (id=879) [details]
patch

Updated patch that adds filtering of the environment pushed. systemd doesn't
accept everything and will discard the entire request if it gets anything it
doesn't like.
------- Comment #18 From cendio 2018-10-01 16:26:41 -------
A more detailed check of distributions:

RHEL 7
------

Does not have a shared d-bus. Has no scripts updating the environment. Does
have dbus-update-activation-environment though.

(has a shared XDG_RUNTIME_DIR though)

Fedora 28
---------

Shared d-bus. Updates DISPLAY and XAUTHORITY via
/etc/X11/xinit/xinitrc.d/50-xinput.sh. This file comes from the upstream
systemd. No system-wide update of the entire environment.

SLES 15
-------

Same as Fedora.

Ubuntu 18.04
------------

Shared d-bus. Updates DISPLAY and XAUTHORITY via their own
/etc/X11/Xsession.d/20dbus_xdg-runtime then updates the rest via
/etc/X11/Xsession.d/95dbus_update-activation-env. They do not have any
filtering so I'm not sure how they deal with systemd not accepting some things.

(Ubuntu is also paranoid about DBUS_SESSION_BUS_ADDRESS not being explicitly
set, but I cannot see why. There are scripts that checks for the bus at the
standard path and updates DBUS_SESSION_BUS_ADDRESS.)

Arch Linux
----------

I could not get a full system up and running, so a bit unsure. I could find
them shipping /etc/X11/xinit/xinitrc.d/50-xinput.sh from systemd, but I could
not find a script that would update the rest of the environment.
------- Comment #19 From cendio 2018-10-02 10:10:29 -------
(In reply to comment #18)
> (Ubuntu is also paranoid about DBUS_SESSION_BUS_ADDRESS not being explicitly
> set, but I cannot see why. There are scripts that checks for the bus at the
> standard path and updates DBUS_SESSION_BUS_ADDRESS.)
> 

Alright, so I found some more info on this. I have this quote from Debian:

> For example,
> the dbus-user-session package changes $DBUS_SESSION_BUS_ADDRESS from
> "essential for normal use" to "only needed for backwards compatibility",

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=815503

Digging further in to the packaging reveals this upstream commit:

https://cgit.freedesktop.org/dbus/dbus/commit/bus/systemd-user/dbus.socket.in?id=98e4499240050ea3b41951fda0c06b863b89b152

And this discussion:

https://github.com/systemd/systemd/issues/1600

What I can tell from that discussion is essentially that
$DBUS_SESSION_BUS_ADDRESS is considered legacy and will eventually be removed.
However systemd/dbus seems to take on the responsibility of setting it until
then. So we don't have to "fix" it. But we also shouldn't write code that
depends on it. Our scripts currently do that though, so they need to be
tweaked.
------- Comment #20 From cendio 2018-10-02 10:50:07 -------
(In reply to comment #17)
> 
> Updated patch that adds filtering of the environment pushed. systemd doesn't
> accept everything and will discard the entire request if it gets anything it
> doesn't like.

The filter rules are:

 * Must be valid UTF-8
 * The name must only contain [A-Za-z0-9_]
 * The name cannot start with a number
 * The value cannot contain control characters (0x00-0x1f and 0x7f), except for
the standard whitespace characters ([ \t\r\n\v\f])

No idea for the origin of these specific rules but it is what systemd and
gnome-session implements. The reason for the filter is to prevent attacks like
ShellShock.
------- Comment #21 From cendio 2018-10-02 11:14:25 -------
Hmm.... The Debian discussion highlights another existing problem with our
current approach:

On older systems (without dbus-update-activation-environment), anything started
by dbus will get the environment active when dbus-launch is called. For us that
means that most of what is sent in xstartup.d, and by tl-run-profile, will be
missing.

Debian tries to launch dbus last, but apparently they have issues with that
approach as well as dbus is then launched implicitly (multiple times even) by
programs needing it.


I think we'll stick with the existing approach for older systems. It seems to
have worked well in practice so let's not rock the boat.
------- Comment #29 From cendio 2018-10-03 15:34:22 -------
Seems to work fine. Mostly tested on Ubuntu 18.04.

> * We should not start a new dbus if $XDG_RUNTIME_DIR/bus exists (even if $DBUS_SESSION_BUS_ADDRESS isn't set)

Yup. Added a script that unset $DBUS_SESSION_BUS_ADDRESS, and we still detected
things properly.

> * dbus or systemd activated user programs on older systems (lacking dbus-update-activation-environment) should get the environment from when dbus-launch was run (generally from tl-dbus-launch.sh)

Yup. Tested on RHEL 6. gconfd is D-Bus activated AFAICT, and it has $DISPLAY
but not $DESKTOP_SESSION.

> * dbus or systemd activated user programs should get the correct $DISPLAY and $XAUTHORITY between tl-dbus-launch.sh and tl-run-profile

Yup. Started gnome-terminal whilst the profile chooser was open, and
gnome-terminal-server had the correct $DISPLAY.

> * dbus or systemd activated user programs started after tl-run-profile should get the same environment as the program started by tl-run-profile

Yup. I can see late additions like $DESKTOP_SESSION set.

>   * Both profiles and $TLCOMMAND should get this export

Yup.

>   * The export should happen even without the help of the desktop environment

Yup. Tested with the xterm profile.

>   * Session specific variables should not be exported ($XDG_SEAT, $XDG_SESSION_ID, $XDG_VTNR)

I can't see any of them exported, even though $XDG_SESSION_ID is in the
session.

>   * Variables not matching the filter rules should not be exported (see comment #20)

Bash has the same filters for variable names, so I could not test those. The
other ones are correctly filtered though, and the code looks fine for filtering
the names as well.
------- Comment #30 From cendio 2018-10-15 15:50:29 -------
I mainly used Ubuntu 18.04 to test this new mechanism. I used the following
command to compare the environment variables for processes started under the
user bus:

 cat /proc/<PID>/environ | tr '\0' '\n'

I also tested CentOS 7, which has dbus-update-activate-environment, but no
shared user bus. It worked well.

> * We should not start a new dbus if $XDG_RUNTIME_DIR/bus exists (even if $DBUS_SESSION_BUS_ADDRESS isn't set)

Works.

> * dbus or systemd activated user programs on older systems (lacking dbus-update-activation-environment) should get the environment from when dbus-launch was run (generally from tl-dbus-launch.sh)

Works. I also briefly verified that things still work on CentOS 6 (no
dbus-update-activate-environment) and that can't see anything suspicious in the
logs.

> * dbus or systemd activated user programs should get the correct $DISPLAY and $XAUTHORITY between tl-dbus-launch.sh and tl-run-profile

Looks good.

> * dbus or systemd activated user programs started after tl-run-profile should get the same environment as the program started by tl-run-profile

Check.

> * Both profiles and $TLCOMMAND should get this export

Yep.

> * The export should happen even without the help of the desktop environment

Even if I start an xterm profile I can see the full list of environment
variables.

> * Session specific variables should not be exported ($XDG_SEAT, $XDG_SESSION_ID, $XDG_VTNR)

Comparing env between xterm and a gnome-terminal started through said xterm
shows that they have different XDG_SESSION_IDs, and the xterm process didn't
have any XDG_SEAT or XDG_VTNR. To me this seems to indicate that no export
happened.

> * Variables not matching the filter rules should not be exported (see comment #20)

Couldn't properly test this, but none of the variables exported did include
such characters.


All in all, this looks good. Closing.