summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorA. Wilcox <AWilcox@Wilcox-Tech.com>2018-02-20 22:02:02 -0600
committerA. Wilcox <AWilcox@Wilcox-Tech.com>2018-02-20 22:02:02 -0600
commitee33a1a838ae6aa5bdb1de6688c79883d9e35fe3 (patch)
treeb5b4825c22251afb02abf8cf5bcf6a9e90b9291b
parent0007a6ccd7d5975b19c9033eb7bc2ce3aa98f35b (diff)
downloadpackages-ee33a1a838ae6aa5bdb1de6688c79883d9e35fe3.tar.gz
packages-ee33a1a838ae6aa5bdb1de6688c79883d9e35fe3.tar.bz2
packages-ee33a1a838ae6aa5bdb1de6688c79883d9e35fe3.tar.xz
packages-ee33a1a838ae6aa5bdb1de6688c79883d9e35fe3.zip
system/polkit: add PAM-enabled PolicyKit
-rw-r--r--system/polkit/0001-Bug-50145-make-netgroup-support-optional.patch108
-rw-r--r--system/polkit/APKBUILD80
-rw-r--r--system/polkit/CVE-2013-4288.patch123
-rw-r--r--system/polkit/CVE-2015-3218.patch115
-rw-r--r--system/polkit/CVE-2015-3255.patch67
-rw-r--r--system/polkit/CVE-2015-4625.patch1008
-rw-r--r--system/polkit/automake.patch19
-rw-r--r--system/polkit/disable-ck-test.patch15
-rw-r--r--system/polkit/fix-consolekit-db-stat.patch30
-rw-r--r--system/polkit/fix-parallel-make.patch40
-rw-r--r--system/polkit/fix-test-fgetpwent.patch20
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&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)
+
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>