From 06ea86c6e2e9cf127ba970b83f4da7ad3d014bd7 Mon Sep 17 00:00:00 2001 From: Xarblu Date: Wed, 26 Aug 2026 15:02:35 +0200 Subject: [PATCH] pkexec: Allow fallback to user path when realpath has no action This restores the old (< v127) behaviour as a fallback to keep backwards compatibility with old actions (see https://bugs.gentoo.org/959152). The canonical (real-)path is still preferred if it has a matches an action. Signed-off-by: Xarblu --- src/programs/pkexec.c | 59 +++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 19 deletions(-) diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c index 9028fe5b..f78742d4 100644 --- a/src/programs/pkexec.c +++ b/src/programs/pkexec.c @@ -361,11 +361,6 @@ find_action_for_path (PolkitAuthority *authority, g_list_foreach (actions, (GFunc) g_object_unref, NULL); g_list_free (actions); - /* Fall back to org.freedesktop.policykit.exec */ - - if (action_id == NULL) - action_id = g_strdup ("org.freedesktop.policykit.exec"); - return action_id; } @@ -705,16 +700,6 @@ main (int argc, char *argv[]) } } - s = realpath(path, NULL); - if (s != NULL) - { - /* The called program resolved to the canonical location. We don't update - * argv[n] this time. The called program still sees the original - * called path. This is very important for multi-call binaries like - * busybox. */ - g_free (path); - path = s; - } if (access (path, F_OK) != 0) { g_printerr ("Error accessing %s: %s\n", path, g_strerror (errno)); @@ -844,10 +829,46 @@ main (int argc, char *argv[]) g_assert (path != NULL); g_assert (exec_argv != NULL); - action_id = find_action_for_path (authority, - path, - exec_argv[1], - &allow_gui); + + s = realpath(path, NULL); + if (s != NULL) + { + /* The called program resolved to the canonical location. We don't update + * argv[n] this time. The called program still sees the original + * called path. This is very important for multi-call binaries like + * busybox. */ + action_id = find_action_for_path (authority, + s, + exec_argv[1], + &allow_gui); + + /* Commit to the canonical only when it has a match. + * Else we want to preserve and try the original path. */ + if (action_id != NULL) + { + g_free (path); + path = s; + } + else + { + g_free (s); + } + } + + /* Canonical path had no match. + * Fall back to user provided path. */ + if (action_id == NULL) + { + action_id = find_action_for_path (authority, + path, + exec_argv[1], + &allow_gui); + } + + /* Fall back to org.freedesktop.policykit.exec */ + if (action_id == NULL) + action_id = g_strdup ("org.freedesktop.policykit.exec"); + g_assert (action_id != NULL); details = polkit_details_new ();