summaryrefslogtreecommitdiff
path: root/user/polkit/CVE-2015-4625.patch
diff options
context:
space:
mode:
Diffstat (limited to 'user/polkit/CVE-2015-4625.patch')
-rw-r--r--user/polkit/CVE-2015-4625.patch1008
1 files changed, 0 insertions, 1008 deletions
diff --git a/user/polkit/CVE-2015-4625.patch b/user/polkit/CVE-2015-4625.patch
deleted file mode 100644
index 4a43fb433..000000000
--- a/user/polkit/CVE-2015-4625.patch
+++ /dev/null
@@ -1,1008 +0,0 @@
-From ea544ffc18405237ccd95d28d7f45afef49aca17 Mon Sep 17 00:00:00 2001
-From: Colin Walters <walters@redhat.com>
-Date: Thu, 4 Jun 2015 12:15:18 -0400
-Subject: CVE-2015-4625: Use unpredictable cookie values, keep them secret
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-Tavis noted that it'd be possible with a 32 bit counter for someone to
-cause the cookie to wrap by creating Authentication requests in a
-loop.
-
-Something important to note here is that wrapping of signed integers
-is undefined behavior in C, so we definitely want to fix that. All
-counter integers used in this patch are unsigned.
-
-See the comment above `authentication_agent_generate_cookie` for
-details, but basically we're now using a cookie of the form:
-
-```
- <agent serial> - <agent random id> - <session serial> - <session
-random id>
-```
-
-Which has multiple 64 bit counters, plus unpredictable random 128 bit
-integer ids (effectively UUIDs, but we're not calling them that
-because we don't need to be globally unique.
-
-We further ensure that the cookies are not visible to other processes
-by changing the setuid helper to accept them over standard input. This
-means that an attacker would have to guess both ids.
-
-In any case, the security hole here is better fixed with the other
-change to bind user id (uid) of the agent with cookie lookups, making
-cookie guessing worthless.
-
-Nevertheless, I think it's worth doing this change too, for defense in
-depth.
-
-Bug: https://bugs.freedesktop.org/show_bug.cgi?id=90832
-CVE: CVE-2015-4625
-Reported-by: Tavis Ormandy <taviso@google.com>
-Reviewed-by: Miloslav Trmač <mitr@redhat.com>
-Signed-off-by: Colin Walters <walters@redhat.com>
-
-diff --git a/src/polkitagent/polkitagenthelper-pam.c b/src/polkitagent/polkitagenthelper-pam.c
-index 937386e..19062aa 100644
---- a/src/polkitagent/polkitagenthelper-pam.c
-+++ b/src/polkitagent/polkitagenthelper-pam.c
-@@ -65,7 +65,7 @@ main (int argc, char *argv[])
- {
- int rc;
- const char *user_to_auth;
-- const char *cookie;
-+ char *cookie = NULL;
- struct pam_conv pam_conversation;
- pam_handle_t *pam_h;
- const void *authed_user;
-@@ -97,7 +97,7 @@ main (int argc, char *argv[])
- openlog ("polkit-agent-helper-1", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
-
- /* check for correct invocation */
-- if (argc != 3)
-+ if (!(argc == 2 || argc == 3))
- {
- syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
- fprintf (stderr, "polkit-agent-helper-1: wrong number of arguments. This incident has been logged.\n");
-@@ -105,7 +105,10 @@ main (int argc, char *argv[])
- }
-
- user_to_auth = argv[1];
-- cookie = argv[2];
-+
-+ cookie = read_cookie (argc, argv);
-+ if (!cookie)
-+ goto error;
-
- if (getuid () != 0)
- {
-@@ -203,6 +206,8 @@ main (int argc, char *argv[])
- goto error;
- }
-
-+ free (cookie);
-+
- #ifdef PAH_DEBUG
- fprintf (stderr, "polkit-agent-helper-1: successfully sent D-Bus message to PolicyKit daemon\n");
- #endif /* PAH_DEBUG */
-@@ -212,6 +217,7 @@ main (int argc, char *argv[])
- return 0;
-
- error:
-+ free (cookie);
- if (pam_h != NULL)
- pam_end (pam_h, rc);
-
-diff --git a/src/polkitagent/polkitagenthelper-shadow.c b/src/polkitagent/polkitagenthelper-shadow.c
-index a4f73ac..e877915 100644
---- a/src/polkitagent/polkitagenthelper-shadow.c
-+++ b/src/polkitagent/polkitagenthelper-shadow.c
-@@ -46,7 +46,7 @@ main (int argc, char *argv[])
- {
- struct spwd *shadow;
- const char *user_to_auth;
-- const char *cookie;
-+ char *cookie = NULL;
- time_t now;
-
- /* clear the entire environment to avoid attacks with
-@@ -67,7 +67,7 @@ main (int argc, char *argv[])
- openlog ("polkit-agent-helper-1", LOG_CONS | LOG_PID, LOG_AUTHPRIV);
-
- /* check for correct invocation */
-- if (argc != 3)
-+ if (!(argc == 2 || argc == 3))
- {
- syslog (LOG_NOTICE, "inappropriate use of helper, wrong number of arguments [uid=%d]", getuid ());
- fprintf (stderr, "polkit-agent-helper-1: wrong number of arguments. This incident has been logged.\n");
-@@ -86,7 +86,10 @@ main (int argc, char *argv[])
- }
-
- user_to_auth = argv[1];
-- cookie = argv[2];
-+
-+ cookie = read_cookie (argc, argv);
-+ if (!cookie)
-+ goto error;
-
- #ifdef PAH_DEBUG
- fprintf (stderr, "polkit-agent-helper-1: user to auth is '%s'.\n", user_to_auth);
-@@ -153,6 +156,8 @@ main (int argc, char *argv[])
- goto error;
- }
-
-+ free (cookie);
-+
- #ifdef PAH_DEBUG
- fprintf (stderr, "polkit-agent-helper-1: successfully sent D-Bus message to PolicyKit daemon\n");
- #endif /* PAH_DEBUG */
-@@ -162,6 +167,7 @@ main (int argc, char *argv[])
- return 0;
-
- error:
-+ free (cookie);
- fprintf (stdout, "FAILURE\n");
- flush_and_wait ();
- return 1;
-diff --git a/src/polkitagent/polkitagenthelperprivate.c b/src/polkitagent/polkitagenthelperprivate.c
-index cfa77fc..e23f9f5 100644
---- a/src/polkitagent/polkitagenthelperprivate.c
-+++ b/src/polkitagent/polkitagenthelperprivate.c
-@@ -23,6 +23,7 @@
- #include "config.h"
- #include "polkitagenthelperprivate.h"
- #include <stdio.h>
-+#include <string.h>
- #include <stdlib.h>
- #include <unistd.h>
-
-@@ -45,6 +46,38 @@ _polkit_clearenv (void)
- #endif
-
-
-+char *
-+read_cookie (int argc, char **argv)
-+{
-+ /* As part of CVE-2015-4625, we started passing the cookie
-+ * on standard input, to ensure it's not visible to other
-+ * processes. However, to ensure that things continue
-+ * to work if the setuid binary is upgraded while old
-+ * agents are still running (this will be common with
-+ * package managers), we support both modes.
-+ */
-+ if (argc == 3)
-+ return strdup (argv[2]);
-+ else
-+ {
-+ char *ret = NULL;
-+ size_t n = 0;
-+ ssize_t r = getline (&ret, &n, stdin);
-+ if (r == -1)
-+ {
-+ if (!feof (stdin))
-+ perror ("getline");
-+ free (ret);
-+ return NULL;
-+ }
-+ else
-+ {
-+ g_strchomp (ret);
-+ return ret;
-+ }
-+ }
-+}
-+
- gboolean
- send_dbus_message (const char *cookie, const char *user)
- {
-diff --git a/src/polkitagent/polkitagenthelperprivate.h b/src/polkitagent/polkitagenthelperprivate.h
-index aeca2c7..547fdcc 100644
---- a/src/polkitagent/polkitagenthelperprivate.h
-+++ b/src/polkitagent/polkitagenthelperprivate.h
-@@ -38,6 +38,8 @@
-
- int _polkit_clearenv (void);
-
-+char *read_cookie (int argc, char **argv);
-+
- gboolean send_dbus_message (const char *cookie, const char *user);
-
- void flush_and_wait ();
-diff --git a/src/polkitagent/polkitagentsession.c b/src/polkitagent/polkitagentsession.c
-index f014773..8b93ad0 100644
---- a/src/polkitagent/polkitagentsession.c
-+++ b/src/polkitagent/polkitagentsession.c
-@@ -55,6 +55,7 @@
- #include <stdio.h>
- #include <sys/types.h>
- #include <sys/wait.h>
-+#include <gio/gunixoutputstream.h>
- #include <pwd.h>
-
- #include "polkitagentmarshal.h"
-@@ -88,7 +89,7 @@ struct _PolkitAgentSession
- gchar *cookie;
- PolkitIdentity *identity;
-
-- int child_stdin;
-+ GOutputStream *child_stdin;
- int child_stdout;
- GPid child_pid;
-
-@@ -129,7 +130,6 @@ G_DEFINE_TYPE (PolkitAgentSession, polkit_agent_session, G_TYPE_OBJECT);
- static void
- polkit_agent_session_init (PolkitAgentSession *session)
- {
-- session->child_stdin = -1;
- session->child_stdout = -1;
- }
-
-@@ -395,11 +395,7 @@ kill_helper (PolkitAgentSession *session)
- session->child_stdout = -1;
- }
-
-- if (session->child_stdin != -1)
-- {
-- g_warn_if_fail (close (session->child_stdin) == 0);
-- session->child_stdin = -1;
-- }
-+ g_clear_object (&session->child_stdin);
-
- session->helper_is_running = FALSE;
-
-@@ -545,9 +541,9 @@ polkit_agent_session_response (PolkitAgentSession *session,
-
- add_newline = (response[response_len] != '\n');
-
-- write (session->child_stdin, response, response_len);
-+ (void) g_output_stream_write_all (session->child_stdin, response, response_len, NULL, NULL, NULL);
- if (add_newline)
-- write (session->child_stdin, newline, 1);
-+ (void) g_output_stream_write_all (session->child_stdin, newline, 1, NULL, NULL, NULL);
- }
-
- /**
-@@ -567,8 +563,9 @@ polkit_agent_session_initiate (PolkitAgentSession *session)
- {
- uid_t uid;
- GError *error;
-- gchar *helper_argv[4];
-+ gchar *helper_argv[3];
- struct passwd *passwd;
-+ int stdin_fd = -1;
-
- g_return_if_fail (POLKIT_AGENT_IS_SESSION (session));
-
-@@ -600,10 +597,8 @@ polkit_agent_session_initiate (PolkitAgentSession *session)
-
- helper_argv[0] = PACKAGE_PREFIX "/lib/polkit-1/polkit-agent-helper-1";
- helper_argv[1] = passwd->pw_name;
-- helper_argv[2] = session->cookie;
-- helper_argv[3] = NULL;
-+ helper_argv[2] = NULL;
-
-- session->child_stdin = -1;
- session->child_stdout = -1;
-
- error = NULL;
-@@ -615,7 +610,7 @@ polkit_agent_session_initiate (PolkitAgentSession *session)
- NULL,
- NULL,
- &session->child_pid,
-- &session->child_stdin,
-+ &stdin_fd,
- &session->child_stdout,
- NULL,
- &error))
-@@ -628,6 +623,13 @@ polkit_agent_session_initiate (PolkitAgentSession *session)
- if (G_UNLIKELY (_show_debug ()))
- g_print ("PolkitAgentSession: spawned helper with pid %d\n", (gint) session->child_pid);
-
-+ session->child_stdin = (GOutputStream*)g_unix_output_stream_new (stdin_fd, TRUE);
-+
-+ /* Write the cookie on stdin so it can't be seen by other processes */
-+ (void) g_output_stream_write_all (session->child_stdin, session->cookie, strlen (session->cookie),
-+ NULL, NULL, NULL);
-+ (void) g_output_stream_write_all (session->child_stdin, "\n", 1, NULL, NULL, NULL);
-+
- session->child_stdout_channel = g_io_channel_unix_new (session->child_stdout);
- session->child_stdout_watch_source = g_io_create_watch (session->child_stdout_channel,
- G_IO_IN | G_IO_ERR | G_IO_HUP);
-diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c
-index 3f339e9..15adc6a 100644
---- a/src/polkitbackend/polkitbackendinteractiveauthority.c
-+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
-@@ -214,6 +214,8 @@ typedef struct
-
- GDBusConnection *system_bus_connection;
- guint name_owner_changed_signal_id;
-+
-+ guint64 agent_serial;
- } PolkitBackendInteractiveAuthorityPrivate;
-
- /* ---------------------------------------------------------------------------------------------------- */
-@@ -439,11 +441,15 @@ struct AuthenticationAgent
- volatile gint ref_count;
-
- PolkitSubject *scope;
-+ guint64 serial;
-
- gchar *locale;
- GVariant *registration_options;
- gchar *object_path;
- gchar *unique_system_bus_name;
-+ GRand *cookie_pool;
-+ gchar *cookie_prefix;
-+ guint64 cookie_serial;
-
- GDBusProxy *proxy;
-
-@@ -1427,9 +1433,54 @@ authentication_session_cancelled_cb (GCancellable *cancellable,
- authentication_session_cancel (session);
- }
-
-+/* We're not calling this a UUID, but it's basically
-+ * the same thing, just not formatted that way because:
-+ *
-+ * - I'm too lazy to do it
-+ * - If we did, people might think it was actually
-+ * generated from /dev/random, which we're not doing
-+ * because this value doesn't actually need to be
-+ * globally unique.
-+ */
-+static void
-+append_rand_u128_str (GString *buf,
-+ GRand *pool)
-+{
-+ g_string_append_printf (buf, "%08x%08x%08x%08x",
-+ g_rand_int (pool),
-+ g_rand_int (pool),
-+ g_rand_int (pool),
-+ g_rand_int (pool));
-+}
-+
-+/* A value that should be unique to the (AuthenticationAgent, AuthenticationSession)
-+ * pair, and not guessable by other agents.
-+ *
-+ * <agent serial> - <agent uuid> - <session serial> - <session uuid>
-+ *
-+ * See http://lists.freedesktop.org/archives/polkit-devel/2015-June/000425.html
-+ *
-+ */
-+static gchar *
-+authentication_agent_generate_cookie (AuthenticationAgent *agent)
-+{
-+ GString *buf = g_string_new ("");
-+
-+ g_string_append (buf, agent->cookie_prefix);
-+
-+ g_string_append_c (buf, '-');
-+ agent->cookie_serial++;
-+ g_string_append_printf (buf, "%" G_GUINT64_FORMAT,
-+ agent->cookie_serial);
-+ g_string_append_c (buf, '-');
-+ append_rand_u128_str (buf, agent->cookie_pool);
-+
-+ return g_string_free (buf, FALSE);
-+}
-+
-+
- static AuthenticationSession *
- authentication_session_new (AuthenticationAgent *agent,
-- const gchar *cookie,
- PolkitSubject *subject,
- PolkitIdentity *user_of_subject,
- PolkitSubject *caller,
-@@ -1447,7 +1498,7 @@ authentication_session_new (AuthenticationAgent *agent,
-
- session = g_new0 (AuthenticationSession, 1);
- session->agent = authentication_agent_ref (agent);
-- session->cookie = g_strdup (cookie);
-+ session->cookie = authentication_agent_generate_cookie (agent);
- session->subject = g_object_ref (subject);
- session->user_of_subject = g_object_ref (user_of_subject);
- session->caller = g_object_ref (caller);
-@@ -1496,16 +1547,6 @@ authentication_session_free (AuthenticationSession *session)
- g_free (session);
- }
-
--static gchar *
--authentication_agent_new_cookie (AuthenticationAgent *agent)
--{
-- static gint counter = 0;
--
-- /* TODO: use a more random-looking cookie */
--
-- return g_strdup_printf ("cookie%d", counter++);
--}
--
- static PolkitSubject *
- authentication_agent_get_scope (AuthenticationAgent *agent)
- {
-@@ -1553,12 +1594,15 @@ authentication_agent_unref (AuthenticationAgent *agent)
- g_free (agent->unique_system_bus_name);
- if (agent->registration_options != NULL)
- g_variant_unref (agent->registration_options);
-+ g_rand_free (agent->cookie_pool);
-+ g_free (agent->cookie_prefix);
- g_free (agent);
- }
- }
-
- static AuthenticationAgent *
--authentication_agent_new (PolkitSubject *scope,
-+authentication_agent_new (guint64 serial,
-+ PolkitSubject *scope,
- const gchar *unique_system_bus_name,
- const gchar *locale,
- const gchar *object_path,
-@@ -1592,6 +1636,7 @@ authentication_agent_new (PolkitSubject *scope,
-
- agent = g_new0 (AuthenticationAgent, 1);
- agent->ref_count = 1;
-+ agent->serial = serial;
- agent->scope = g_object_ref (scope);
- agent->object_path = g_strdup (object_path);
- agent->unique_system_bus_name = g_strdup (unique_system_bus_name);
-@@ -1599,6 +1644,25 @@ authentication_agent_new (PolkitSubject *scope,
- agent->registration_options = registration_options != NULL ? g_variant_ref (registration_options) : NULL;
- agent->proxy = proxy;
-
-+ {
-+ GString *cookie_prefix = g_string_new ("");
-+ GRand *agent_private_rand = g_rand_new ();
-+
-+ g_string_append_printf (cookie_prefix, "%" G_GUINT64_FORMAT "-", agent->serial);
-+
-+ /* Use a uniquely seeded PRNG to get a prefix cookie for this agent,
-+ * whose sequence will not correlate with the per-authentication session
-+ * cookies.
-+ */
-+ append_rand_u128_str (cookie_prefix, agent_private_rand);
-+ g_rand_free (agent_private_rand);
-+
-+ agent->cookie_prefix = g_string_free (cookie_prefix, FALSE);
-+
-+ /* And a newly seeded pool for per-session cookies */
-+ agent->cookie_pool = g_rand_new ();
-+ }
-+
- return agent;
- }
-
-@@ -2193,7 +2257,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent,
- {
- PolkitBackendInteractiveAuthorityPrivate *priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (authority);
- AuthenticationSession *session;
-- gchar *cookie;
- GList *l;
- GList *identities;
- gchar *localized_message;
-@@ -2215,8 +2278,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent,
- &localized_icon_name,
- &localized_details);
-
-- cookie = authentication_agent_new_cookie (agent);
--
- identities = NULL;
-
- /* select admin user if required by the implicit authorization */
-@@ -2279,7 +2340,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent,
- user_identities = g_list_prepend (NULL, polkit_unix_user_new (0));
-
- session = authentication_session_new (agent,
-- cookie,
- subject,
- user_of_subject,
- caller,
-@@ -2335,7 +2395,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent,
- g_list_free_full (user_identities, g_object_unref);
- g_list_foreach (identities, (GFunc) g_object_unref, NULL);
- g_list_free (identities);
-- g_free (cookie);
-
- g_free (localized_message);
- g_free (localized_icon_name);
-@@ -2482,7 +2541,9 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken
- goto out;
- }
-
-- agent = authentication_agent_new (subject,
-+ priv->agent_serial++;
-+ agent = authentication_agent_new (priv->agent_serial,
-+ subject,
- polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)),
- locale,
- object_path,
---
-cgit v0.10.2
-
-From 493aa5dc1d278ab9097110c1262f5229bbaf1766 Mon Sep 17 00:00:00 2001
-From: Colin Walters <walters@redhat.com>
-Date: Wed, 17 Jun 2015 13:07:02 -0400
-Subject: CVE-2015-4625: Bind use of cookies to specific uids
-MIME-Version: 1.0
-Content-Type: text/plain; charset=UTF-8
-Content-Transfer-Encoding: 8bit
-
-http://lists.freedesktop.org/archives/polkit-devel/2015-June/000425.html
-
-The "cookie" value that Polkit hands out is global to all polkit
-users. And when `AuthenticationAgentResponse` is invoked, we
-previously only received the cookie and *target* identity, and
-attempted to find an agent from that.
-
-The problem is that the current cookie is just an integer
-counter, and if it overflowed, it would be possible for
-an successful authorization in one session to trigger a response
-in another session.
-
-The overflow and ability to guess the cookie were fixed by the
-previous patch.
-
-This patch is conceptually further hardening on top of that. Polkit
-currently treats uids as equivalent from a security domain
-perspective; there is no support for
-SELinux/AppArmor/etc. differentiation.
-
-We can retrieve the uid from `getuid()` in the setuid helper, which
-allows us to ensure the uid invoking `AuthenticationAgentResponse2`
-matches that of the agent.
-
-Then the authority only looks at authentication sessions matching the
-cookie that were created by a matching uid, thus removing the ability
-for different uids to interfere with each other entirely.
-
-Several fixes to this patch were contributed by:
-Miloslav Trmač <mitr@redhat.com>
-
-Bug: https://bugs.freedesktop.org/show_bug.cgi?id=90837
-CVE: CVE-2015-4625
-Reported-by: Tavis Ormandy <taviso@google.com>
-Reviewed-by: Miloslav Trmač <mitr@redhat.com>
-Signed-off-by: Colin Walters <walters@redhat.com>
-
-diff --git a/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml b/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml
-index 3b519c2..5beef7d 100644
---- a/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml
-+++ b/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml
-@@ -8,7 +8,19 @@
- <annotation name="org.gtk.EggDBus.DocString" value="<para>This D-Bus interface is used for communication between the system-wide PolicyKit daemon and one or more authentication agents each running in a user session.</para><para>An authentication agent must implement this interface and register (passing the object path of the object implementing the interface) using the org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent() and org.freedesktop.PolicyKit1.Authority.UnregisterAuthenticationAgent() methods on the #org.freedesktop.PolicyKit1.Authority interface of the PolicyKit daemon.</para>"/>
-
- <method name="BeginAuthentication">
-- <annotation name="org.gtk.EggDBus.DocString" value="<para>Called by the PolicyKit daemon when the authentication agent needs the user to authenticate as one of the identities in @identities for the action with the identifier @action_id.</para><para>Upon succesful authentication, the authentication agent must invoke the org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse() method on the #org.freedesktop.PolicyKit1.Authority interface of the PolicyKit daemon before returning.</para><para>If the user dismisses the authentication dialog, the authentication agent should return an error.</para>"/>
-+ <annotation name="org.gtk.EggDBus.DocString" value="<para>Called
-+ by the PolicyKit daemon when the authentication agent needs the
-+ user to authenticate as one of the identities in @identities for
-+ the action with the identifier @action_id.</para><para>This
-+ authentication is normally achieved via the
-+ polkit_agent_session_response() API, which invokes a private
-+ setuid helper process to verify the authentication. When
-+ successful, it calls the
-+ org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse2()
-+ method on the #org.freedesktop.PolicyKit1.Authority interface of
-+ the PolicyKit daemon before returning. If the user dismisses the
-+ authentication dialog, the authentication agent should call
-+ polkit_agent_session_cancel().</para>"/>
-
- <arg name="action_id" direction="in" type="s">
- <annotation name="org.gtk.EggDBus.DocString" value="The identifier for the action that the user is authentication for."/>
-diff --git a/data/org.freedesktop.PolicyKit1.Authority.xml b/data/org.freedesktop.PolicyKit1.Authority.xml
-index fbfb9cd..f9021ee 100644
---- a/data/org.freedesktop.PolicyKit1.Authority.xml
-+++ b/data/org.freedesktop.PolicyKit1.Authority.xml
-@@ -313,7 +313,29 @@
- </method>
-
- <method name="AuthenticationAgentResponse">
-- <annotation name="org.gtk.EggDBus.DocString" value="Method for authentication agents to invoke on successful authentication. This method will fail unless a sufficiently privileged caller invokes it."/>
-+ <annotation name="org.gtk.EggDBus.DocString" value="Method for authentication agents to invoke on successful
-+authentication, intended only for use by a privileged helper process
-+internal to polkit."/>
-+
-+ <arg name="cookie" direction="in" type="s">
-+ <annotation name="org.gtk.EggDBus.DocString" value="The cookie identifying the authentication request that was passed to the authentication agent."/>
-+ </arg>
-+
-+ <arg name="identity" direction="in" type="(sa{sv})">
-+ <annotation name="org.gtk.EggDBus.Type" value="Identity"/>
-+ <annotation name="org.gtk.EggDBus.DocString" value="A #Identity struct describing what identity was authenticated."/>
-+ </arg>
-+ </method>
-+
-+ <method name="AuthenticationAgentResponse2">
-+ <annotation name="org.gtk.EggDBus.DocString" value="Method for authentication agents to invoke on successful
-+authentication, intended only for use by a privileged helper process
-+internal to polkit. Note this method was added in 0.114, and should be preferred over AuthenticationAgentResponse
-+as it fixes a security issue."/>
-+
-+ <arg name="uid" direction="in" type="u">
-+ <annotation name="org.gtk.EggDBus.DocString" value="The real uid of the agent. Normally set by the setuid helper program."/>
-+ </arg>
-
- <arg name="cookie" direction="in" type="s">
- <annotation name="org.gtk.EggDBus.DocString" value="The cookie identifying the authentication request that was passed to the authentication agent."/>
-diff --git a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml
-index 6525e25..e66bf53 100644
---- a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml
-+++ b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml
-@@ -42,6 +42,8 @@ Structure <link linkend="eggdbus-struct-TemporaryAuthorization">TemporaryAuth
- IN String object_path)
- <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse">AuthenticationAgentResponse</link> (IN String cookie,
- IN <link linkend="eggdbus-struct-Identity">Identity</link> identity)
-+<link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse">AuthenticationAgentResponse2</link> (IN uint32 uid, IN String cookie,
-+ IN <link linkend="eggdbus-struct-Identity">Identity</link> identity)
- <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.EnumerateTemporaryAuthorizations">EnumerateTemporaryAuthorizations</link> (IN <link linkend="eggdbus-struct-Subject">Subject</link> subject,
- OUT Array&lt;<link linkend="eggdbus-struct-TemporaryAuthorization">TemporaryAuthorization</link>&gt; temporary_authorizations)
- <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.RevokeTemporaryAuthorizations">RevokeTemporaryAuthorizations</link> (IN <link linkend="eggdbus-struct-Subject">Subject</link> subject)
-@@ -777,10 +779,52 @@ AuthenticationAgentResponse (IN String cookie,
- IN <link linkend="eggdbus-struct-Identity">Identity</link> identity)
- </programlisting>
- <para>
--Method for authentication agents to invoke on successful authentication. This method will fail unless a sufficiently privileged caller invokes it.
-+Method for authentication agents to invoke on successful
-+authentication, intended only for use by a privileged helper process
-+internal to polkit. Deprecated in favor of AuthenticationAgentResponse2.
-+ </para>
-+<variablelist role="params">
-+ <varlistentry>
-+ <term><literal>IN String <parameter>cookie</parameter></literal>:</term>
-+ <listitem>
-+ <para>
-+The cookie identifying the authentication request that was passed to the authentication agent.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
-+ <term><literal>IN <link linkend="eggdbus-struct-Identity">Identity</link> <parameter>identity</parameter></literal>:</term>
-+ <listitem>
-+ <para>
-+A <link linkend="eggdbus-struct-Identity">Identity</link> struct describing what identity was authenticated.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+</variablelist>
-+ </refsect2>
-+ <refsect2 role="function" id="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse2">
-+ <title>AuthenticationAgentResponse2 ()</title>
-+ <programlisting>
-+AuthenticationAgentResponse2 (IN uint32 uid,
-+ IN String cookie,
-+ IN <link linkend="eggdbus-struct-Identity">Identity</link> identity)
-+ </programlisting>
-+ <para>
-+Method for authentication agents to invoke on successful
-+authentication, intended only for use by a privileged helper process
-+internal to polkit. Note this method was introduced in 0.114 to fix a security issue.
- </para>
- <variablelist role="params">
- <varlistentry>
-+ <term><literal>IN uint32 <parameter>uid</parameter></literal>:</term>
-+ <listitem>
-+ <para>
-+The user id of the agent; normally this is the owner of the parent pid
-+of the process that invoked the internal setuid helper.
-+ </para>
-+ </listitem>
-+ </varlistentry>
-+ <varlistentry>
- <term><literal>IN String <parameter>cookie</parameter></literal>:</term>
- <listitem>
- <para>
-diff --git a/docs/polkit/overview.xml b/docs/polkit/overview.xml
-index 150a7bc..176d2ea 100644
---- a/docs/polkit/overview.xml
-+++ b/docs/polkit/overview.xml
-@@ -314,16 +314,18 @@
- <para>
- Authentication agents are provided by desktop environments. When
- an user session starts, the agent registers with the polkit
-- Authority using
-- the <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent">RegisterAuthenticationAgent()</link>
-+ Authority using the <link
-+ linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent">RegisterAuthenticationAgent()</link>
- method. When services are needed, the authority will invoke
-- methods on
-- the <link linkend="eggdbus-interface-org.freedesktop.PolicyKit1.AuthenticationAgent">org.freedesktop.PolicyKit1.AuthenticationAgent</link>
-+ methods on the <link
-+ linkend="eggdbus-interface-org.freedesktop.PolicyKit1.AuthenticationAgent">org.freedesktop.PolicyKit1.AuthenticationAgent</link>
- D-Bus interface. Once the user is authenticated, (a privileged
-- part of) the agent invokes
-- the <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse">AuthenticationAgentResponse()</link>
-- method. Note that the polkit Authority itself does not care
-- how the agent authenticates the user.
-+ part of) the agent invokes the <link
-+ linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse">AuthenticationAgentResponse()</link>
-+ method. This method should be treated as an internal
-+ implementation detail, and callers should use the public shared
-+ library API to invoke it, which currently uses a setuid helper
-+ program.
- </para>
- <para>
- The <link linkend="ref-authentication-agent-api">libpolkit-agent-1</link>
-diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c
-index ab6d3cd..6bd684a 100644
---- a/src/polkit/polkitauthority.c
-+++ b/src/polkit/polkitauthority.c
-@@ -1492,6 +1492,14 @@ polkit_authority_authentication_agent_response (PolkitAuthority *authority,
- gpointer user_data)
- {
- GVariant *identity_value;
-+ /* Note that in reality, this API is only accessible to root, and
-+ * only called from the setuid helper `polkit-agent-helper-1`.
-+ *
-+ * However, because this is currently public API, we avoid
-+ * triggering warnings from ABI diff type programs by just grabbing
-+ * the real uid of the caller here.
-+ */
-+ uid_t uid = getuid ();
-
- g_return_if_fail (POLKIT_IS_AUTHORITY (authority));
- g_return_if_fail (cookie != NULL);
-@@ -1501,8 +1509,9 @@ polkit_authority_authentication_agent_response (PolkitAuthority *authority,
- identity_value = polkit_identity_to_gvariant (identity);
- g_variant_ref_sink (identity_value);
- g_dbus_proxy_call (authority->proxy,
-- "AuthenticationAgentResponse",
-- g_variant_new ("(s@(sa{sv}))",
-+ "AuthenticationAgentResponse2",
-+ g_variant_new ("(us@(sa{sv}))",
-+ (guint32)uid,
- cookie,
- identity_value),
- G_DBUS_CALL_FLAGS_NONE,
-diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c
-index 601a974..03a4e84 100644
---- a/src/polkitbackend/polkitbackendauthority.c
-+++ b/src/polkitbackend/polkitbackendauthority.c
-@@ -355,6 +355,7 @@ polkit_backend_authority_unregister_authentication_agent (PolkitBackendAuthority
- gboolean
- polkit_backend_authority_authentication_agent_response (PolkitBackendAuthority *authority,
- PolkitSubject *caller,
-+ uid_t uid,
- const gchar *cookie,
- PolkitIdentity *identity,
- GError **error)
-@@ -373,7 +374,7 @@ polkit_backend_authority_authentication_agent_response (PolkitBackendAuthority
- }
- else
- {
-- return klass->authentication_agent_response (authority, caller, cookie, identity, error);
-+ return klass->authentication_agent_response (authority, caller, uid, cookie, identity, error);
- }
- }
-
-@@ -587,6 +588,11 @@ static const gchar *server_introspection_data =
- " <arg type='s' name='cookie' direction='in'/>"
- " <arg type='(sa{sv})' name='identity' direction='in'/>"
- " </method>"
-+ " <method name='AuthenticationAgentResponse2'>"
-+ " <arg type='u' name='uid' direction='in'/>"
-+ " <arg type='s' name='cookie' direction='in'/>"
-+ " <arg type='(sa{sv})' name='identity' direction='in'/>"
-+ " </method>"
- " <method name='EnumerateTemporaryAuthorizations'>"
- " <arg type='(sa{sv})' name='subject' direction='in'/>"
- " <arg type='a(ss(sa{sv})tt)' name='temporary_authorizations' direction='out'/>"
-@@ -1035,6 +1041,57 @@ server_handle_authentication_agent_response (Server *server,
- error = NULL;
- if (!polkit_backend_authority_authentication_agent_response (server->authority,
- caller,
-+ (uid_t)-1,
-+ cookie,
-+ identity,
-+ &error))
-+ {
-+ g_dbus_method_invocation_return_gerror (invocation, error);
-+ g_error_free (error);
-+ goto out;
-+ }
-+
-+ g_dbus_method_invocation_return_value (invocation, g_variant_new ("()"));
-+
-+ out:
-+ if (identity != NULL)
-+ g_object_unref (identity);
-+}
-+
-+static void
-+server_handle_authentication_agent_response2 (Server *server,
-+ GVariant *parameters,
-+ PolkitSubject *caller,
-+ GDBusMethodInvocation *invocation)
-+{
-+ const gchar *cookie;
-+ GVariant *identity_gvariant;
-+ PolkitIdentity *identity;
-+ GError *error;
-+ guint32 uid;
-+
-+ identity = NULL;
-+
-+ g_variant_get (parameters,
-+ "(u&s@(sa{sv}))",
-+ &uid,
-+ &cookie,
-+ &identity_gvariant);
-+
-+ error = NULL;
-+ identity = polkit_identity_new_for_gvariant (identity_gvariant, &error);
-+ if (identity == NULL)
-+ {
-+ g_prefix_error (&error, "Error getting identity: ");
-+ g_dbus_method_invocation_return_gerror (invocation, error);
-+ g_error_free (error);
-+ goto out;
-+ }
-+
-+ error = NULL;
-+ if (!polkit_backend_authority_authentication_agent_response (server->authority,
-+ caller,
-+ (uid_t)uid,
- cookie,
- identity,
- &error))
-@@ -1222,6 +1279,8 @@ server_handle_method_call (GDBusConnection *connection,
- server_handle_unregister_authentication_agent (server, parameters, caller, invocation);
- else if (g_strcmp0 (method_name, "AuthenticationAgentResponse") == 0)
- server_handle_authentication_agent_response (server, parameters, caller, invocation);
-+ else if (g_strcmp0 (method_name, "AuthenticationAgentResponse2") == 0)
-+ server_handle_authentication_agent_response2 (server, parameters, caller, invocation);
- else if (g_strcmp0 (method_name, "EnumerateTemporaryAuthorizations") == 0)
- server_handle_enumerate_temporary_authorizations (server, parameters, caller, invocation);
- else if (g_strcmp0 (method_name, "RevokeTemporaryAuthorizations") == 0)
-diff --git a/src/polkitbackend/polkitbackendauthority.h b/src/polkitbackend/polkitbackendauthority.h
-index f9f7385..88df82e 100644
---- a/src/polkitbackend/polkitbackendauthority.h
-+++ b/src/polkitbackend/polkitbackendauthority.h
-@@ -147,6 +147,7 @@ struct _PolkitBackendAuthorityClass
-
- gboolean (*authentication_agent_response) (PolkitBackendAuthority *authority,
- PolkitSubject *caller,
-+ uid_t uid,
- const gchar *cookie,
- PolkitIdentity *identity,
- GError **error);
-@@ -249,6 +250,7 @@ gboolean polkit_backend_authority_unregister_authentication_agent (PolkitBackend
-
- gboolean polkit_backend_authority_authentication_agent_response (PolkitBackendAuthority *authority,
- PolkitSubject *caller,
-+ uid_t uid,
- const gchar *cookie,
- PolkitIdentity *identity,
- GError **error);
-diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c
-index 15adc6a..96725f7 100644
---- a/src/polkitbackend/polkitbackendinteractiveauthority.c
-+++ b/src/polkitbackend/polkitbackendinteractiveauthority.c
-@@ -108,8 +108,9 @@ static AuthenticationAgent *get_authentication_agent_for_subject (PolkitBackendI
- PolkitSubject *subject);
-
-
--static AuthenticationSession *get_authentication_session_for_cookie (PolkitBackendInteractiveAuthority *authority,
-- const gchar *cookie);
-+static AuthenticationSession *get_authentication_session_for_uid_and_cookie (PolkitBackendInteractiveAuthority *authority,
-+ uid_t uid,
-+ const gchar *cookie);
-
- static GList *get_authentication_sessions_initiated_by_system_bus_unique_name (PolkitBackendInteractiveAuthority *authority,
- const gchar *system_bus_unique_name);
-@@ -169,6 +170,7 @@ static gboolean polkit_backend_interactive_authority_unregister_authentication_a
-
- static gboolean polkit_backend_interactive_authority_authentication_agent_response (PolkitBackendAuthority *authority,
- PolkitSubject *caller,
-+ uid_t uid,
- const gchar *cookie,
- PolkitIdentity *identity,
- GError **error);
-@@ -440,6 +442,7 @@ struct AuthenticationAgent
- {
- volatile gint ref_count;
-
-+ uid_t creator_uid;
- PolkitSubject *scope;
- guint64 serial;
-
-@@ -1603,6 +1606,7 @@ authentication_agent_unref (AuthenticationAgent *agent)
- static AuthenticationAgent *
- authentication_agent_new (guint64 serial,
- PolkitSubject *scope,
-+ PolkitIdentity *creator,
- const gchar *unique_system_bus_name,
- const gchar *locale,
- const gchar *object_path,
-@@ -1611,6 +1615,10 @@ authentication_agent_new (guint64 serial,
- {
- AuthenticationAgent *agent;
- GDBusProxy *proxy;
-+ PolkitUnixUser *creator_user;
-+
-+ g_assert (POLKIT_IS_UNIX_USER (creator));
-+ creator_user = POLKIT_UNIX_USER (creator);
-
- if (!g_variant_is_object_path (object_path))
- {
-@@ -1638,6 +1646,7 @@ authentication_agent_new (guint64 serial,
- agent->ref_count = 1;
- agent->serial = serial;
- agent->scope = g_object_ref (scope);
-+ agent->creator_uid = (uid_t)polkit_unix_user_get_uid (creator_user);
- agent->object_path = g_strdup (object_path);
- agent->unique_system_bus_name = g_strdup (unique_system_bus_name);
- agent->locale = g_strdup (locale);
-@@ -1736,8 +1745,9 @@ get_authentication_agent_for_subject (PolkitBackendInteractiveAuthority *authori
- }
-
- static AuthenticationSession *
--get_authentication_session_for_cookie (PolkitBackendInteractiveAuthority *authority,
-- const gchar *cookie)
-+get_authentication_session_for_uid_and_cookie (PolkitBackendInteractiveAuthority *authority,
-+ uid_t uid,
-+ const gchar *cookie)
- {
- PolkitBackendInteractiveAuthorityPrivate *priv;
- GHashTableIter hash_iter;
-@@ -1755,6 +1765,23 @@ get_authentication_session_for_cookie (PolkitBackendInteractiveAuthority *author
- {
- GList *l;
-
-+ /* We need to ensure that if somehow we have duplicate cookies
-+ * due to wrapping, that the cookie used is matched to the user
-+ * who called AuthenticationAgentResponse2. See
-+ * http://lists.freedesktop.org/archives/polkit-devel/2015-June/000425.html
-+ *
-+ * Except if the legacy AuthenticationAgentResponse is invoked,
-+ * we don't know the uid and hence use -1. Continue to support
-+ * the old behavior for backwards compatibility, although everyone
-+ * who is using our own setuid helper will automatically be updated
-+ * to the new API.
-+ */
-+ if (uid != (uid_t)-1)
-+ {
-+ if (agent->creator_uid != uid)
-+ continue;
-+ }
-+
- for (l = agent->active_sessions; l != NULL; l = l->next)
- {
- AuthenticationSession *session = l->data;
-@@ -2544,6 +2571,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken
- priv->agent_serial++;
- agent = authentication_agent_new (priv->agent_serial,
- subject,
-+ user_of_caller,
- polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)),
- locale,
- object_path,
-@@ -2757,6 +2785,7 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack
- static gboolean
- polkit_backend_interactive_authority_authentication_agent_response (PolkitBackendAuthority *authority,
- PolkitSubject *caller,
-+ uid_t uid,
- const gchar *cookie,
- PolkitIdentity *identity,
- GError **error)
-@@ -2799,7 +2828,7 @@ polkit_backend_interactive_authority_authentication_agent_response (PolkitBacken
- }
-
- /* find the authentication session */
-- session = get_authentication_session_for_cookie (interactive_authority, cookie);
-+ session = get_authentication_session_for_uid_and_cookie (interactive_authority, uid, cookie);
- if (session == NULL)
- {
- g_set_error (error,
---
-cgit v0.10.2
-
---- ./configure.ac.orig
-+++ ./configure.ac
-@@ -122,7 +122,7 @@
- changequote([,])dnl
- fi
-
--PKG_CHECK_MODULES(GLIB, [gio-2.0 >= 2.28.0])
-+PKG_CHECK_MODULES(GLIB, [gmodule-2.0 gio-unix-2.0 gio-2.0 >= 2.30.0])
- AC_SUBST(GLIB_CFLAGS)
- AC_SUBST(GLIB_LIBS)
-