Apparmor error with org.freedesktop.login1.Manager

Possibly one for @jdstrand -

$ snap install polar-bookshelf
$ snap run polar-bookshelf
Failed to generate minidump.Segmentation fault (core dumped)

snappy-debug.security scanlog shows:-

= AppArmor =
Time: Oct 25 18:00:23
Log: apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/" interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" mask="send" name="org.bluez" pid=18089 label="snap.polar-bookshelf.polar-bookshelf" peer_pid=2042 peer_label="unconfined"
DBus access

= AppArmor =
Time: Oct 25 18:00:23
Log: apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/org/freedesktop/login1" interface="org.freedesktop.login1.Manager" member="Inhibit" mask="send" name="org.freedesktop.login1" pid=18089 label="snap.polar-bookshelf.polar-bookshelf" peer_pid=2058 peer_label="unconfined"
DBus access
Suggestion:
* try adding 'shutdown' to 'plugs'

I tried adding screen-inhibit-control and shutdown and connecting shutdown but it fails in the same way.

The snap works fine in devmode.

Any ideas?

Indications from the upstream issue are that removing sentry from the snap makes this stop happening. Would be good if this could be fixed on our side, as other electron application developers may also want to use it.

Also an electron issue about this.

https://www.freedesktop.org/wiki/Software/systemd/logind/ has this to say:

“Inhibit() creates an inhibition lock. It takes four parameters: What, Who, Why and Mode. “What” is one or more of “shutdown”, “sleep”, “idle”, “handle-power-key”, “handle-suspend-key”, “handle-hibernate-key”, “handle-lid-switch”, separated by colons, for inhibiting poweroff/reboot, suspend/hibernate, the automatic idle logic, or hardware key handling. “Who” should be a short human readable string identifying the application taking the lock. “Why” should be a short human readable string identifying the reason why the lock is taken. Finally, “Mode” is either “block” or “delay” which encodes whether the inhibit shall be consider mandatory or whether it should just delay the operation to a certain maximum time. The call returns a file descriptor. The lock is released the moment this file descriptor (and all its duplicates) are closed. For more information on the inhibition logic see Inhibitor Locks.”

As such, this Inhibit is different from screen-inhibit. It could probably be added to the shutdown interface, but that is not a perfect fit because the shutdown interface is about, well, shutting down and this DBus api is about preventing shutting down. Preventing shutting down allows the snap the ability to prevent booting into a new kernel, core, etc so an application using this interface would be considered privileged. I’m honestly quite surprised that an electron app or a desktop app is in the business of inhibiting shutdown-- this sounds like a mis-feature or a bug in these applications. Can you detail the justification for inhibiting shutdown/etc?

1 Like

Also, does the denial cause the snap to crash or does it happily keep running (I would hope the latter-- seems like policykit could conceivably block this (separate from apparmor) and that should not be a fatal error.

It would die. Upstream have removed the sentry call to prevent it crashing. I have had some other applications which die similarly but don’t use sentry. I saw it this week with an electron app called wewechat I snapped.

https://people.canonical.com/~alan/wewechat_1.1.7_amd64.snap

$ wewechat 
Gtk-Message: Failed to load module "canberra-gtk-module"
Gtk-Message: Failed to load module "canberra-gtk-module"
Segmentation fault (core dumped)
INFO: following '/var/log/syslog'. If have dropped messages, use:
INFO: $ sudo journalctl --output=short --follow --all | sudo snappy-debug.security scanlog
sysctl: permission denied on key 'kernel.printk_ratelimit'
= AppArmor =
Time: Nov  2 15:08:44
Log: apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/" interface="org.freedesktop.DBus.ObjectManager" member="GetManagedObjects" mask="send" name="org.bluez" pid=1300 label="snap.wewechat.wewechat" peer_pid=2266 peer_label="unconfined"
DBus access

= AppArmor =
Time: Nov  2 15:08:44
Log: apparmor="DENIED" operation="dbus_method_call"  bus="system" path="/org/freedesktop/login1" interface="org.freedesktop.login1.Manager" member="Inhibit" mask="send" name="org.freedesktop.login1" pid=1300 label="snap.wewechat.wewechat" peer_pid=2286 peer_label="unconfined"
DBus access
Suggestion:
* try adding 'shutdown' to 'plugs'

is this behaviour of the apps a misguided attempt to ensure they get shut down properly to prevent them losing data? kinda like Windows’ behaviour where it will signal all applications to close and then wait for them all to cleanly exit before rebooting or turning off with a notice “The following applicaitons are preventing shutdown”.

Missed this question, sorry.

I can’t. I am merely trying to snap someone else’s code, and wonder why it crashes.

This is buggy code. It should fail gracefully as there are other things that might prevent its access besides an AppArmor denial due to being packaged as a snap (as mentioned, a deb, rpm, whatever would crash if there was a polkit denial for this (eg, see /usr/share/polkit-1/actions/org.freedesktop.login1.policy). I would argue snaps should not typically be allowed this.

That said, because we know there is polkit, one could argue that on classic distro where polkit is a thing (polkit does not exist on Ubuntu Core devices yet), we could allow the access. I would argue we should not since the distro/admin may have configured the system to allow access for certain users/groups, and since polkit doesn’t atm understand snaps, on these systems if we allowed the access the snap would be able to prevent shutdowns/reboot/etc when run under these users/groups. This would be a manually connected interface anyway.

Put more clearly-- electron, sentry, whatever needs to handle the denial gracefully. This will improve their robustness outside of snaps which would be good for them. If there is a legitimate use of the DBus api, we can consider adding an interface, but IMO we don’t want to allow the access simply because an application is coded incorrectly when facing a denial.