Support dbus runtime relocation

Bug #1633520 reported by Michael Terry
12
This bug affects 2 people
Affects Status Importance Assigned to Milestone
D-Bus
Unknown
Wishlist
dbus (Ubuntu)
Confirmed
Undecided
Unassigned
snapd (Ubuntu)
Confirmed
Undecided
Unassigned

Bug Description

For example, when running in a snap.

I ran into this while testing a unity8 desktop session snap. Session services were being dbus-activated, but dbus was running the hardcoded paths in the session desktop files. Which weren't pointed into the snap.

DBus has support for relocating those paths, but it only does so on Windows.

I've added a patch to support $DBUS_ROOT on Unix and relocate paths as needed. I've linked the upstream bug here. We may want to consider patching Ubuntu while we wait for it to land upstream.

I've attached the patch here too.

Tags: patch
Revision history for this message
In , Michael Terry (michael-terry) wrote :

Created attachment 127303
proposed patch

It would be nice if DBus added support for a runtime relocatable root in Unix. i.e. at runtime, be able to be run from /opt/dbus/ or some such, without having that be a compile-time prefix.

I notice the Windows version has some basic support for this. Detecting its installation directory and treating paths as relative to that.

My specific use case is testing a snap [1] of a full desktop environment. This bundled in dbus and session services and all sorts of things. The session DBus was trying to activate services with their compile-time hardcoded paths and not finding them.

And I bet similar use cases exist.

The plumbing already exists to fix those paths up, thanks to the Windows support.

So I threw together a patch for the Unix side of things, to listen to the new variable DBUS_ROOT. If you prefer a different env name, let me know.

[1] http://snapcraft.io/

Revision history for this message
Michael Terry (mterry) wrote :
description: updated
tags: added: patch
Revision history for this message
In , Simon McVittie (smcv) wrote :

