Problem running example of locationd

Hey everyone,

I am relatively new to snapcraft and I am trying to build the locationd example application provided here:
https://docs.ubuntu.com/core/en/stacks/location/location-service/docs/obtain-location

I first tried a simple snapcraft.yml with no plugs defined and had the following error:

ERROR:dbus.proxies:Introspect error on :1.132:/com/ubuntu/location/Service: dbus.exceptions.DBusException: org.freedesktop.DBus.Error.AccessDenied: An AppArmor policy prevents this sender from sending this message to this recipient; type="method_call", sender=":1.168" (uid=1000 pid=2861 comm="/snap/gpssensorlog/x10/usr/bin/python3 /snap/gpsse") interface="org.freedesktop.DBus.Introspectable" member="Introspect" error name="(unset)" requested_reply="0" destination=":1.132" (uid=0 pid=26004 comm="/snap/locationd/163/bin/locationd run --bus=system")
Traceback (most recent call last):
  File "/snap/gpssensorlog/x10/bin/publish_gps.py", line 22, in <module>
    session_path = service.CreateSessionForCriteria(requirements)
  File "/snap/gpssensorlog/x10/usr/lib/python3/dist-packages/dbus/proxies.py", line 70, in __call__
    return self._proxy_method(*args, **keywords)
  File "/snap/gpssensorlog/x10/usr/lib/python3/dist-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/snap/gpssensorlog/x10/usr/lib/python3/dist-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.AccessDenied: An AppArmor policy prevents this sender from sending this message to this recipient; type="method_call", sender=":1.168" (uid=1000 pid=2861 comm="/snap/gpssensorlog/x10/usr/bin/python3 /snap/gpsse") interface="com.ubuntu.location.Service" member="CreateSessionForCriteria" error name="(unset)" requested_reply="0" destination=":1.132" (uid=0 pid=26004 comm="/snap/locationd/163/bin/locationd run --bus=system")

I then added the following plugs:
plugs:
location-observe:
interface: location-observe
location-control:
interface: location-control

So my snapcraft.yml now looks like this:

name: gpssensorlog # you probably want to 'snapcraft register <name>'
version: '1.0' # just for humans, typically '1.2+git' or '1.3.2'
summary: Logs the gps sensor values to a file
description: |
  This program captures the gps data and logs it to a file that can be shipped to the backend.

grade: devel # must be 'stable' to release into candidate/stable channels
confinement: devmode # use 'strict' once you have the right plugs and slots

apps:
    publish:
        command: bin/publish_gps.py
        plugs: ["location-observe", "location-control"]

plugs:
  location-observe:  # name that is used with 'snap connect' on plugs side
    interface: location-observe
  location-control:  # name that is used with 'snap connect' on plugs side
    interface: location-control

parts:
    files:
        plugin: python
        python-version: python3
        source: .
        stage-packages:
        - python3-dbus

I then connected the 2 interfaces:

snap connect gpssensorlog:location-observe locationd:service-observe snap connect gpssensorlog:location-control locationd:service-control

Resulting in one less error and one other error:

ERROR:dbus.proxies:Introspect error on :1.132:/com/ubuntu/location/Service: dbus.exceptions.DBusException: org.freedesktop.DBus.Error.AccessDenied: An AppArmor policy prevents this sender from sending this message to this recipient; type="method_call", sender=":1.175" (uid=1000 pid=3447 comm="/snap/gpssensorlog/x11/usr/bin/python3 /snap/gpsse") interface="org.freedesktop.DBus.Introspectable" member="Introspect" error name="(unset)" requested_reply="0" destination=":1.132" (uid=0 pid=26004 comm="/snap/locationd/163/bin/locationd run --bus=system")
Traceback (most recent call last):
  File "/snap/gpssensorlog/x11/bin/publish_gps.py", line 22, in <module>
    session_path = service.CreateSessionForCriteria(requirements)
  File "/snap/gpssensorlog/x11/usr/lib/python3/dist-packages/dbus/proxies.py", line 70, in __call__
    return self._proxy_method(*args, **keywords)
  File "/snap/gpssensorlog/x11/usr/lib/python3/dist-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/snap/gpssensorlog/x11/usr/lib/python3/dist-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.InvalidArgs: Type of message, '(a{sb})', does not match expected type '(a{sv})'

