Bug#1061094: mmdebstrap vs. apt -o DPkg::Inhibit-Shutdown
Package: apt
Version: 2.6.1
Severity: wishlist
I'm creating this bug so there's a bug number I can link to.
We discussed it on #debian-apt around 2024-01-16 08:54:47+00:00.
I noticed that since 2023-10-10, mmdebstrap triggers these errors:
2023-10-10T15:53:32+1100 hera polkitd[2696604]:
Error evaluating admin rules:
Error: Helper exited with non-zero exit status 1,
stdout=`',
stderr=`pkla-check-authorization: Invalid user `100000': No UNIX user with name 100000: Success
(pkla-check-authorization:3461602): GLib-GObject-CRITICAL **: 15:53:32.183: g_object_unref: assertion 'G_IS_OBJECT (object)' failed'
I initially thought it was a faulty postinst, but
after several hours of digging, I managed to narrow it down:
bash5$ journalctl -o short-iso -u polkit --grep='Error evaluating admin rules' -fn0 &
bash5$ sudo dbus-monitor --system --pcap | tshark -r- -Y 'dbus.interface == "org.freedesktop.login1.Manager"' &
bash5$ mmdebstrap bookworm /dev/null --quiet
11 24.706215 :1.1955 → org.freedesktop.login1 D-Bus 246 Inhibit() @ /org/freedesktop/login1
2024-01-18T10:36:10+1100 hera polkitd[1035]: Error evaluating admin rules: Error: Helper exited with non-zero exit status 1, stdout=`', stderr=`pkla-check-authorization: Invalid user `100000': No UNIX user with name 100000: Success
(pkla-check-authorization:874223): GLib-GObject-CRITICAL **: 10:36:10.673: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
'
50 37.507789 :1.1956 → org.freedesktop.login1 D-Bus 246 Inhibit() @ /org/freedesktop/login1
2024-01-18T10:36:23+1100 hera polkitd[1035]: Error evaluating admin rules: Error: Helper exited with non-zero exit status 1, stdout=`', stderr=`pkla-check-authorization: Invalid user `100000': No UNIX user with name 100000: Success
(pkla-check-authorization:875795): GLib-GObject-CRITICAL **: 10:36:23.475: g_object_unref: assertion 'G_IS_OBJECT (object)' failed
'
bash5$ mmdebstrap bookworm /dev/null --quiet '--aptopt=DPKG::Inhibit-Shutdown 0;'
The relevant code is here:
https://salsa.debian.org/apt-team/apt/-/blob/2.6.1/apt-pkg/deb/dpkgpm.cc?ref_type=tags#L1508-1509
What is happening is this:
* "apt install foo" starts
* apt/dpkg --dbus--> systemd, "please inhibit (refuse to) shutdown/reboot during installs"
* systemd --dbus--> polkit, "user 1234 asked to inhibit shutdowns, is that allowed?"
* polkit --dbus--> systemd, "user 1234 doesn't exist, therefore no"
* systemd ignores the request (maybe signalling an error?)
* apt/dpkg continues on without any real issue
This issue DOES NOT affect normal host usage of apt, because
"sudo apt install x" runs the host's apt, with a normal host-wide user that polkit can see.
The inhibit works there (assuming pid1 is systemd, I guess).
This issue DOES NOT affect normal chroots, because
"sudo chroot /target apt install x" cannot "see" the un-chrooted dbus, so
the inhibit attempt fails before reaching systemd/polkit.
This issue affects mmdebstrap, because mmdebstrap run's the host's apt,
with an unshare'd userns such that apt thinks the user is root, and
systemd/polkit thinks it's a transient UID with no record in nss passwd table.
(systemd DynamicUser= units and systemd-nspawn containers have similar transient UIDs, and
in those cases "apt install libnss-systemd libnss-machines" provides nss passwd entries.)
Julian suggested this change:
- if (_config->FindB("DPkg::Inhibit-Shutdown", true))
+ if (_config->FindB("DPkg::Inhibit-Shutdown", _config->FindDir("Dir", "/") == "/"))
I like this plan.
This will fix the mmdebstrap case, because mmdebstrap runs something like "unshare ⋯ apt -o Dir=/tmp/mmdebstrap.XXXXXX".
(No one cares if an mmdebstrap image build is "corrupted" by a halt/reboot - you just rerun mmdebstrap and make a fresh one.)
This should NOT affect "sudo apt install x" or "sudo chroot /target apt install x", because
in both cases apt is operating on / (either the host's /, or the chroot's /).
This should NOT affect debootstrap because it only runs dpkg, not apt (I think).
This MIGHT affect someone else doing "apt -o Dir=⋯" to do custom installs, but
everything I can think of offhand is a wrapper around debootstrap, except for
https://github.com/openSUSE/obs-build/blob/master/obs-docker-support#L118
Everything I can find seems to set e.g. Dir::Etc rather than Dir itself.
https://codesearch.debian.net/search?q=apt.*-o.*Dir%5B%5E%3A%5D
https://github.com/search?q=%2Fapt.*-o.*Dir%2F&type=code (requires Microsoft account, requires javascript)
PS: general details about the "inihibit" functionality are here:
https://manpages.debian.org/bookworm/systemd/systemd-inhibit.1.en.html
https://www.freedesktop.org/wiki/Software/systemd/inhibit/
Reply to: