AccessDenied when running my Packaged Bluetooth app

Project: https://github.com/willdeberry/bjarkan

Steps to Reproduce

  1. Install edge variant of snap: sudo snap install --edge bjarkan
  2. Connect interfaces: bjarkan:uhid, bjarkan:bluetooth-control, bjarkan:network-control, bjarkan:network-manager
  3. Help works: sudo bjarkan --help
  4. Talking to bluetooth via dbus does not work: sudo bjarkan paired-devices

Expected Results

Exits 0, and if no paired devices, produces no output

Actual Results

Aug 16 11:39:49 PLC-3078dab8-bb720371 audit[797]: USER_AVC pid=797 uid=112 auid=4294967295 ses=4294967295 msg='apparmor="DENIED" operation="dbus_method_call" bus="system" path="/" interface="org.freedesktop.DBus.Introspectable" member="Introspect" mask="send" name=":1.99" pid=13416 label="snap.bjarkan.bjarkan" peer_pid=5668 peer_label="unconfined" exe="/usr/bin/dbus-daemon" sauid=112 hostname=? addr=? terminal=?'

Aug 16 11:39:49 PLC-3078dab8-bb720371 audit[797]: USER_AVC pid=797 uid=112 auid=4294967295 ses=4294967295 msg='apparmor="DENIED" operation="dbus_method_call" bus="system" path="/" interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" mask="send" name=":1.99" pid=13416 label="snap.bjarkan.bjarkan" peer_pid=5668 peer_label="unconfined" exe="/usr/bin/dbus-daemon" sauid=112 hostname=? addr=? terminal=?'

It seems like you are trying to talk to bluez, which is different than what bluetooth-control provides. If you are on Ubuntu Core, you can install the bluez snap and your snap can then use ‘plugs: [ bluez ]’ to connect to it.

Note that the bluez interface is not available as an implicit classic slot at this time.

Is there a specific reason for this (I was wondering already during the day when @willdeberry asked on IRC) ?
If Bluetooth is available on classic it should just expose a bluez interface IMHO.

For a classic install, would it be expected that I would need to bundle my own bluez package? Much like https://git.launchpad.net/~snappy-hwe-team/snappy-hwe-snaps/+git/bluez/tree/snapcraft.yaml#n74

I also went through the path of installing the bluez snap on 16.04. It did not install a :bluez Slot. The only thing I found was bluez:service. See output of sudo snap interfaces below:

bluez:service             bjarkan:bluez,bluez:client
:account-control          -
:alsa                     -
:autopilot-introspection  -
:avahi-observe            -
:bluetooth-control        bjarkan,bluez
:browser-support          -
:camera                   -
:classic-support          -
:core-support             core:core-support-plug
:cups-control             -
:dcdbas-control           -
:docker-support           -
:firewall-control         -
:framebuffer              -
:fuse-support             -
:gsettings                -
:hardware-observe         -
:hardware-random-control  -
:hardware-random-observe  -
:home                     bluez
:io-ports-control         -
:joystick                 -
:kernel-module-control    -
:kubernetes-support       -
:libvirt                  -
:locale-control           -
:log-observe              -
:lxd-support              -
:modem-manager            -
:mount-observe            -
:netlink-audit            -
:netlink-connector        -
:network                  bjarkan
:network-bind             -
:network-control          bjarkan,bluez
:network-manager          bjarkan
:network-observe          -
:network-setup-control    -
:network-setup-observe    -
:ofono                    -
:opengl                   -
:openvswitch              -
:openvswitch-support      -
:optical-drive            -
:physical-memory-control  -
:physical-memory-observe  -
:ppp                      -
:process-control          -
:pulseaudio               -
:raw-usb                  -
:removable-media          -
:screen-inhibit-control   -
:shutdown                 -
:snapd-control            -
:system-observe           -
:system-trace             -
:time-control             -
:timeserver-control       -
:timezone-control         -
:tpm                      -
:uhid                     bluez
:unity7                   -
:upower-observe           -
:x11                      -

There is no reason and the interface could be converted to being available on both. See avahi-observe in master for how this could be done.

This is the slot. Your snap would ‘plugs: [ bluez ]’ and on the command line you would ‘snap connect bjarkan:bluez bluez:service’.

Note that installing the bluez snap on a classic system is probably not going to do what you want unless you remove the bluez deb. Also, on classic with the bluez snap you won’t necessarily have the same dbus bus policy and definitely won’t have polkit. I don’t recommend you pursue this for production deployments. The snap is designed for Ubuntu Core, not classic.

Better would be to adjust snapd to expose the slot on classic (see my last comment).

Where would I find the code for avahi-observe so a curious mind like mine could see how things are being done to expose the interface for classic?

https://github.com/snapcore/snapd/tree/master/interfaces/builtin (see avahi_observe.go and avahi_observe_test.go).

So unless I am over simplifying things, this should be as easy as doing something like https://github.com/snapcore/snapd/blob/master/interfaces/builtin/avahi_observe.go#L41 within the bluez interface. If so, I will be happy to write up a PR for snapd.

well, i guess there is a bit more to it … you dont really want to expose that interface on a system that has no bluetooth enabled/available

This is what the base declaration is for-- it isn’t auto-connectable so it doesn’t matter if the interface is there.

The base declaration needs to be updated like that, yes, but you also need to adjust the security policy for connecting to unconfined (since on classic, bluez is unconfined but on core it has the snap’s security label). See: https://github.com/snapcore/snapd/blob/master/interfaces/builtin/avahi_observe.go#L436

Essentially:

  • adjust the base declaration and adjust testsuite as appropriate
  • adjust to use ‘unconfined’ when OnClassic
  • add a test to bluez_test.go for when OnClassic (see TestAppArmorSpec() in avahi_observe_test.go)

You can quickly iterate with specific testsuite tests with:

$ go build -v github.com/snapcore/snapd/... && go test -v github.com/snapcore/snapd/interfaces/builtin
$ go build -v github.com/snapcore/snapd/... && go test -v github.com/snapcore/snapd/interfaces/policy

(first is for your interface changes, the second for the base declaration)

1 Like

So I made the changes that I think are needed: https://github.com/willdeberry/snapd/commit/506c576926a1d1be02aa3a4f7af7ae3547c34d89

Ran the tests you suggested and all is passing. However, reading through the HACKING.md to build snapd and test it locally, I am still not seeing the :bluez interface.

Having not dealt with go before, not sure if I am missing something obvious.

I responded in github.

So I updated the code to reflect the addition of core and a couple other things I had missed on the first go round (https://github.com/willdeberry/snapd/commit/1169f593d856f85222d17150b829bf27cf4728ce). Haven’t touched the tests yet as I was trying to get this working before going that path.

I am building snapd and snap using the following commands:
go build -o /tmp/snapd github.com/willdeberry/snapd/cmd/snapd
go build -o /tmp/snap github.com/willdeberry/snapd/cmd/snap

I then stopped all other snapd services as advised by the docs: sudo systemctl stop snapd.service snapd.socket. Then launched my built snapd service: sudo SNAPD_DEBUG=1 SNAPD_DEBUG_HTTP=3 /tmp/snapd.

Nothing I do seems to show a newly exposed :bluez interface.

Was able to get things resolved and a PR sent: https://github.com/snapcore/snapd/pull/3812

1 Like