polkit: fix polkit-agent-helper@ sandbox for pam_u2f

polkit 127 switched to socket activation with a systemd unit for
polkit-agent-helper that uses PrivateDevices=yes and ProtectHome=yes.
This breaks pam_u2f (and potentially other PAM modules that interact
with hardware), because:

- PrivateDevices=yes creates a private /dev without hidraw devices,
  so FIDO tokens are inaccessible
- ProtectHome=yes blocks reading ~/.config/Yubico/u2f_keys
- StandardError=inherit causes polkit agents to misinterpret PAM
  diagnostic output as protocol errors, resulting in tight
  re-execution loops

Fix by overriding these properties in the polkit module:
- StandardError=journal unconditionally (benefits all PAM modules)
- PrivateDevices/DeviceAllow/ProtectHome when pam_u2f is enabled

Co-authored-by: Victor Luft <victor@luft.io>
This commit is contained in:
Philip Taron
2026-04-01 16:50:18 -07:00
co-authored by Victor Luft
parent d7922c9d62
commit f3648de497
+22
View File
@@ -80,6 +80,28 @@ in
systemd.sockets."polkit-agent-helper".wantedBy = [ "sockets.target" ];
systemd.services."polkit-agent-helper@".serviceConfig = lib.mkMerge [
# The upstream unit inherits stderr to the polkit agent, which causes
# agent processes to misinterpret diagnostic output from PAM modules
# as protocol errors, resulting in tight re-execution loops.
{ StandardError = "journal"; }
# The upstream unit uses PrivateDevices=yes and ProtectHome=yes,
# which prevents PAM modules from accessing hardware (e.g. FIDO
# tokens via /dev/hidraw*) or reading key files from home directories.
(lib.mkIf config.security.pam.u2f.enable {
# Override upstream PrivateDevices=yes to allow access to /dev/hidraw*
PrivateDevices = false;
DeviceAllow = [
"/dev/urandom r"
"char-hidraw rw"
];
# Override upstream ProtectHome=yes so pam_u2f can read
# ~/.config/Yubico/u2f_keys (the default key file location)
ProtectHome = "read-only";
})
];
# The polkit daemon reads action/rule files
environment.pathsToLink = [ "/share/polkit-1" ];