I have no clue how to proceed with this maybe someone can help me out?

Kind Regards,
Stijn De Haes

Hey,

let me look into this, will do some tests and get back to you.

Best,
K

1 Like

Sorry it took a while, meanwhile I had a day off.

What you are experiencing is an AppArmor denial on calling the Introspect method on org.freedesktop.DBus.Introspectable interface.

I have checked the location_{observe, control} interface definitions and they both allow for such calls.

Could you share how do you run your program?

Moreover do the steps described https://docs.snapcraft.io/build-snaps/debugging in the “Debugging confined apps section” and let’s take it from there.

Cheers.

I believe you’ve connected these incorrectly. I think they should be connected to core, though I may be wrong, which happens automatically when you don’t specify a target slot:

snap connect gpssensorlog:location-observe
snap connect gpssensorlog:location-control

You also do not need to define the plugs in your yaml as they are provided by the system, so you are possibly masking the default implementations. Remove the following lines:

plugs:
  location-observe:  # name that is used with 'snap connect' on plugs side
    interface: location-observe
  location-control:  # name that is used with 'snap connect' on plugs side
    interface: location-control

I ran into the same issue when trying to implement the example from https://docs.ubuntu.com/core/en/stacks/location/location-service/docs/obtain-location

I have defined the plugs

plugs: [ location-observe ]

And then try the prime

snap try prime --jailmode
snap connect location-dbus:location-observe locationd:service-observe

The following error:

ERROR:dbus.proxies:Introspect error on :1.184:/com/ubuntu/location/Service: dbus.exceptions.DBusException: org.freedesktop.DBus.Error.AccessDenied: An AppArmor policy prevents this sender from sending this message to this recipient; type="method_call", sender=":1.238" (uid=0 pid=18915 comm="python3 -m location_dbus.location " label="snap.location-dbus.location (complain)") interface="org.freedesktop.DBus.Introspectable" member="Introspect" error name="(unset)" requested_reply="0" destination=":1.184" (uid=0 pid=23503 comm="/snap/locationd/163/bin/locationd run --bus=system" label="snap.locationd.run (enforce)")
Traceback (most recent call last):
  File "/snap/location-dbus/x12/usr/lib/python3.5/runpy.py", line 184, in _run_module_as_main
    "__main__", mod_spec)
  File "/snap/location-dbus/x12/usr/lib/python3.5/runpy.py", line 85, in _run_code
    exec(code, run_globals)
  File "/home/shaned24/code/location_dbus/location_dbus/location.py", line 17, in <module>
    session_path = service.CreateSessionForCriteria(requirements)
  File "/snap/location-dbus/x12/usr/lib/python3/dist-packages/dbus/proxies.py", line 70, in __call__
    return self._proxy_method(*args, **keywords)
  File "/snap/location-dbus/x12/usr/lib/python3/dist-packages/dbus/proxies.py", line 145, in __call__
    **keywords)
  File "/snap/location-dbus/x12/usr/lib/python3/dist-packages/dbus/connection.py", line 651, in call_blocking
    message, timeout)
dbus.exceptions.DBusException: org.freedesktop.DBus.Error.InvalidArgs: Type of message, '(a{sb})', does not match expected type '(a{sv})'

Further information:

Unfortunately there is no core interface slot called “location-observe” I can only connect my location-observe plug to locationd:service-observe

Debugging with snappy debug shows:

