Status changed to 'Confirmed' because the bug affects multiple users.

** Changed in: policykit-1 (Ubuntu)
       Status: New => Confirmed

-- 
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:
  Unknown
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     : touch-packages@lists.launchpad.net
Unsubscribe : https://launchpad.net/~touch-packages
More help   : https://help.launchpad.net/ListHelp

Reply via email to