How to use dbus-run-session on ubuntu core

We have several different applications that we want to be able to communicate with each other.
dbus-run-session is available on ubuntu core, and we are using it to run our apps on a private session bus.

We have requested (and received) the permissions in the snap store for our dbus service names, and have the dbus slots and plugs configured. That all seems to be working.

It is when we try to move to a private session bus with dbus-run-session that we have issues.
dbus-run-session needs access to the following directories and files.

/sys/kernel/security/apparmor/* rw,
/usr/share/dbus-1/** rw,

I can’t figure out which interface dbus-run-session needs in order to access the above files.

Suggestions? Right now everything works in --devmode, but we have to stay in --devmode.

Wendell

2 Likes

Running your own private bus isn’t currently supported, but I took a look to see what it would take to implement it. Essentially I found that with the following session.conf file saved in $SNAP_COMMON/session.conf:

<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN"
 "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
<busconfig>
  <type>session</type>
  <keep_umask/>
  <listen>unix:tmpdir=snap.SNAP_NAME.</listen>
  <auth>EXTERNAL</auth>
  <apparmor mode="disabled"/>

  <policy context="default">
    <!-- Allow everything to be sent -->
    <allow send_destination="*" eavesdrop="true"/>
    <!-- Allow everything to be received -->
    <allow eavesdrop="true"/>
    <!-- Allow anyone to own anything -->
    <allow own="*"/>
  </policy>
</busconfig>

(where SNAP_NAME is the hardcoded name of your snap; <policy> should be able to be whatever makes sense for your snap) and the following apparmor policy added on top of the slot side policy:

/usr/bin/dbus-run-session ixr,
/usr/bin/dbus-daemon ixr,
/sys/module/apparmor/parameters/enabled r,
unix (bind,listen) addr="@snap.@{SNAP_NAME}./dbus-*",

and finally add bind to the snap’s seccomp policy. Then I could use dbus-run-session within a snap. Eg:

$ snap run --shell test-snapd-policy-app-consumer-classic
bash$ dbus-run-session --config-file=$SNAP_COMMON/session.conf env|grep DBUS
DBUS_SESSION_BUS_ADDRESS=unix:abstract=snap.test-snapd-policy-app-provider-classic./dbus-3HdA9U1lxA,guid=3438b8dd2cb51db68cf446a45babfc54

There is an apparmor denial that is just noise:

audit(1537997046.626:5710): apparmor="DENIED" operation="open" profile="snap.test-snapd-policy-app-provider-classic.dbus-session" name="/proc/19256/mounts" pid=19256 comm="dbus-daemon" requested_mask="r" denied_mask="r" fsuid=1000 ouid=1000

What this does is allow the snap to run dbus-run-session, which calls dbus-daemon with the configuration from the snap-provided session.conf file, which allows setting up of a private dbus bus at ‘@snap.SNAP_NAME./dbus-*’ and the private bus is setup. We need other rules for communicating over it; this is what I expect we would want in reality (untested):

# allow us to manage our own abstract socket
unix (bind, listen) addr="@snap.@{SNAP_NAME}.**",
# allow processes from this snap to use abstract sockets from this snap
unix (accept, connect, receive, send) addr="@snap.@{SNAP_NAME}.**" peer=(label=snap.@{SNAP_NAME}.*),

There are a couple of interesting things about this:

  • the session.conf disables apparmor in dbus-daemon. That’s fine-- it isn’t in a good position to mediate itself and other snaps can’t access the private bus anyway because the ‘unix’ rules make this snap specific. Unconfined processes would be able to access it once they found the bus
  • you therefore shouldn’t need to use the dbus interface at all with registering well-known names-- this is really about giving your snap access to the abstract socket; the fact that the snap is using a private dbus session is an implementation detail that can stay within the snap. It does mean that your services can only be accessed by clients within the same snap (likely what you are trying to achieve with a private bus anyway)
  • the abstract socket is snap-specific because we use snap.SNAP_NAME. (the ‘snap.’ prefix and trailing ‘.’ means that snaps can’t overlap here and makes it equivalent to what we already allow with named sockets (eg, that can live in SNAP_COMMON, etc)

I’m inclined to add the above to the default policy, but for your snap today, you can’t use the private bus. I’ll update this topic if/when those changes land.

1 Like

This was just merged into trunk and on its way to 2.36: https://github.com/snapcore/snapd/pull/5968

this seems to have slightly regressed in apparmor in UC20.

i’m trying to package an electron app as wayland kiosk app for Ubuntu Core, unlike with X11, electron needs a dbus session wrapped around it in this setup.

following the above tutorial and using dbus-run-session from a command-chain script works well but triggers an apparmor denial in the logs:

audit: type=1400 audit(1632401841.953:1625): apparmor="DENIED" operation="open" profile="snap.electron-kiosk-uc20.electron-kiosk-uc20" name="/sys/kernel/security/apparmor/features/dbus/mask" pid=105392 comm="dbus-daemon" requested_mask="r" denied_mask="r" fsuid=0 ouid=0

this does not seem to cause any issues but it would be nice if we could somehow quieten it … @alexmurray any idea what we could do here ?

Hmm doesn’t seem like that path leaks much information so maybe it could just be added to the default template as a read-only permission

@jjohansen may have thoughts on what else it can be used for though I don’t see anything at https://gitlab.com/apparmor/apparmor/-/wikis/AppArmorFeatureABI

1 Like

I would guess that apparmor_parser should autogenerate a rule allowing access to this when a dbus rule is encountered in the profile - but hopefully @jjohansen can clarify…?

The parser doesn’t add an implicit rule for this when dbus rules exist in the profile because it is NOT needed or used by them. This is a query against the apparmor kernel interface to see if dbus mediation is supported by the kernel. Any fs access under /sys/kernel/security/apparmor/features/ is gathering info about what the current kernel supports.

It looks like the dbus daemon it self is doing the query, which would make sense as the apparmor code in the dbus daemon does check whether the kernel supports its mediation and if it doesn’t the code does not attempt to do any mediation.

Why this is showing up now and wasn’t early I can’t say. The dbus apparmor code has always checked if the kernel supports dbus mediation, and there haven’t been any real changes around this apparmor side either.

Note: this denial will keep the dbus-daemon from enforcing any dbus policy rules. This may not necessarily be bad depending on which dbus daemon it is. Eg a private one within the snap confinement session would not affect the system daemon.

This is exactly what it is and it functions as expected inside the snap daemon session. I was just wondering if we could quieten the message to not spam the logs (I am sure I do not want full mediation when running de-coupled inside a snap just providing internal service to shipped parts)

yes. You can either add a rule to explicitly allow the access

  r /sys/kernel/security/apparmor/features/dbus/mask,

or you can add a rule to explicitly deny the access

 deny  r /sys/kernel/security/apparmor/features/dbus/mask,

Querying kernel support is its only use. The threat level of accessing this is low but it is possible an attacker could probe this value and modify its behavior if dbus mediation is present. Basically avoid sending dbus messages to avoid revealing its presence

I think that mechanism isn’t sufficient to prevent it from being included in the default template, and also I’m not sure where to put this access if we decided to not put it in the default template, so let’s start there and if folks disagree then they can suggest somewhere else to put it :slight_smile:

PR up https://github.com/snapcore/snapd/pull/10842

1 Like

i’m not sure if an explicit denial (which quietens it as well) wouldn’t be the better approach here … the current behavior of dbus-run-session inside a kiosk snap works as expected when the read is not allowed, i’m a bit scared that allowing the read will limit functionality for this particular use-case

How would it limit functionality by allowing dbus-run-session to read what level of mediation is performed by AppArmor?

by possibly making dbus-daemon behave according to the level (which does apply outside the snap but not inside) ?

i haven’t checked the code if it does anything like that indeed :slight_smile: (but i guess there is a reason why it checks that setting at all)

is there an easy way to modify the template on a running system so i could try ?

you should be able to copy the profile file out of /var/lib/snapd/apparmor/profiles/ add the rule and the load it into the kernel with

apparmor_parser -r /the/modified/profile/file

This will do a live replacement of the profile on the kernel and it will be applied to the running tasks that were confined by the old profile.

I should note that if you are getting the denied audit message, adding the deny rule shouldn’t change the behavior (apparmor is default deny). At this level it just tells apparmor this denial is known and should be quieted.

2 Likes

ah, i did not know that overrides the default template … being lazy with this throw-away install i just added it directly to /var/lib/snapd/apparmor/profiles/snap.electron-kiosk-wayland.electron-kiosk-wayland

seems to not cause any obvious bad behavior and the log spam goes away with:

/sys/kernel/security/apparmor/features/dbus/mask r,

added, like in the PR …

1 Like