** Changed in: policykit-1
Status: Unknown => New
--
You received this bug notification because you are a member of Ubuntu
Touch seeded packages, which is subscribed to policykit-1 in Ubuntu.
https://bugs.launchpad.net/bugs/2084150
Title:
Path move from /lib to /usr/lib causes systemd-reply-password pkexec
mismatch
Status in PolicyKit:
New
Status in policykit-1 package in Ubuntu:
Confirmed
Bug description:
In Ubuntu/Noble, the location of
/lib/systemd/systemd-reply-password
is now
/usr/lib/systemd/systemd-reply-password.
This is also reflected in the policykit-1 action:
[jammy]$ grep path
/usr/share/polkit-1/actions/org.freedesktop.systemd1.policy
<annotate
key="org.freedesktop.policykit.exec.path">/lib/systemd/systemd-reply-password</annotate>
[noble]$ grep path
/usr/share/polkit-1/actions/org.freedesktop.systemd1.policy
<annotate
key="org.freedesktop.policykit.exec.path">/usr/lib/systemd/systemd-reply-password</annotate>
So far, so good.
However, if you have software that is written according to the specs
documented in systemd, you get the following problem:
https://github.com/systemd/systemd/blob/70516b026b7a83dbe7b8141c67f2dbe412ce24d9/docs/PASSWORD_AGENTS.md
> Access to the socket is restricted to privileged users.
> To acquire the necessary privileges to send the answer
> back, consider using PolicyKit. In fact, the GNOME agent
> we ship does that, and you may simply piggyback on that,
> by executing
> "/usr/bin/pkexec /lib/systemd/systemd-reply-password 1 /path/to/socket"
> or "/usr/bin/pkexec /lib/systemd/systemd-reply-password 0 /path/to/socket"
> and writing the password to its standard input. Use '1'
> as argument if a password was entered by the user, or '0'
> if the user canceled the request.
If you follow these specs, the exec path is /lib/systemd/systemd-
reply-password and not /usr/lib/systemd/systemd-reply-password. This
means that the action in
/usr/share/polkit-1/actions/org.freedesktop.systemd1.policy is not
matched, and no action-id org.freedesktop.systemd1.reply-password is
found.
That means that a rules.d script like this does not work:
polkit.addRule(function(action, subject) {
if (action.id == "org.freedesktop.systemd1.reply-password" &&
subject.local && subject.active &&
(subject.isInGroup("sudo") || subject.isInGroup("netdev"))) {
return polkit.Result.YES;
}
return polkit.Result.NOT_HANDLED;
});
For a call to /lib/systemd/systemd-reply-password the action.id will
not be "org.freedesktop.systemd1.reply-password" but it will be
"org.freedesktop.policykit.exec".
Adding a second <annotation> in
/usr/share/polkit-1/actions/org.freedesktop.systemd1.policy does NOT
help:
<annotate
key="org.freedesktop.policykit.exec.path">/lib/systemd/systemd-reply-password</annotate>
<annotate
key="org.freedesktop.policykit.exec.path">/usr/lib/systemd/systemd-reply-password</annotate>
<!-- yes, multiple are allowed, but with different keys/attributes -->
<!-- so, only the last one will be used -->
Adding a second <action> with the same
"org.freedesktop.systemd1.reply-password" id does NOT work either. It
will only use the second one.
It looks like the sane thing to do would be to patch polkitd to do a
`realpath /lib/systemd/systemd-reply-password` to find
`/usr/lib/systemd/systemd-reply-password` before comparing it to the
org.freedesktop.policykit.exec.path value.
Alternatively EVERY caller to /lib/systemd/systemd-reply-password
should check which the realest path is, before calling it. In which
case you end up with something like this:
> diff --git a/openvpn-u2f-ask-password b/openvpn-u2f-ask-password
> index b0637ae..4ffa1a7 100755
> --- a/openvpn-u2f-ask-password
> +++ b/openvpn-u2f-ask-password
> @@ -351,7 +351,11 @@ class AskPassword:
>
> def respond(self, response):
> subprocess.run(
> - ['/usr/bin/pkexec', '/lib/systemd/systemd-reply-password',
> + ['/usr/bin/pkexec',
> + # Work around incompatibility with policykit actions and
> + # Ubuntu move of /lib to /usr/lib, which causes polkit-1
> + # actions not to be matched if the non-real path is used.
> + os.path.realpath('/lib/systemd/systemd-reply-password'),
> '1', self._values['Socket']],
> input=response.encode('ascii'))
> print('DEBUG: response to {!r}: {}'.format(
This was quite elusive to track down. If nothing else, I hope this
ticket helps someone else.
Cheers,
Walter Doekes
OSSO B.V.
====
A possible fix could be to call realpath(3) just before the call to
find_action_for_path:
https://github.com/polkit-
org/polkit/blob/94e2b5471f8e559897a80f6dbd84f454debc0d38/src/programs/pkexec.c#L796-L799
So it is called just before the comparison here:
https://github.com/polkit-
org/polkit/blob/94e2b5471f8e559897a80f6dbd84f454debc0d38/src/programs/pkexec.c#L309
That would make calls to both /lib/systemd/systemd-reply-password and
/usr/lib/systemd/systemd-reply-password behave the same.
To manage notifications about this bug go to:
https://bugs.launchpad.net/policykit-1/+bug/2084150/+subscriptions
--
Mailing list: https://launchpad.net/~touch-packages
Post to : [email protected]
Unsubscribe : https://launchpad.net/~touch-packages
More help : https://help.launchpad.net/ListHelp