diff options
Diffstat (limited to 'system/polkit')
-rw-r--r-- | system/polkit/0001-Bug-50145-make-netgroup-support-optional.patch | 108 | ||||
-rw-r--r-- | system/polkit/APKBUILD | 80 | ||||
-rw-r--r-- | system/polkit/CVE-2013-4288.patch | 123 | ||||
-rw-r--r-- | system/polkit/CVE-2015-3218.patch | 115 | ||||
-rw-r--r-- | system/polkit/CVE-2015-3255.patch | 67 | ||||
-rw-r--r-- | system/polkit/CVE-2015-4625.patch | 1008 | ||||
-rw-r--r-- | system/polkit/automake.patch | 19 | ||||
-rw-r--r-- | system/polkit/disable-ck-test.patch | 15 | ||||
-rw-r--r-- | system/polkit/fix-consolekit-db-stat.patch | 30 | ||||
-rw-r--r-- | system/polkit/fix-parallel-make.patch | 40 | ||||
-rw-r--r-- | system/polkit/fix-test-fgetpwent.patch | 20 |
11 files changed, 1625 insertions, 0 deletions
diff --git a/system/polkit/0001-Bug-50145-make-netgroup-support-optional.patch b/system/polkit/0001-Bug-50145-make-netgroup-support-optional.patch new file mode 100644 index 000000000..1498e831a --- /dev/null +++ b/system/polkit/0001-Bug-50145-make-netgroup-support-optional.patch @@ -0,0 +1,108 @@ +From 2428beec9189bb93e6e1fdd5bdde35acf5279a03 Mon Sep 17 00:00:00 2001 +From: Natanael Copa <ncopa@alpinelinux.org> +Date: Sun, 20 May 2012 15:42:56 +0200 +Subject: [PATCH] Bug 50145 - make netgroup support optional + +https://bugs.freedesktop.org/show_bug.cgi?id=50145 + +netgroups are not defined in POSIX and are not be available on +all systems. + +We check for getnetgrent in configure script. + +Signed-off-by: Natanael Copa <ncopa@alpinelinux.org> +--- + configure.ac | 2 +- + src/polkitbackend/polkitbackendlocalauthority.c | 8 ++++++-- + src/polkitbackend/polkitbackendlocalauthorizationstore.c | 3 ++- + 3 files changed, 9 insertions(+), 4 deletions(-) + +diff --git a/configure.ac b/configure.ac +index f325922..711aa7c 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -141,7 +141,7 @@ AC_CHECK_LIB(expat,XML_ParserCreate,[EXPAT_LIBS="-lexpat"], + [AC_MSG_ERROR([Can't find expat library. Please install expat.])]) + AC_SUBST(EXPAT_LIBS) + +-AC_CHECK_FUNCS(clearenv) ++AC_CHECK_FUNCS(clearenv getnetgrent) + + if test "x$GCC" = "xyes"; then + LDFLAGS="-Wl,--as-needed $LDFLAGS" +diff --git a/src/polkitbackend/polkitbackendlocalauthority.c b/src/polkitbackend/polkitbackendlocalauthority.c +index b53eda3..f14e924 100644 +--- a/src/polkitbackend/polkitbackendlocalauthority.c ++++ b/src/polkitbackend/polkitbackendlocalauthority.c +@@ -52,9 +52,10 @@ + + static GList *get_users_in_group (PolkitIdentity *group, + gboolean include_root); +- ++#if defined HAVE_GETNETGRENT + static GList *get_users_in_net_group (PolkitIdentity *group, + gboolean include_root); ++#endif + + static GList *get_groups_for_user (PolkitIdentity *user); + +@@ -511,10 +512,12 @@ polkit_backend_local_authority_get_admin_auth_identities (PolkitBackendInteracti + { + ret = g_list_concat (ret, get_users_in_group (identity, FALSE)); + } ++#if defined HAVE_GETNETGRENT + else if (POLKIT_IS_UNIX_NETGROUP (identity)) + { + ret = g_list_concat (ret, get_users_in_net_group (identity, FALSE)); + } ++#endif + else + { + g_warning ("Unsupported identity %s", admin_identities[n]); +@@ -690,6 +693,7 @@ get_users_in_group (PolkitIdentity *group, + return ret; + } + ++#if defined HAVE_GETNETGRENT + static GList * + get_users_in_net_group (PolkitIdentity *group, + gboolean include_root) +@@ -741,7 +745,7 @@ get_users_in_net_group (PolkitIdentity *group, + endnetgrent (); + return ret; + } +- ++#endif + + static GList * + get_groups_for_user (PolkitIdentity *user) +diff --git a/src/polkitbackend/polkitbackendlocalauthorizationstore.c b/src/polkitbackend/polkitbackendlocalauthorizationstore.c +index 2ddfe75..02553c4 100644 +--- a/src/polkitbackend/polkitbackendlocalauthorizationstore.c ++++ b/src/polkitbackend/polkitbackendlocalauthorizationstore.c +@@ -725,6 +725,7 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization + break; + } + ++#if defined HAVE_GETNETGRENT + /* if no identity specs matched and identity is a user, match against netgroups */ + if (ll == NULL && POLKIT_IS_UNIX_USER (identity)) + { +@@ -732,13 +733,13 @@ polkit_backend_local_authorization_store_lookup (PolkitBackendLocalAuthorization + const gchar *user_name = polkit_unix_user_get_name (user_identity); + if (!user_name) + continue; +- + for (ll = authorization->netgroup_identities; ll != NULL; ll = ll->next) + { + if (innetgr ((const gchar *) ll->data, NULL, user_name, NULL)) + break; + } + } ++#endif + + if (ll == NULL) + continue; +-- +1.7.10.2 + diff --git a/system/polkit/APKBUILD b/system/polkit/APKBUILD new file mode 100644 index 000000000..fdc37d634 --- /dev/null +++ b/system/polkit/APKBUILD @@ -0,0 +1,80 @@ +# Contributor: Carlo Landmeter +# Maintainer: Natanael Copa <ncopa@alpinelinux.org> +pkgname=polkit +pkgver=0.105 +pkgrel=8 +pkgdesc="Application development toolkit for controlling system-wide privileges" +url="http://www.freedesktop.org/wiki/Software/polkit/" +arch="all" +license="LGPL" +depends= +options="suid" +depends_dev="eggdbus-dev dbus-glib-dev linux-pam-dev" +makedepends="$depends_dev expat-dev glib-dev gtk-doc gobject-introspection-dev + intltool autoconf automake libtool" +install= +subpackages="$pkgname-dev $pkgname-doc $pkgname-lang" +source="http://www.freedesktop.org/software/polkit/releases/polkit-$pkgver.tar.gz + 0001-Bug-50145-make-netgroup-support-optional.patch + CVE-2013-4288.patch + CVE-2015-3218.patch + CVE-2015-3255.patch + CVE-2015-4625.patch + automake.patch + fix-parallel-make.patch + fix-consolekit-db-stat.patch + fix-test-fgetpwent.patch + disable-ck-test.patch +" + +prepare() { + cd "$builddir" + update_config_sub + default_prepare + libtoolize --force && aclocal && autoconf && automake --add-missing +} + +build() { + cd "$builddir" + ./configure \ + --build=$CBUILD \ + --host=$CHOST \ + --prefix=/usr \ + --sysconfdir=/etc \ + --mandir=/usr/share/man \ + --infodir=/usr/share/info \ + --libexecdir=/usr/lib/polkit-1 \ + --localstatedir=/var \ + --disable-static \ + --enable-nls \ + --enable-introspection \ + --with-os-type=alpine \ + --with-pam-include=base-auth \ + --disable-gtk-doc \ + --disable-gtk-doc-html \ + --disable-gtk-doc-pdf + + make +} + +check() { + cd "$builddir" + make check +} + +package() { + cd "$builddir" + make DESTDIR="$pkgdir" install +} + +sha512sums="7c0f84b9639814b4690e42b570285ff2018a5ea4cfd7216d9abf44c84ece6592c530f2d6211511c1346963daf4f135e9fa79d1b2f592b454115950991b5e4bc3 polkit-0.105.tar.gz +09ca9c14044c0a281e9069919efbb6d14918f23f58a282b5ce25c8a6640966396904373822869fe994c711f40c33d5c34cf3b77f85a59e239ba3d0c22a31ca8e 0001-Bug-50145-make-netgroup-support-optional.patch +d6de3beb063243c11906f525ef2eb65aeca823c25b1f44dde4a16f4fc2c5ce587b129e0bfb25a4a4b88ac2bf5713c47e57700c139323d961c9f9b6ba4c03fffb CVE-2013-4288.patch +625be61ca38267508bb360002c410414f7ca814487f4a51257906118731e208be0c90d21f45ac90fd9f64f2f5937fa1e312d6900179853fabbaaf5e75073c82c CVE-2015-3218.patch +0b26b819da0b34f10ff8a768850560b3207a6e10a7141bd1aa4769c1cb2829eb110164974b99d993d4e3a62145ace0fc5375489f84d2b56fe08e3430e3232aa8 CVE-2015-3255.patch +32ecc38db938fc1e3d14ffd9c492d12a42a91750e0eb1f66f8346d0cefd6e18fd0dffac8bffc65578cfb56c9598d3b336721477e8496de2619d6d69f1a6b309e CVE-2015-4625.patch +25465a23332247d0873e24cb5f011a267413615526755a8295a6367d64fc5eb8c2aa3c9c1fdcfa183b39e3ece14f33b25f15a339d966a31f3feb861b3f17adbf automake.patch +6b0d9262ba8b3c000acdcc8c86bd6fc043e5750a0155730638d4e3a92e63f43cb476d63b11856c041d60d8f38f7eb5ada0eb0eced9100bdac3bc2c7dd5108ddd fix-parallel-make.patch +95493ef842b46ce9e724933a5d86083589075fb452435057b8f629643cac7c7eff67a24fd188087987e98057f0130757fad546d0c090767da3d71ebaf8485a24 fix-consolekit-db-stat.patch +966825aded565432f4fda9e54113a773b514ebf7ee7faa83bcb8b97d218ae84a8707d6747bbc3cb8a828638d692fdef34c05038f150ad38e02a29f2c782aba5b fix-test-fgetpwent.patch +f73ab05ab5fdc90d3961fdcf88fa57eee8c90af4960b20d7ac845d2395c4cc20873ddc72bfd00fd127471336807faa705d0845444a0218343e74063e8f190980 disable-ck-test.patch" diff --git a/system/polkit/CVE-2013-4288.patch b/system/polkit/CVE-2013-4288.patch new file mode 100644 index 000000000..0ca8131e8 --- /dev/null +++ b/system/polkit/CVE-2013-4288.patch @@ -0,0 +1,123 @@ +From a3fa3b86f0015e42a534526ed800bcde5b3f2a15 Mon Sep 17 00:00:00 2001 +From: Colin Walters <walters@verbum.org> +Date: Mon, 19 Aug 2013 12:16:11 -0400 +Subject: [PATCH] pkcheck: Support --process=pid,start-time,uid syntax too + +The uid is a new addition; this allows callers such as libvirt to +close a race condition in reading the uid of the process talking to +them. They can read it via getsockopt(SO_PEERCRED) or equivalent, +rather than having pkcheck look at /proc later after the fact. + +Programs which invoke pkcheck but need to know beforehand (i.e. at +compile time) whether or not it supports passing the uid can +use: + +pkcheck_supports_uid=$($PKG_CONFIG --variable pkcheck_supports_uid polkit-gobject-1) +test x$pkcheck_supports_uid = xyes + +Conflicts: + docs/man/pkcheck.xml + src/programs/pkcheck.c +--- + data/polkit-gobject-1.pc.in | 3 +++ + docs/man/pkcheck.xml | 33 +++++++++++++++++++++------------ + src/programs/pkcheck.c | 7 ++++++- + 3 files changed, 30 insertions(+), 13 deletions(-) + +diff --git a/data/polkit-gobject-1.pc.in b/data/polkit-gobject-1.pc.in +index c39677d..5c4c620 100644 +--- a/data/polkit-gobject-1.pc.in ++++ b/data/polkit-gobject-1.pc.in +@@ -11,3 +11,6 @@ Version: @VERSION@ + Libs: -L${libdir} -lpolkit-gobject-1 + Cflags: -I${includedir}/polkit-1 + Requires: gio-2.0 >= 2.18 glib-2.0 >= 2.18 ++# Programs using pkcheck can use this to determine ++# whether or not it can be passed a uid. ++pkcheck_supports_uid=true +diff --git a/docs/man/pkcheck.xml b/docs/man/pkcheck.xml +index 6b8a874..9f2faef 100644 +--- a/docs/man/pkcheck.xml ++++ b/docs/man/pkcheck.xml +@@ -55,6 +55,9 @@ + <arg choice="plain"> + <replaceable>pid,pid-start-time</replaceable> + </arg> ++ <arg choice="plain"> ++ <replaceable>pid,pid-start-time,uid</replaceable> ++ </arg> + </group> + </arg> + <arg choice="plain"> +@@ -90,7 +93,7 @@ + <title>DESCRIPTION</title> + <para> + <command>pkcheck</command> is used to check whether a process, specified by +- either <option>--process</option> or <option>--system-bus-name</option>, ++ either <option>--process</option> (see below) or <option>--system-bus-name</option>, + is authorized for <replaceable>action</replaceable>. The <option>--detail</option> + option can be used zero or more times to pass details about <replaceable>action</replaceable>. + If <option>--allow-user-interaction</option> is passed, <command>pkcheck</command> blocks +@@ -160,17 +163,23 @@ KEY3=VALUE3 + <refsect1 id="pkcheck-notes"> + <title>NOTES</title> + <para> +- Since process identifiers can be recycled, the caller should always use +- <replaceable>pid,pid-start-time</replaceable> to specify the process +- to check for authorization when using the <option>--process</option> option. +- The value of <replaceable>pid-start-time</replaceable> +- can be determined by consulting e.g. the +- <citerefentry> +- <refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum> +- </citerefentry> +- file system depending on the operating system. If only <replaceable>pid</replaceable> +- is passed to the <option>--process</option> option, then <command>pkcheck</command> +- will look up the start time itself but note that this may be racy. ++ Do not use either the bare <replaceable>pid</replaceable> or ++ <replaceable>pid,start-time</replaceable> syntax forms for ++ <option>--process</option>. There are race conditions in both. ++ New code should always use ++ <replaceable>pid,pid-start-time,uid</replaceable>. The value of ++ <replaceable>start-time</replaceable> can be determined by ++ consulting e.g. the ++ <citerefentry><refentrytitle>proc</refentrytitle><manvolnum>5</manvolnum></citerefentry> ++ file system depending on the operating system. If fewer than 3 ++ arguments are passed, <command>pkcheck</command> will attempt to ++ look up them up internally, but note that this may be racy. ++ </para> ++ <para> ++ If your program is a daemon with e.g. a custom Unix domain ++ socket, you should determine the <replaceable>uid</replaceable> ++ parameter via operating system mechanisms such as ++ <literal>PEERCRED</literal>. + </para> + </refsect1> + +diff --git a/src/programs/pkcheck.c b/src/programs/pkcheck.c +index 719a36c..057e926 100644 +--- a/src/programs/pkcheck.c ++++ b/src/programs/pkcheck.c +@@ -372,6 +372,7 @@ main (int argc, char *argv[]) + else if (g_strcmp0 (argv[n], "--process") == 0 || g_strcmp0 (argv[n], "-p") == 0) + { + gint pid; ++ guint uid; + guint64 pid_start_time; + + n++; +@@ -381,7 +382,11 @@ main (int argc, char *argv[]) + goto out; + } + +- if (sscanf (argv[n], "%i,%" G_GUINT64_FORMAT, &pid, &pid_start_time) == 2) ++ if (sscanf (argv[n], "%i,%" G_GUINT64_FORMAT ",%u", &pid, &pid_start_time, &uid) == 3) ++ { ++ subject = polkit_unix_process_new_for_owner (pid, pid_start_time, uid); ++ } ++ else if (sscanf (argv[n], "%i,%" G_GUINT64_FORMAT, &pid, &pid_start_time) == 2) + { + subject = polkit_unix_process_new_full (pid, pid_start_time); + } +-- +1.8.5.1 + diff --git a/system/polkit/CVE-2015-3218.patch b/system/polkit/CVE-2015-3218.patch new file mode 100644 index 000000000..977825102 --- /dev/null +++ b/system/polkit/CVE-2015-3218.patch @@ -0,0 +1,115 @@ +From 48e646918efb2bf0b3b505747655726d7869f31c Mon Sep 17 00:00:00 2001 +From: Colin Walters <walters@redhat.com> +Date: Sat, 30 May 2015 09:06:23 -0400 +Subject: CVE-2015-3218: backend: Handle invalid object paths in + RegisterAuthenticationAgent +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Properly propagate the error, otherwise we dereference a `NULL` +pointer. This is a local, authenticated DoS. + +`RegisterAuthenticationAgentWithOptions` and +`UnregisterAuthentication` have been validated to not need changes for +this. + +http://lists.freedesktop.org/archives/polkit-devel/2015-May/000420.html +https://bugs.freedesktop.org/show_bug.cgi?id=90829 + +Reported-by: Tavis Ormandy <taviso@google.com> +Reviewed-by: Philip Withnall <philip@tecnocode.co.uk> +Reviewed-by: Miloslav Trmač <mitr@redhat.com> +Signed-off-by: Colin Walters <walters@redhat.com> + +diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c +index f6ea0fc..587f954 100644 +--- a/src/polkitbackend/polkitbackendinteractiveauthority.c ++++ b/src/polkitbackend/polkitbackendinteractiveauthority.c +@@ -1566,36 +1566,42 @@ authentication_agent_new (PolkitSubject *scope, + const gchar *unique_system_bus_name, + const gchar *locale, + const gchar *object_path, +- GVariant *registration_options) ++ GVariant *registration_options, ++ GError **error) + { + AuthenticationAgent *agent; +- GError *error; ++ GDBusProxy *proxy; + +- agent = g_new0 (AuthenticationAgent, 1); ++ if (!g_variant_is_object_path (object_path)) ++ { ++ g_set_error (error, POLKIT_ERROR, POLKIT_ERROR_FAILED, ++ "Invalid object path '%s'", object_path); ++ return NULL; ++ } ++ ++ proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, ++ G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | ++ G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, ++ NULL, /* GDBusInterfaceInfo* */ ++ unique_system_bus_name, ++ object_path, ++ "org.freedesktop.PolicyKit1.AuthenticationAgent", ++ NULL, /* GCancellable* */ ++ error); ++ if (proxy == NULL) ++ { ++ g_prefix_error (error, "Failed to construct proxy for agent: " ); ++ return NULL; ++ } + ++ agent = g_new0 (AuthenticationAgent, 1); + agent->ref_count = 1; + agent->scope = g_object_ref (scope); + agent->object_path = g_strdup (object_path); + agent->unique_system_bus_name = g_strdup (unique_system_bus_name); + agent->locale = g_strdup (locale); + agent->registration_options = registration_options != NULL ? g_variant_ref (registration_options) : NULL; +- +- error = NULL; +- agent->proxy = g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SYSTEM, +- G_DBUS_PROXY_FLAGS_DO_NOT_LOAD_PROPERTIES | +- G_DBUS_PROXY_FLAGS_DO_NOT_CONNECT_SIGNALS, +- NULL, /* GDBusInterfaceInfo* */ +- agent->unique_system_bus_name, +- agent->object_path, +- "org.freedesktop.PolicyKit1.AuthenticationAgent", +- NULL, /* GCancellable* */ +- &error); +- if (agent->proxy == NULL) +- { +- g_warning ("Error constructing proxy for agent: %s", error->message); +- g_error_free (error); +- /* TODO: Make authentication_agent_new() return NULL and set a GError */ +- } ++ agent->proxy = proxy; + + return agent; + } +@@ -2398,8 +2404,6 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken + caller_cmdline = NULL; + agent = NULL; + +- /* TODO: validate that object path is well-formed */ +- + interactive_authority = POLKIT_BACKEND_INTERACTIVE_AUTHORITY (authority); + priv = POLKIT_BACKEND_INTERACTIVE_AUTHORITY_GET_PRIVATE (interactive_authority); + +@@ -2486,7 +2490,10 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken + polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (caller)), + locale, + object_path, +- options); ++ options, ++ error); ++ if (!agent) ++ goto out; + + g_hash_table_insert (priv->hash_scope_to_authentication_agent, + g_object_ref (subject), +-- +cgit v0.10.2 + diff --git a/system/polkit/CVE-2015-3255.patch b/system/polkit/CVE-2015-3255.patch new file mode 100644 index 000000000..1bd7c6bcf --- /dev/null +++ b/system/polkit/CVE-2015-3255.patch @@ -0,0 +1,67 @@ +From 9f5e0c731784003bd4d6fc75ab739ff8b2ea269f Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Wed, 1 Apr 2015 05:22:37 +0200 +Subject: CVE-2015-3255 Fix GHashTable usage. + +Don't assume that the hash table with free both the key and the value +at the same time, supply proper deallocation functions for the key +and value separately. + +Then drop ParsedAction::action_id which is no longer used for anything. + +https://bugs.freedesktop.org/show_bug.cgi?id=69501 +and +https://bugs.freedesktop.org/show_bug.cgi?id=83590 + +CVE: CVE-2015-3255 + +diff --git a/src/polkitbackend/polkitbackendactionpool.c b/src/polkitbackend/polkitbackendactionpool.c +index bc14381..3894fe9 100644 +--- a/src/polkitbackend/polkitbackendactionpool.c ++++ b/src/polkitbackend/polkitbackendactionpool.c +@@ -40,7 +40,6 @@ + + typedef struct + { +- gchar *action_id; + gchar *vendor_name; + gchar *vendor_url; + gchar *icon_name; +@@ -62,7 +61,6 @@ typedef struct + static void + parsed_action_free (ParsedAction *action) + { +- g_free (action->action_id); + g_free (action->vendor_name); + g_free (action->vendor_url); + g_free (action->icon_name); +@@ -134,7 +132,7 @@ polkit_backend_action_pool_init (PolkitBackendActionPool *pool) + + priv->parsed_actions = g_hash_table_new_full (g_str_hash, + g_str_equal, +- NULL, ++ g_free, + (GDestroyNotify) parsed_action_free); + + priv->parsed_files = g_hash_table_new_full (g_str_hash, +@@ -988,7 +986,6 @@ _end (void *data, const char *el) + icon_name = pd->global_icon_name; + + action = g_new0 (ParsedAction, 1); +- action->action_id = g_strdup (pd->action_id); + action->vendor_name = g_strdup (vendor); + action->vendor_url = g_strdup (vendor_url); + action->icon_name = g_strdup (icon_name); +@@ -1003,7 +1000,8 @@ _end (void *data, const char *el) + action->implicit_authorization_inactive = pd->implicit_authorization_inactive; + action->implicit_authorization_active = pd->implicit_authorization_active; + +- g_hash_table_insert (priv->parsed_actions, action->action_id, action); ++ g_hash_table_insert (priv->parsed_actions, g_strdup (pd->action_id), ++ action); + + /* we steal these hash tables */ + pd->annotations = NULL; +-- +cgit v0.10.2 + diff --git a/system/polkit/CVE-2015-4625.patch b/system/polkit/CVE-2015-4625.patch new file mode 100644 index 000000000..4a43fb433 --- /dev/null +++ b/system/polkit/CVE-2015-4625.patch @@ -0,0 +1,1008 @@ +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<<link linkend="eggdbus-struct-TemporaryAuthorization">TemporaryAuthorization</link>> 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) + diff --git a/system/polkit/automake.patch b/system/polkit/automake.patch new file mode 100644 index 000000000..0f6825a26 --- /dev/null +++ b/system/polkit/automake.patch @@ -0,0 +1,19 @@ +--- ./configure.ac.orig 2012-12-31 21:39:08.969445979 +0000 ++++ ./configure.ac 2012-12-31 21:39:30.136285425 +0000 +@@ -3,7 +3,7 @@ + AC_PREREQ(2.59c) + AC_INIT(polkit, 0.105, http://lists.freedesktop.org/mailman/listinfo/polkit-devel) + AM_INIT_AUTOMAKE(polkit, 0.105) +-AM_CONFIG_HEADER(config.h) ++AC_CONFIG_HEADER(config.h) + AM_MAINTAINER_MODE + + m4_ifdef([AM_SILENT_RULES], [AM_SILENT_RULES([yes])]) +@@ -24,7 +24,6 @@ + + AC_ISC_POSIX + AC_PROG_CC +-AM_PROG_CC_STDC + AC_HEADER_STDC + AM_PROG_LIBTOOL + AC_PROG_MAKE_SET diff --git a/system/polkit/disable-ck-test.patch b/system/polkit/disable-ck-test.patch new file mode 100644 index 000000000..e1987d40d --- /dev/null +++ b/system/polkit/disable-ck-test.patch @@ -0,0 +1,15 @@ +This test requires ConsoleKit to be running. + +--- polkit-0.105/test/polkitbackend/Makefile.am.old 2012-04-24 11:05:34.000000000 -0500 ++++ polkit-0.105/test/polkitbackend/Makefile.am 2017-09-27 20:48:42.479959296 -0500 +@@ -36,8 +36,8 @@ + TEST_PROGS += polkitbackendlocalauthorizationstoretest + polkitbackendlocalauthorizationstoretest_SOURCES = polkitbackendlocalauthorizationstoretest.c + +-TEST_PROGS += polkitbackendlocalauthoritytest +-polkitbackendlocalauthoritytest_SOURCES = polkitbackendlocalauthoritytest.c ++#TEST_PROGS += polkitbackendlocalauthoritytest ++#polkitbackendlocalauthoritytest_SOURCES = polkitbackendlocalauthoritytest.c + + # ---------------------------------------------------------------------------------------------------- + diff --git a/system/polkit/fix-consolekit-db-stat.patch b/system/polkit/fix-consolekit-db-stat.patch new file mode 100644 index 000000000..3deceb639 --- /dev/null +++ b/system/polkit/fix-consolekit-db-stat.patch @@ -0,0 +1,30 @@ +--- polkit-0.105.orig/src/polkitbackend/polkitbackendsessionmonitor.c 2012-04-24 19:05:34.000000000 +0300 ++++ polkit-0.105/src/polkitbackend/polkitbackendsessionmonitor.c 2015-08-17 14:50:51.428580856 +0300 +@@ -47,7 +47,7 @@ struct _PolkitBackendSessionMonitor + + GKeyFile *database; + GFileMonitor *database_monitor; +- time_t database_mtime; ++ struct timespec database_mtim; + }; + + struct _PolkitBackendSessionMonitorClass +@@ -95,7 +95,7 @@ reload_database (PolkitBackendSessionMon + goto out; + } + +- monitor->database_mtime = statbuf.st_mtime; ++ monitor->database_mtim = statbuf.st_mtim; + + monitor->database = g_key_file_new (); + if (!g_key_file_load_from_file (monitor->database, +@@ -131,7 +131,8 @@ ensure_database (PolkitBackendSessionMon + strerror (errno)); + goto out; + } +- if (statbuf.st_mtime == monitor->database_mtime) ++ if (statbuf.st_mtim.tv_sec == monitor->database_mtim.tv_sec && ++ statbuf.st_mtim.tv_nsec == monitor->database_mtim.tv_nsec) + { + ret = TRUE; + goto out; diff --git a/system/polkit/fix-parallel-make.patch b/system/polkit/fix-parallel-make.patch new file mode 100644 index 000000000..b693a34dd --- /dev/null +++ b/system/polkit/fix-parallel-make.patch @@ -0,0 +1,40 @@ +From 7bd30764a5230684c7c979a08a83dfa6e327f719 Mon Sep 17 00:00:00 2001 +From: Ryan Lortie <desrt@velocity.(none)> +Date: Tue, 13 Nov 2012 16:50:14 +0000 +Subject: build: Fix .gir generation for parallel make + +As per the intructions in the introspection Makefile, we should have a +line declaring a dependency between the .gir and .la files. + +https://bugs.freedesktop.org/show_bug.cgi?id=57077 + +Signed-off-by: David Zeuthen <zeuthen@gmail.com> +--- +diff --git a/src/polkit/Makefile.am b/src/polkit/Makefile.am +index 39d6d84..d648d29 100644 +--- a/src/polkit/Makefile.am ++++ b/src/polkit/Makefile.am +@@ -106,6 +106,8 @@ if HAVE_INTROSPECTION + + INTROSPECTION_GIRS = Polkit-1.0.gir + ++Polkit-1.0.gir: libpolkit-gobject-1.la ++ + girdir = $(INTROSPECTION_GIRDIR) + gir_DATA = Polkit-1.0.gir + +diff --git a/src/polkitagent/Makefile.am b/src/polkitagent/Makefile.am +index 1cfb73c..5b7d4c7 100644 +--- a/src/polkitagent/Makefile.am ++++ b/src/polkitagent/Makefile.am +@@ -108,6 +108,8 @@ if HAVE_INTROSPECTION + girdir = $(INTROSPECTION_GIRDIR) + gir_DATA = PolkitAgent-1.0.gir + ++PolkitAgent-1.0.gir: libpolkit-agent-1.la ++ + typelibsdir = $(INTROSPECTION_TYPELIBDIR) + typelibs_DATA = PolkitAgent-1.0.typelib + +-- +cgit v0.9.0.2-2-gbebe diff --git a/system/polkit/fix-test-fgetpwent.patch b/system/polkit/fix-test-fgetpwent.patch new file mode 100644 index 000000000..7bc6481cc --- /dev/null +++ b/system/polkit/fix-test-fgetpwent.patch @@ -0,0 +1,20 @@ +--- polkit-0.105/test/mocklibc/src/pwd.c.old 2012-04-24 11:05:34.000000000 -0500 ++++ polkit-0.105/test/mocklibc/src/pwd.c 2017-09-27 19:40:57.883227673 -0500 +@@ -16,6 +16,7 @@ + * Author: Nikki VonHollen <vonhollen@gmail.com> + */ + ++#define _GNU_SOURCE + #include <pwd.h> + + #include <stdio.h> +--- polkit-0.105/test/mocklibc/src/grp.c.old 2012-04-24 11:05:34.000000000 -0500 ++++ polkit-0.105/test/mocklibc/src/grp.c 2017-09-27 19:44:57.759238450 -0500 +@@ -16,6 +16,7 @@ + * Author: Nikki VonHollen <vonhollen@gmail.com> + */ + ++#define _GNU_SOURCE + #include <grp.h> + + #include <stdio.h> |