= AppArmor =
Time: Dec 11 01:58:15
Log: apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/com/ubuntu/location/Service" interface="org.freedesktop.DBus.Introspectable" member="Introspect" name=":1.238" mask="receive" pid=23503 label="snap.locationd.run" peer_pid=18915 peer_label="snap.location-dbus.location"
DBus access
Suggestion:
* try adding 'location-observe' to 'plugs'

My interfaces:

snap interfaces | grep location
:network                                  locationd
:network-manager                           locationd
locationd:service-control                  location-dbus:location-control,locationd:client-control
locationd:service-observe                  location-dbus:location-observe,locationd:client-observe
-                                          locationd:ubx
-                                          locationd:wpa

Any updates to this issue as it is still unsolved?

Following the official example https://docs.ubuntu.com/core/en/stacks/location/location-service/docs/obtain-location, the behavior of AppArmor as described by @shaned24 is confirmed.

My plugs in snapcraft are defined:

apps:
  gps:
    command: bin/gps
    plugs: ["location-observe", "location-control"] 

and connected after installation:

nap connections gps
Interface         Plug                  Slot                       Notes
location-control  gps:location-control  locationd:service-control  manual
location-observe  gps:location-observe  locationd:service-observe  manual

Still the snappy debug suggests to add location-observe to plugs - which is already there.

= AppArmor =
Time: Aug 24 20:28:20
Log: apparmor="DENIED" operation="capable" profile="/usr/lib/snapd/snap-confine" pid=21634 comm="snap-confine" capability=4  capname="fsetid"
Capability: fsetid
Suggestions:
* adjust program to not require 'CAP_FSETID' (see 'man 7 capabilities')
* add one of 'account-control' to 'plugs'
* do nothing if program otherwise works properly

= AppArmor =
Time: Aug 24 20:28:23
Log: apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/com/ubuntu/location/Service" interface="org.freedesktop.DBus.Introspectable" member="Introspect" name=":1.21" mask="receive" pid=2808 label="snap.locationd.run" peer_pid=21634 peer_label="snap.gps.gps"
DBus access
Suggestion:
* try adding 'location-observe' to 'plugs'

What do I miss?? Is the first bit of debug relevant?

The fsetid is just noise from snap-confine that was reintroduced after a refactor. You can ignore it (we’ll get it fixed).

snappy-debug is not very smart with DBus denials and currently makes a (not particularly) educated guess which in this case is not very helpful (there is actually a snapd query API that is in the works that would allow snappy-debug to ask if an interface was connected before suggesting it that would help in this case).

As for the actual problem, this denial ‘apparmor=“DENIED” operation=“dbus_method_call” bus=“system” path="/com/ubuntu/location/Service" interface=“org.freedesktop.DBus.Introspectable” member=“Introspect” name=":1.21" mask=“receive” pid=2808 label=“snap.locationd.run” peer_pid=21634 peer_label=“snap.gps.gps”’ show there is a bug in the snapd policy. We need this rule in locationObserveConnectedSlotAppArmor and locationControlConnectedSlotAppArmor:

# Allow introspection from clients
dbus (receive)
    bus=system
    path=/com/ubuntu/location/Service
    interface=org.freedesktop.DBus.Introspectable
    member=Introspect
    peer=(label=###PLUG_SECURITY_TAGS###),

I’ve add this to the list for the next batch of policy updates.

@jdstrand very useful explanation, thank you.

Ref batch of policy updates - is there a PR or backlog item linked to one could follow its development?

Is there a way to disarm this confinement level in snapd meanwhile? gadget snap required for that?

Alternatively I could also directly connect to serial port - but I guess there I would have to bother with the user group issue as ttys are root only and in ubuntu core there is no dialout group where I could add my snap to, right? Or would there a secure workaround?

adding link: https://bugs.launchpad.net/snapd/+bug/1881232

The backlog item is in an internal trello board so a public bug would be good. I looked at the bug link you referenced but it seems to be for a different issue…