(In reply to Michael Terry from comment #0)
> So I threw together a patch for the Unix side of things, to listen to the
> new variable DBUS_ROOT.

libdbus and dbus-daemon are security-sensitive code, and in some configurations the environment is attacker-controlled. Please don't rush into this.

Revision history for this message
In , Simon McVittie (smcv) wrote :

Comment on attachment 127303
proposed patch

Review of attachment 127303:
-----------------------------------------------------------------

For the session bus, it would seem reasonable to search XDG_DATA_DIRS according to the basedir spec (<https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.html>). I'd rather do that than invent a new environment variable.

I'm somewhat sceptical about the correctness of a Snap app-container running its own dbus-daemon - a contained app doesn't sound a lot like a login session to me (<https://dbus.freedesktop.org/doc/dbus-specification.html#message-bus-types>), and this is pretty much the opposite of the direction that the "user-session" work has gone in (<https://lists.freedesktop.org/archives/systemd-devel/2015-January/027711.html>).

However, relocating a dbus-daemon with XDG_DATA_DIRS seems potentially useful for regression testing or whatever (which is also the intended purpose of most of the environment variables that Snap app-containers (ab)use to pretend to be a namespace, AIUI).

---

What is your use case for relocating the system bus?

The system bus is a bus for the system. Running a separate system bus in a container seems deeply inappropriate, unless the container is as close to whole-system as things like lxc and Docker, in which case the chroot-like environment will do the right thing anyway.

Revision history for this message
In , Simon McVittie (smcv) wrote :

(In reply to Simon McVittie from comment #2)
> For the session bus, it would seem reasonable to search XDG_DATA_DIRS
> according to the basedir spec
> (<https://specifications.freedesktop.org/basedir-spec/basedir-spec-latest.
> html>). I'd rather do that than invent a new environment variable.

What I mean here is: take the logic we use for <standard_session_servicedirs/>, which I assume you're basically happy with because you don't seem to have patched it, and apply it to finding ${datadir}/dbus-1/session.conf (taking the first one and ignoring any that it "shadows" seems reasonable).

We implement <standard_session_servicedirs/> by behaving as though our compile-time @DATADIR@ had been appended to XDG_DATA_DIRS; the same would make sense for ${datadir}/dbus-1/session.conf.

Revision history for this message
In , Michael Terry (michael-terry) wrote :

Thank you for looking at this!

> Please don't rush into this.

Agreed. I wanted to check with you folks before I actually did anything on the Ubuntu side.

> What is your use case for relocating the system bus?

I don't have one. I was just trying to be consistent with the other changes. I'm happy to drop those bits.

> I'm somewhat sceptical about the correctness of a Snap app-container running its own dbus-daemon - a contained app doesn't sound a lot like a login session to me

In most cases, yes, that wouldn't be a normal thing to do. But this is a bit of a special "fat" snap for an entire desktop environment (unity8 is what I'm testing now, but I don't see why one couldn't also snap up a GNOME or KDE session).

> We implement <standard_session_servicedirs/> by behaving as though our compile-time @DATADIR@ had been appended to XDG_DATA_DIRS; the same would make sense for ${datadir}/dbus-1/session.conf.

So the serviceconf-discovery aspects of my patch were merely me trying to make the Unix side of things be consistent with what the Windows side of things does, now that _dbus_replace_install_prefix was no longer a no-op.

But adjusting XDG_DATA_DIRS is enough for my purposes there. My major goal with this patch was actually to make relocating of activated services work. I think I buried that lede.

In activation.c, _dbus_replace_install_prefix is called on the Exec= line found in the service desktop file.

Consider this snap I'm trying to make, with session dbus and installed session services. One such service might have an Exec line like Exec=/usr/bin/foo-bar. When DBus wants to activate that service, it needs to adjust that Exec line based on where my snap is installed, which is only known at run time. And that's where setting DBUS_ROOT would come in for me.

So my patch to _dbus_replace_install_prefix is what really interests me and I can take or leave my other changes.

Would a patch to just that function be better received, and leave the config-file searching functions alone?

Revision history for this message
In , Simon McVittie (smcv) wrote :

(In reply to Michael Terry from comment #4)
> Consider this snap I'm trying to make, with session dbus and installed
> session services. One such service might have an Exec line like
> Exec=/usr/bin/foo-bar. When DBus wants to activate that service, it needs
> to adjust that Exec line based on where my snap is installed, which is only
> known at run time. And that's where setting DBUS_ROOT would come in for me.

I am really not comfortable with rewriting absolute paths to mean something that isn't actually what they say - I feel as though an absolute path should lead to "you asked for it, you got it", with anything else being a violation of the least-astonishment principle. I wasn't a D-Bus maintainer at the time the Windows install-prefix-rewriting was implemented, so I've tolerated what we already had; but I'm not a fan of it extending its tentacles outside the Windows special case, and I'd like to be able to replace it with something less astonishing.

We have had efforts in the past to make D-Bus .service files relocatable in a less astonishing way, by interpreting *relative* Exec paths (which currently have no useful meaning) as relative to something (the original suggestion was dbus-daemon's $prefix, but "where I found the service file" seems better). However, I think it would also be a least-astonishment problem if a relative Exec didn't mean the same thing as it does in .desktop files, its meaning is currently undefined in .desktop files, and when I raised the equivalent question for .desktop files the conversation descended into disagreements about how the relative path should be resolved in corner cases (if you symlink a desktop file between directories, or worse, copy/symlink it to your ~/Desktop and double-click on it).

Relative paths in .desktop files also seem like something you will need for this current effort in Snap; it would be helpful to try to get some sort of consensus there. Latest attempt: <https://lists.freedesktop.org/archives/xdg/2016-June/013754.html>

I am not a huge fan of Snap's approach to relocation in general: the way Flatpak does this, with userns + bind mounts so the path really exists at least in the container's view of the filesystem, seems a lot more honest to me.

Revision history for this message
In , Michael Terry (michael-terry) wrote :

> I am really not comfortable with rewriting absolute paths to mean something that isn't actually what they say

I'm sympathetic to that position. But

A) A data file like a dbus service file simply cannot specify a full path, if its proper path is only known at run time. Which is the case for snaps, and maybe other use cases too(?).

B) In some cases, the administrator knows more about how they've set up the environment than the service author *can* know. The administrator can edit the file, sure. But an environment variable is often an easier approach for them (at least if all the administrator has done is moved its root).

For the work I'm doing, I can hack my snap to use relative paths in its bundled dbus service files (chop off their '/' prefix) and run dbus-daemon --session with a cwd of the snap root directory. That would let me use dbus's existing relative-dir support in my favor. For as long as dbus still supports that way, at least.

So I can hack it. But I was hoping for a cleaner way of doing that in a systematic way (and maybe help people doing similar things that don't have the luxury of being able to do the hack I can).

> ... with anything else being a violation of the least-astonishment principle.

I understand that what the Windows side is doing may be a bit surprising. Since that check is always on.

But with this patch, the relocation support is opt-in by setting DBUS_ROOT. In which case, the relocation would be quite expected. Maybe it would be even less likely to surprise if it was a command line argument?

> Relative paths in .desktop files also seem like something you will need

I don't *think* I'll actually need that. I'm snapping unity8, and for .desktop based application launches, it has code to prefix the correct root directory onto the Exec line (since it reads those and knows when it's running as a snap).

Revision history for this message
In , Simon McVittie (smcv) wrote :

(In reply to Michael Terry from comment #6)
> A) A data file like a dbus service file simply cannot specify a full path,
> if its proper path is only known at run time.

I'm not disputing that - but in that situation, I really don't think it's right to specify a full path that gets rewritten internally to mean something other than what it says.

Hence the various suggestions on the .desktop file thread: paths relative to the .desktop file (or in this case the .service file), or paths relative to the loading executable's $prefix, or paths that start with some magic token. https://lists.freedesktop.org/archives/xdg/2016-June/013754.html explains those options in more detail, and explains why my preferred one of those is relative to the .desktop file.

If this is something that Canonical has a need for, please try to push the .desktop file discussion towards some sort of consensus (which might be as simple as writing detailed pseudocode for what relative paths should mean and justifying why that meaning was chosen), so that we can make relative paths in .service files do the same thing as relative paths in .desktop files. There was at least one Canonical developer (desrt) already involved in the thread I linked.

I'm afraid I don't have the mental bandwidth to reach that consensus myself - other things that I'm working on are more important to me. If reaching that consensus is more important to you than it is to me, please help.

(In reply to Michael Terry from comment #6)
> For the work I'm doing, I can hack my snap to use relative paths in its
> bundled dbus service files (chop off their '/' prefix) and run dbus-daemon
> --session with a cwd of the snap root directory. That would let me use
> dbus's existing relative-dir support in my favor. For as long as dbus still
> supports that way, at least.

To be clear, I consider this resolution of relative paths to be an accident, not a feature: it's a side-effect of how the service-spawning code is implemented. When we reach a consensus on what more useful thing should be meant by relative paths, it will change.

Revision history for this message
Alberto Mardegan (mardy) wrote :

Hi Micheal, I also just stumbled on this problem. :-)

I wonder if this could be solved in a very different way, which does not involve any changes to dbus-daemon. I've seen that for bug 1590679 we are moving to a solution [1] in which the snap providing the D-Bus service would declare an interface slot.

Could snapd be so smart to copy the .service file into /usr/share/dbus/services/ when the interface gets connected, and unlink it when it gets disconnected?

Or, if the proposed merge gets changes in such a way that the snap declares a plug (rather than a slot), we might be able to use the upcoming interface hooks so that the (privileged) snap providing the slot would register interface hook that perform the linking/unlinking of the .service files.

Opinions?

[1] https://github.com/snapcore/snapd/pull/1613

Revision history for this message
Jamie Strandboge (jdstrand) wrote :

"Could snapd be so smart to copy the .service file into /usr/share/dbus/services/ when the interface gets connected, and unlink it when it gets disconnected?"

Yes it could and that sounds like a reasonable approach if it is properly designed, but I think that is a different problem than what PR #1613 is trying to solve. I mention "properly designed" because "when the interface gets connected" would have to be expressed as a plug so that it could be connected/disconnected and as such, likely a different interface, such as 'dbus-activation-support' or something.

Revision history for this message
Alberto Mardegan (mardy) wrote :

Thanks Jamie, I've added snapd to this bug. Given that it's blocking me, I happily volunteer to work on it.

Just please confirm that my understanding is correct: it will be a new interface, whose slot will be implemented in snapd itself, and snaps willing to use the auto-activation feature will have to declare a plug with a parameter describing the service file to be installed (the name of the service can be found inside the .service file). Is this correct?

Revision history for this message
Michael Terry (mterry) wrote :

Alberto, sure that could work in principle. Good point.

- We'd have to not only copy the .service file, but modify its Exec= line to point inside the correct snap and update the file when a new snap version gets installed (or delete it if the new snap doesn't use the file anymore, etc).

- What is the use case that you hit this with? In my use case, both the session dbus daemon and the session dbus .service are all inside a monolithic snap. But it sounds like you want multiple snaps to install session .service files that can be run from another "session" snap? Just curious what you're envisioning.

Revision history for this message
Alberto Mardegan (mardy) wrote :

1) Indeed, it wouldn't be as simple as a file copy, it should also modify the path as you wrote.

2) I think we have the same use-case: unity8. I'm now working on getting Online Accounts to work inside a unity8 snap, but we might want to move away from a monolitic approach and deliver some session services as snaps. My understanding is that there might be a lightdm snap which will presumably start the dbus user session, and unity8 will be another snap which has all the D-Bus services we need (online accounts, EDS, content hub, etc.).

Revision history for this message
Michael Terry (mterry) wrote :

So mardy, is there a different bug about snapd growing support for dbus activation or will we use this? (just trying to keep track of it)

Revision history for this message
Alberto Mardegan (mardy) wrote :

I think we can use this one.

Revision history for this message
Launchpad Janitor (janitor) wrote :

Status changed to 'Confirmed' because the bug affects multiple users.

Changed in dbus (Ubuntu):
status: New → Confirmed
Changed in snapd (Ubuntu):
status: New → Confirmed
Revision history for this message
In , Gitlab-migration (gitlab-migration) wrote :

-- GitLab Migration Automatic Message --

This bug has been migrated to freedesktop.org's GitLab instance and has been closed from further activity.

You can subscribe and participate further through the new bug through this link to our GitLab instance: https://gitlab.freedesktop.org/dbus/dbus/issues/159.

Changed in dbus:
importance: Unknown → Wishlist
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.