diff options
author | Michael Olbrich <m.olbrich@pengutronix.de> | 2019-01-17 09:32:40 +0100 |
---|---|---|
committer | Michael Olbrich <m.olbrich@pengutronix.de> | 2019-01-17 09:38:14 +0100 |
commit | 6bf3ad9ea9cee02ca61228bb4480d7615b89b1c7 (patch) | |
tree | 8bfd5f463d90a46cf0b986af6f36b814d94ac2b7 /patches/polkit-0.105 | |
parent | b65c9c3698750d98b0d36fec8fb3a0153b5c6c79 (diff) | |
download | ptxdist-6bf3ad9ea9cee02ca61228bb4480d7615b89b1c7.tar.gz ptxdist-6bf3ad9ea9cee02ca61228bb4480d7615b89b1c7.tar.xz |
polkit: add debian patches
Based on a patch from Florian Bäuerle <florian.baeuerle@allegion.com>
Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de>
Diffstat (limited to 'patches/polkit-0.105')
46 files changed, 4548 insertions, 25 deletions
diff --git a/patches/polkit-0.105/0001-0.106-agenthelper-pam-Fix-newline-trimming-code.patch b/patches/polkit-0.105/0001-0.106-agenthelper-pam-Fix-newline-trimming-code.patch new file mode 100644 index 000000000..0dcef786f --- /dev/null +++ b/patches/polkit-0.105/0001-0.106-agenthelper-pam-Fix-newline-trimming-code.patch @@ -0,0 +1,47 @@ +From: Colin Walters <walters@verbum.org> +Date: Wed, 6 Jun 2012 09:05:14 -0400 +Subject: [PATCH] 0.106: agenthelper-pam: Fix newline-trimming code + +First, we were using == instead of =, as the author probably intended. +But after changing that, we're now assigning to const memory. Fix +that by writing to a temporary string buffer. + +Signed-off-by: David Zeuthen <zeuthen@gmail.com> +Origin: upstream, 0.106, commit:14121fda7e4fa9463c66ce419cc32be7e7f3b535 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitagent/polkitagenthelper-pam.c | 11 ++++++++--- + 1 file changed, 8 insertions(+), 3 deletions(-) + +diff --git a/src/polkitagent/polkitagenthelper-pam.c b/src/polkitagent/polkitagenthelper-pam.c +index 85a26718a513..7af5321ebfa3 100644 +--- a/src/polkitagent/polkitagenthelper-pam.c ++++ b/src/polkitagent/polkitagenthelper-pam.c +@@ -227,6 +227,8 @@ conversation_function (int n, const struct pam_message **msg, struct pam_respons + char buf[PAM_MAX_RESP_SIZE]; + int i; + gchar *escaped = NULL; ++ gchar *tmp = NULL; ++ size_t len; + + data = data; + if (n <= 0 || n > PAM_MAX_NUM_MSG) +@@ -258,9 +260,12 @@ conversation_function (int n, const struct pam_message **msg, struct pam_respons + #ifdef PAH_DEBUG + fprintf (stderr, "polkit-agent-helper-1: writing `%s' to stdout\n", msg[i]->msg); + #endif /* PAH_DEBUG */ +- if (strlen (msg[i]->msg) > 0 && msg[i]->msg[strlen (msg[i]->msg) - 1] == '\n') +- msg[i]->msg[strlen (msg[i]->msg) - 1] == '\0'; +- escaped = g_strescape (msg[i]->msg, NULL); ++ tmp = g_strdup (msg[i]->msg); ++ len = strlen (tmp); ++ if (len > 0 && tmp[len - 1] == '\n') ++ tmp[len - 1] = '\0'; ++ escaped = g_strescape (tmp, NULL); ++ g_free (tmp); + fputs (escaped, stdout); + g_free (escaped); + #ifdef PAH_DEBUG diff --git a/patches/polkit-0.105/0001-check-for-libsystemd-instead-of-libsystemd-login.patch b/patches/polkit-0.105/0001-check-for-libsystemd-instead-of-libsystemd-login.patch deleted file mode 100644 index 1814ee989..000000000 --- a/patches/polkit-0.105/0001-check-for-libsystemd-instead-of-libsystemd-login.patch +++ /dev/null @@ -1,22 +0,0 @@ -From: Michael Olbrich <m.olbrich@pengutronix.de> -Date: Fri, 27 May 2016 20:20:16 +0200 -Subject: [PATCH] check for libsystemd instead of libsystemd-login - -Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> ---- - configure.ac | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/configure.ac b/configure.ac -index f4a0c4177fbf..4bf2c05d989c 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -160,7 +160,7 @@ AC_ARG_ENABLE([systemd], - [enable_systemd=auto]) - if test "$enable_systemd" != "no"; then - PKG_CHECK_MODULES(SYSTEMD, -- [libsystemd-login], -+ [libsystemd], - have_systemd=yes, - have_systemd=no) - if test "$have_systemd" = "yes"; then diff --git a/patches/polkit-0.105/0002-0.108-build-Fix-.gir-generation-for-parallel-make.patch b/patches/polkit-0.105/0002-0.108-build-Fix-.gir-generation-for-parallel-make.patch new file mode 100644 index 000000000..6f8991262 --- /dev/null +++ b/patches/polkit-0.105/0002-0.108-build-Fix-.gir-generation-for-parallel-make.patch @@ -0,0 +1,45 @@ +From: Ryan Lortie <desrt@velocity.(none)> +Date: Tue, 13 Nov 2012 11:50:14 -0500 +Subject: [PATCH] 0.108: 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. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=57077 +Signed-off-by: David Zeuthen <zeuthen@gmail.com> +Bug-Debian: https://bugs.debian.org/894205 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/Makefile.am | 2 ++ + src/polkitagent/Makefile.am | 2 ++ + 2 files changed, 4 insertions(+) + +diff --git a/src/polkit/Makefile.am b/src/polkit/Makefile.am +index 1068ea124b41..41ccf5c34581 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 e8c9fb1a7aa8..7b51137b5658 100644 +--- a/src/polkitagent/Makefile.am ++++ b/src/polkitagent/Makefile.am +@@ -106,6 +106,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 + diff --git a/patches/polkit-0.105/0003-0.110-Set-XAUTHORITY-environment-variable-if-is-unse.patch b/patches/polkit-0.105/0003-0.110-Set-XAUTHORITY-environment-variable-if-is-unse.patch new file mode 100644 index 000000000..53082a771 --- /dev/null +++ b/patches/polkit-0.105/0003-0.110-Set-XAUTHORITY-environment-variable-if-is-unse.patch @@ -0,0 +1,62 @@ +From: David Zeuthen <zeuthen@gmail.com> +Date: Wed, 19 Dec 2012 14:28:29 -0500 +Subject: [PATCH] 0.110: Set XAUTHORITY environment variable if is unset + +The way it works is that if XAUTHORITY is unset, then its default +value is $HOME/.Xauthority. But since we're changing user identity +this will not work since $HOME will now change. Therefore, if +XAUTHORITY is unset, just set its default value before changing +identity. This bug only affected login managers using X Window +Authorization but not explicitly setting the XAUTHORITY variable. + +You can argue that XAUTHORITY is broken since it forces uid-changing +apps like pkexec(1) to do more work - and get involved in intimate +details of how X works and so on - but that doesn't change how things +work. + +Based on a patch from Peter Wu <lekensteyn@gmail.com>. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=51623 +Signed-off-by: David Zeuthen <zeuthen@gmail.com> +Origin: upstream, 0.110, commit:d6acecdd0ebb42e28ff28e04e0207cb01fa20910 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/programs/pkexec.c | 22 ++++++++++++++++++++++ + 1 file changed, 22 insertions(+) + +diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c +index 373977b891c8..7fafa14d1c7a 100644 +--- a/src/programs/pkexec.c ++++ b/src/programs/pkexec.c +@@ -597,6 +597,28 @@ main (int argc, char *argv[]) + g_ptr_array_add (saved_env, g_strdup (value)); + } + ++ /* $XAUTHORITY is "special" - if unset, we need to set it to ~/.Xauthority. Yes, ++ * this is broken but it's unfortunately how things work (see fdo #51623 for ++ * details) ++ */ ++ if (g_getenv ("XAUTHORITY") == NULL) ++ { ++ const gchar *home; ++ ++ /* pre-2.36 GLib does not examine $HOME (it always looks in /etc/passwd) and ++ * this is not what we want ++ */ ++ home = g_getenv ("HOME"); ++ if (home == NULL) ++ home = g_get_home_dir (); ++ ++ if (home != NULL) ++ { ++ g_ptr_array_add (saved_env, g_strdup ("XAUTHORITY")); ++ g_ptr_array_add (saved_env, g_build_filename (home, ".Xauthority", NULL)); ++ } ++ } ++ + /* Nuke the environment to get a well-known and sanitized environment to avoid attacks + * via e.g. the DBUS_SYSTEM_BUS_ADDRESS environment variable and similar. + */ diff --git a/patches/polkit-0.105/0004-0.110-Fix-build-on-GNU-Hurd.patch b/patches/polkit-0.105/0004-0.110-Fix-build-on-GNU-Hurd.patch new file mode 100644 index 000000000..c58fd302c --- /dev/null +++ b/patches/polkit-0.105/0004-0.110-Fix-build-on-GNU-Hurd.patch @@ -0,0 +1,44 @@ +From: Emilio Pozuelo Monfort <pochu27@gmail.com> +Date: Sat, 26 Mar 2011 07:28:14 +0000 +Subject: [PATCH] 0.110: Fix build on GNU Hurd + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=35685 +Applied-upstream: 0.110, commit:d6de13e12379826af8ca9355a32da48707b9831f + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/programs/pkexec.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c +index 7fafa14d1c7a..682fe95419c8 100644 +--- a/src/programs/pkexec.c ++++ b/src/programs/pkexec.c +@@ -53,7 +53,7 @@ + #include <polkitagent/polkitagent.h> + + static gchar *original_user_name = NULL; +-static gchar original_cwd[PATH_MAX]; ++static gchar *original_cwd; + static gchar *command_line = NULL; + static struct passwd *pw; + +@@ -465,7 +465,7 @@ main (int argc, char *argv[]) + goto out; + } + +- if (getcwd (original_cwd, sizeof (original_cwd)) == NULL) ++ if ((original_cwd = g_get_current_dir ()) == NULL) + { + g_printerr ("Error getting cwd: %s\n", + g_strerror (errno)); +@@ -953,6 +953,7 @@ main (int argc, char *argv[]) + g_ptr_array_free (saved_env, TRUE); + } + ++ g_free (original_cwd); + g_free (path); + g_free (command_line); + g_free (opt_user); diff --git a/patches/polkit-0.105/0005-0.111-pkexec-Set-process-environment-from-pam_getenv.patch b/patches/polkit-0.105/0005-0.111-pkexec-Set-process-environment-from-pam_getenv.patch new file mode 100644 index 000000000..4f4fa151a --- /dev/null +++ b/patches/polkit-0.105/0005-0.111-pkexec-Set-process-environment-from-pam_getenv.patch @@ -0,0 +1,47 @@ +From: Steve Langasek <steve.langasek@canonical.com> +Date: Fri, 8 Mar 2013 12:00:00 +0100 +Subject: [PATCH] 0.111: pkexec: Set process environment from pam_getenvlist() + +Various pam modules provide environment variables that are intended to be set +in the environment of the pam session. pkexec needs to process the output of +pam_getenvlist() to get these. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=62016 +Applied-upstream: 0.111, commit:5aef9722c15a350fbf8b20a3b58419f156cc7c98 +Bug-Ubuntu: https://bugs.launchpad.net/bugs/982684 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/programs/pkexec.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c +index 682fe95419c8..9a0570a307a1 100644 +--- a/src/programs/pkexec.c ++++ b/src/programs/pkexec.c +@@ -145,6 +145,7 @@ open_session (const gchar *user_to_auth) + gboolean ret; + gint rc; + pam_handle_t *pam_h; ++ char **envlist; + struct pam_conv conversation; + + ret = FALSE; +@@ -176,6 +177,15 @@ open_session (const gchar *user_to_auth) + + ret = TRUE; + ++ envlist = pam_getenvlist (pam_h); ++ if (envlist != NULL) ++ { ++ guint n; ++ for (n = 0; envlist[n]; n++) ++ putenv (envlist[n]); ++ free (envlist); ++ } ++ + out: + if (pam_h != NULL) + pam_end (pam_h, rc); diff --git a/patches/polkit-0.105/0006-0.111-Fix-a-memory-leak.patch b/patches/polkit-0.105/0006-0.111-Fix-a-memory-leak.patch new file mode 100644 index 000000000..c92b7f595 --- /dev/null +++ b/patches/polkit-0.105/0006-0.111-Fix-a-memory-leak.patch @@ -0,0 +1,26 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Tue, 7 May 2013 22:30:25 +0200 +Subject: [PATCH] 0.111: Fix a memory leak + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=64336 +Origin: upstream, 0.111, commit:d7b6ab40b586c255c49aba22f558eb6602c88b1e + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitagent/polkitagenthelper-pam.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/polkitagent/polkitagenthelper-pam.c b/src/polkitagent/polkitagenthelper-pam.c +index 7af5321ebfa3..292abbe44e88 100644 +--- a/src/polkitagent/polkitagenthelper-pam.c ++++ b/src/polkitagent/polkitagenthelper-pam.c +@@ -321,6 +321,7 @@ error: + } + } + memset (aresp, 0, n * sizeof *aresp); ++ free (aresp); + *resp = NULL; + return PAM_CONV_ERR; + } diff --git a/patches/polkit-0.105/0007-0.112-Use-GOnce-for-interface-type-registration.patch b/patches/polkit-0.105/0007-0.112-Use-GOnce-for-interface-type-registration.patch new file mode 100644 index 000000000..907510e9e --- /dev/null +++ b/patches/polkit-0.105/0007-0.112-Use-GOnce-for-interface-type-registration.patch @@ -0,0 +1,122 @@ +From: Tomas Bzatek <tbzatek@redhat.com> +Date: Wed, 29 May 2013 13:45:31 +0000 +Subject: [PATCH] 0.112: Use GOnce for interface type registration + +Static local variable may not be enough since it doesn't provide locking. + +Related to these udisksd warnings: + GLib-GObject-WARNING **: cannot register existing type `PolkitSubject' + +Thanks to Hans de Goede for spotting this! + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=65130 +Origin: upstream, 0.112, commit:20ad116a6582e57d20f9d8197758947918753a4c + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitidentity.c | 10 ++++++---- + src/polkit/polkitsubject.c | 10 ++++++---- + src/polkitbackend/polkitbackendactionlookup.c | 10 ++++++---- + 3 files changed, 18 insertions(+), 12 deletions(-) + +diff --git a/src/polkit/polkitidentity.c b/src/polkit/polkitidentity.c +index dd15b2f94828..7813c2c07919 100644 +--- a/src/polkit/polkitidentity.c ++++ b/src/polkit/polkitidentity.c +@@ -49,9 +49,9 @@ base_init (gpointer g_iface) + GType + polkit_identity_get_type (void) + { +- static GType iface_type = 0; ++ static volatile gsize g_define_type_id__volatile = 0; + +- if (iface_type == 0) ++ if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GTypeInfo info = + { +@@ -67,12 +67,14 @@ polkit_identity_get_type (void) + NULL /* value_table */ + }; + +- iface_type = g_type_register_static (G_TYPE_INTERFACE, "PolkitIdentity", &info, 0); ++ GType iface_type = ++ g_type_register_static (G_TYPE_INTERFACE, "PolkitIdentity", &info, 0); + + g_type_interface_add_prerequisite (iface_type, G_TYPE_OBJECT); ++ g_once_init_leave (&g_define_type_id__volatile, iface_type); + } + +- return iface_type; ++ return g_define_type_id__volatile; + } + + /** +diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c +index d2c4c205b1f2..aed57951bb6b 100644 +--- a/src/polkit/polkitsubject.c ++++ b/src/polkit/polkitsubject.c +@@ -50,9 +50,9 @@ base_init (gpointer g_iface) + GType + polkit_subject_get_type (void) + { +- static GType iface_type = 0; ++ static volatile gsize g_define_type_id__volatile = 0; + +- if (iface_type == 0) ++ if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GTypeInfo info = + { +@@ -68,12 +68,14 @@ polkit_subject_get_type (void) + NULL /* value_table */ + }; + +- iface_type = g_type_register_static (G_TYPE_INTERFACE, "PolkitSubject", &info, 0); ++ GType iface_type = ++ g_type_register_static (G_TYPE_INTERFACE, "PolkitSubject", &info, 0); + + g_type_interface_add_prerequisite (iface_type, G_TYPE_OBJECT); ++ g_once_init_leave (&g_define_type_id__volatile, iface_type); + } + +- return iface_type; ++ return g_define_type_id__volatile; + } + + /** +diff --git a/src/polkitbackend/polkitbackendactionlookup.c b/src/polkitbackend/polkitbackendactionlookup.c +index 5a1a228a4c10..20747e7921ef 100644 +--- a/src/polkitbackend/polkitbackendactionlookup.c ++++ b/src/polkitbackend/polkitbackendactionlookup.c +@@ -74,9 +74,9 @@ base_init (gpointer g_iface) + GType + polkit_backend_action_lookup_get_type (void) + { +- static GType iface_type = 0; ++ static volatile gsize g_define_type_id__volatile = 0; + +- if (iface_type == 0) ++ if (g_once_init_enter (&g_define_type_id__volatile)) + { + static const GTypeInfo info = + { +@@ -92,12 +92,14 @@ polkit_backend_action_lookup_get_type (void) + NULL /* value_table */ + }; + +- iface_type = g_type_register_static (G_TYPE_INTERFACE, "PolkitBackendActionLookup", &info, 0); ++ GType iface_type = ++ g_type_register_static (G_TYPE_INTERFACE, "PolkitBackendActionLookup", &info, 0); + + g_type_interface_add_prerequisite (iface_type, G_TYPE_OBJECT); ++ g_once_init_leave (&g_define_type_id__volatile, iface_type); + } + +- return iface_type; ++ return g_define_type_id__volatile; + } + + /** diff --git a/patches/polkit-0.105/0008-0.112-polkitunixprocess-Deprecate-racy-APIs.patch b/patches/polkit-0.105/0008-0.112-polkitunixprocess-Deprecate-racy-APIs.patch new file mode 100644 index 000000000..c39c0486c --- /dev/null +++ b/patches/polkit-0.105/0008-0.112-polkitunixprocess-Deprecate-racy-APIs.patch @@ -0,0 +1,31 @@ +From: Colin Walters <walters@verbum.org> +Date: Tue, 20 Aug 2013 15:15:31 -0400 +Subject: [PATCH] 0.112: polkitunixprocess: Deprecate racy APIs + +It's only safe for processes to be created with their owning uid, +(without kernel support, which we don't have). Anything else is +subject to clients exec()ing setuid binaries after the fact. + +Origin: upstream, 0.112, commit:08291789a1f99d4ab29c74c39344304bcca43023 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitunixprocess.h | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/src/polkit/polkitunixprocess.h b/src/polkit/polkitunixprocess.h +index 531a57d61445..f5ed1a73e652 100644 +--- a/src/polkit/polkitunixprocess.h ++++ b/src/polkit/polkitunixprocess.h +@@ -47,7 +47,9 @@ typedef struct _PolkitUnixProcess PolkitUnixProcess; + typedef struct _PolkitUnixProcessClass PolkitUnixProcessClass; + + GType polkit_unix_process_get_type (void) G_GNUC_CONST; ++G_GNUC_DEPRECATED_FOR(polkit_unix_process_new_for_owner) + PolkitSubject *polkit_unix_process_new (gint pid); ++G_GNUC_DEPRECATED_FOR(polkit_unix_process_new_for_owner) + PolkitSubject *polkit_unix_process_new_full (gint pid, + guint64 start_time); + PolkitSubject *polkit_unix_process_new_for_owner (gint pid, diff --git a/patches/polkit-0.105/0009-0.112-pkcheck-Support-process-pid-start-time-uid-syn.patch b/patches/polkit-0.105/0009-0.112-pkcheck-Support-process-pid-start-time-uid-syn.patch new file mode 100644 index 000000000..198ddc639 --- /dev/null +++ b/patches/polkit-0.105/0009-0.112-pkcheck-Support-process-pid-start-time-uid-syn.patch @@ -0,0 +1,121 @@ +From: Colin Walters <walters@verbum.org> +Date: Mon, 19 Aug 2013 12:16:11 -0400 +Subject: [PATCH] 0.112: 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 + +Origin: upstream, 0.112, commit:3968411b0c7ba193f9b9276ec911692aec248608 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + data/polkit-gobject-1.pc.in | 3 +++ + docs/man/pkcheck.xml | 29 ++++++++++++++++++++--------- + src/programs/pkcheck.c | 7 ++++++- + 3 files changed, 29 insertions(+), 10 deletions(-) + +diff --git a/data/polkit-gobject-1.pc.in b/data/polkit-gobject-1.pc.in +index c39677ddf52f..5c4c62072f80 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 6b8a874311a0..508447e23329 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,25 @@ 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 ++ 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 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. ++ 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 719a36c47c21..057e926db86f 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); + } diff --git a/patches/polkit-0.105/0010-0.113-Port-internals-non-deprecated-PolkitProcess-AP.patch b/patches/polkit-0.105/0010-0.113-Port-internals-non-deprecated-PolkitProcess-AP.patch new file mode 100644 index 000000000..b1f29326e --- /dev/null +++ b/patches/polkit-0.105/0010-0.113-Port-internals-non-deprecated-PolkitProcess-AP.patch @@ -0,0 +1,34 @@ +From: Colin Walters <walters@verbum.org> +Date: Sat, 9 Nov 2013 13:48:21 -0500 +Subject: [PATCH] 0.113: Port internals non-deprecated PolkitProcess API where + possible + +We can't port everything, but in PolkitPermission and these test +cases, we can use _for_owner() with the right information. + +[smcv: drop the part that touches +test/polkitbackend/test-polkitbackendjsauthority.c which is not +in this branch] + +Origin: upstream, 0.113, commit:6d3d0a8ffb0fd8ae59eb35593b305ec87da8858d + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitpermission.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/polkit/polkitpermission.c b/src/polkit/polkitpermission.c +index 22d195fcdc60..f8a666e81913 100644 +--- a/src/polkit/polkitpermission.c ++++ b/src/polkit/polkitpermission.c +@@ -122,7 +122,7 @@ polkit_permission_constructed (GObject *object) + PolkitPermission *permission = POLKIT_PERMISSION (object); + + if (permission->subject == NULL) +- permission->subject = polkit_unix_process_new (getpid ()); ++ permission->subject = polkit_unix_process_new_for_owner (getpid (), 0, getuid ()); + + if (G_OBJECT_CLASS (polkit_permission_parent_class)->constructed != NULL) + G_OBJECT_CLASS (polkit_permission_parent_class)->constructed (object); diff --git a/patches/polkit-0.105/0011-0.113-pkexec-Work-around-systemd-injecting-broken-XD.patch b/patches/polkit-0.105/0011-0.113-pkexec-Work-around-systemd-injecting-broken-XD.patch new file mode 100644 index 000000000..a270de1fe --- /dev/null +++ b/patches/polkit-0.105/0011-0.113-pkexec-Work-around-systemd-injecting-broken-XD.patch @@ -0,0 +1,81 @@ +From: Colin Walters <walters@verbum.org> +Date: Thu, 21 Nov 2013 17:39:37 -0500 +Subject: [PATCH] 0.113: pkexec: Work around systemd injecting broken + XDG_RUNTIME_DIR + +This workaround isn't too much code, and it's often better to fix bugs +in two places anyways. + +For more information: + +See https://bugzilla.redhat.com/show_bug.cgi?id=753882 +See http://lists.freedesktop.org/archives/systemd-devel/2013-November/014370.html + +Origin: upstream, 0.113, commit:8635ffc16aeff6a07d675f861fe0dea03ea81d7e + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/programs/pkexec.c | 33 ++++++++++++++++++++++++++++++--- + 1 file changed, 30 insertions(+), 3 deletions(-) + +diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c +index 9a0570a307a1..5e99044311ac 100644 +--- a/src/programs/pkexec.c ++++ b/src/programs/pkexec.c +@@ -139,8 +139,22 @@ pam_conversation_function (int n, + return PAM_CONV_ERR; + } + ++/* A work around for: ++ * https://bugzilla.redhat.com/show_bug.cgi?id=753882 ++ */ ++static gboolean ++xdg_runtime_dir_is_owned_by (const char *path, ++ uid_t target_uid) ++{ ++ struct stat stbuf; ++ ++ return stat (path, &stbuf) == 0 && ++ stbuf.st_uid == target_uid; ++} ++ + static gboolean +-open_session (const gchar *user_to_auth) ++open_session (const gchar *user_to_auth, ++ uid_t target_uid) + { + gboolean ret; + gint rc; +@@ -182,7 +196,19 @@ open_session (const gchar *user_to_auth) + { + guint n; + for (n = 0; envlist[n]; n++) +- putenv (envlist[n]); ++ { ++ const char *envitem = envlist[n]; ++ ++ if (g_str_has_prefix (envitem, "XDG_RUNTIME_DIR=")) ++ { ++ const char *eq = strchr (envitem, '='); ++ g_assert (eq); ++ if (!xdg_runtime_dir_is_owned_by (eq + 1, target_uid)) ++ continue; ++ } ++ ++ putenv (envlist[n]); ++ } + free (envlist); + } + +@@ -892,7 +918,8 @@ main (int argc, char *argv[]) + * As evident above, neither su(1) (and, for that matter, nor sudo(8)) does this. + */ + #ifdef POLKIT_AUTHFW_PAM +- if (!open_session (pw->pw_name)) ++ if (!open_session (pw->pw_name, ++ pw->pw_uid)) + { + goto out; + } diff --git a/patches/polkit-0.105/0012-0.113-PolkitAgentSession-fix-race-between-child-and-.patch b/patches/polkit-0.105/0012-0.113-PolkitAgentSession-fix-race-between-child-and-.patch new file mode 100644 index 000000000..d91e0f09c --- /dev/null +++ b/patches/polkit-0.105/0012-0.113-PolkitAgentSession-fix-race-between-child-and-.patch @@ -0,0 +1,125 @@ +From: Rui Matos <tiagomatos@gmail.com> +Date: Thu, 6 Feb 2014 18:41:18 +0100 +Subject: [PATCH] 0.113: PolkitAgentSession: fix race between child and io + watches + +The helper flushes and fdatasyncs stdout and stderr before terminating +but this doesn't guarantee that our io watch is called before our +child watch. This means that we can end up with a successful return +from the helper which we still report as a failure. + +If we add G_IO_HUP and G_IO_ERR to the conditions we look for in the +io watch and the child terminates we still run the io watch handler +which will complete the session. + +This means that the child watch is in fact needless and we can remove +it. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=60847 +Origin: upstream, 0.113, commit:7650ad1e08ab13bdb461783c4995d186d9392840 +Bug: http://bugs.freedesktop.org/show_bug.cgi?id=30515 +Bug-Ubuntu: https://launchpad.net/bugs/649939 +Bug-Ubuntu: https://launchpad.net/bugs/445303 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitagent/polkitagentsession.c | 47 +++++++--------------------- + 1 file changed, 11 insertions(+), 36 deletions(-) + +diff --git a/src/polkitagent/polkitagentsession.c b/src/polkitagent/polkitagentsession.c +index 8129cd9f7091..a658a2295da7 100644 +--- a/src/polkitagent/polkitagentsession.c ++++ b/src/polkitagent/polkitagentsession.c +@@ -92,7 +92,6 @@ struct _PolkitAgentSession + int child_stdout; + GPid child_pid; + +- GSource *child_watch_source; + GSource *child_stdout_watch_source; + GIOChannel *child_stdout_channel; + +@@ -377,13 +376,6 @@ kill_helper (PolkitAgentSession *session) + session->child_pid = 0; + } + +- if (session->child_watch_source != NULL) +- { +- g_source_destroy (session->child_watch_source); +- g_source_unref (session->child_watch_source); +- session->child_watch_source = NULL; +- } +- + if (session->child_stdout_watch_source != NULL) + { + g_source_destroy (session->child_stdout_watch_source); +@@ -429,26 +421,6 @@ complete_session (PolkitAgentSession *session, + } + } + +-static void +-child_watch_func (GPid pid, +- gint status, +- gpointer user_data) +-{ +- PolkitAgentSession *session = POLKIT_AGENT_SESSION (user_data); +- +- if (G_UNLIKELY (_show_debug ())) +- { +- g_print ("PolkitAgentSession: in child_watch_func for pid %d (WIFEXITED=%d WEXITSTATUS=%d)\n", +- (gint) pid, +- WIFEXITED(status), +- WEXITSTATUS(status)); +- } +- +- /* kill all the watches we have set up, except for the child since it has exited already */ +- session->child_pid = 0; +- complete_session (session, FALSE); +-} +- + static gboolean + io_watch_have_data (GIOChannel *channel, + GIOCondition condition, +@@ -475,10 +447,13 @@ io_watch_have_data (GIOChannel *channel, + NULL, + NULL, + &error); +- if (error != NULL) ++ if (error != NULL || line == NULL) + { +- g_warning ("Error reading line from helper: %s", error->message); +- g_error_free (error); ++ /* In case we get just G_IO_HUP, line is NULL but error is ++ unset.*/ ++ g_warning ("Error reading line from helper: %s", ++ error ? error->message : "nothing to read"); ++ g_clear_error (&error); + + complete_session (session, FALSE); + goto out; +@@ -540,6 +515,9 @@ io_watch_have_data (GIOChannel *channel, + g_free (line); + g_free (unescaped); + ++ if (condition & (G_IO_ERR | G_IO_HUP)) ++ complete_session (session, FALSE); ++ + /* keep the IOChannel around */ + return TRUE; + } +@@ -650,12 +628,9 @@ 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_watch_source = g_child_watch_source_new (session->child_pid); +- g_source_set_callback (session->child_watch_source, (GSourceFunc) child_watch_func, session, NULL); +- g_source_attach (session->child_watch_source, g_main_context_get_thread_default ()); +- + 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); ++ session->child_stdout_watch_source = g_io_create_watch (session->child_stdout_channel, ++ G_IO_IN | G_IO_ERR | G_IO_HUP); + g_source_set_callback (session->child_stdout_watch_source, (GSourceFunc) io_watch_have_data, session, NULL); + g_source_attach (session->child_stdout_watch_source, g_main_context_get_thread_default ()); + diff --git a/patches/polkit-0.105/0013-0.113-polkitd-Fix-problem-with-removing-non-existent.patch b/patches/polkit-0.105/0013-0.113-polkitd-Fix-problem-with-removing-non-existent.patch new file mode 100644 index 000000000..9c6e5ec30 --- /dev/null +++ b/patches/polkit-0.105/0013-0.113-polkitd-Fix-problem-with-removing-non-existent.patch @@ -0,0 +1,27 @@ +From: Lukasz Skalski <l.skalski@samsung.com> +Date: Tue, 22 Apr 2014 11:11:20 +0200 +Subject: [PATCH] 0.113: polkitd: Fix problem with removing non-existent source + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=77167 +Applied-upstream: 0.113, commit:3ca4e00c7e003ea80aa96b499bc7cd83246d7108 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitd/main.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/polkitd/main.c b/src/polkitd/main.c +index b21723f697ce..f18fb917c3b6 100644 +--- a/src/polkitd/main.c ++++ b/src/polkitd/main.c +@@ -93,7 +93,7 @@ on_sigint (gpointer user_data) + { + g_print ("Handling SIGINT\n"); + g_main_loop_quit (loop); +- return FALSE; ++ return TRUE; + } + + int diff --git a/patches/polkit-0.105/0014-0.113-PolkitSystemBusName-Add-public-API-to-retrieve.patch b/patches/polkit-0.105/0014-0.113-PolkitSystemBusName-Add-public-API-to-retrieve.patch new file mode 100644 index 000000000..e10a19d58 --- /dev/null +++ b/patches/polkit-0.105/0014-0.113-PolkitSystemBusName-Add-public-API-to-retrieve.patch @@ -0,0 +1,171 @@ +From: Colin Walters <walters@verbum.org> +Date: Wed, 21 Aug 2013 12:23:55 -0400 +Subject: [PATCH] 0.113: PolkitSystemBusName: Add public API to retrieve Unix + user + +And change the duplicated code in the backend session monitors to use +it. This just a code cleanup resulting from review after +CVE-2013-4288. There's no security impact from this patch, it just +removes duplicated code. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69538 +Origin: upstream, 0.113, commit:904d8404d93dec45fce3b719eb1a626acc6b8a73 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitsystembusname.c | 56 +++++++++++++++++++ + src/polkit/polkitsystembusname.h | 4 ++ + .../polkitbackendsessionmonitor-systemd.c | 20 +------ + .../polkitbackendsessionmonitor.c | 20 +------ + 4 files changed, 62 insertions(+), 38 deletions(-) + +diff --git a/src/polkit/polkitsystembusname.c b/src/polkit/polkitsystembusname.c +index 2a297c4af475..51e4a694aa38 100644 +--- a/src/polkit/polkitsystembusname.c ++++ b/src/polkit/polkitsystembusname.c +@@ -25,6 +25,7 @@ + + #include <string.h> + #include "polkitsystembusname.h" ++#include "polkitunixuser.h" + #include "polkitsubject.h" + #include "polkitprivate.h" + +@@ -396,3 +397,58 @@ polkit_system_bus_name_get_process_sync (PolkitSystemBusName *system_bus_name, + return ret; + } + ++/** ++ * polkit_system_bus_name_get_user_sync: ++ * @system_bus_name: A #PolkitSystemBusName. ++ * @cancellable: (allow-none): A #GCancellable or %NULL. ++ * @error: (allow-none): Return location for error or %NULL. ++ * ++ * Synchronously gets a #PolkitUnixUser object for @system_bus_name; ++ * the calling thread is blocked until a reply is received. ++ * ++ * Returns: (allow-none) (transfer full): A #PolkitUnixUser object or %NULL if @error is set. ++ **/ ++PolkitUnixUser * ++polkit_system_bus_name_get_user_sync (PolkitSystemBusName *system_bus_name, ++ GCancellable *cancellable, ++ GError **error) ++{ ++ GDBusConnection *connection; ++ PolkitUnixUser *ret; ++ GVariant *result; ++ guint32 uid; ++ ++ g_return_val_if_fail (POLKIT_IS_SYSTEM_BUS_NAME (system_bus_name), NULL); ++ g_return_val_if_fail (cancellable == NULL || G_IS_CANCELLABLE (cancellable), NULL); ++ g_return_val_if_fail (error == NULL || *error == NULL, NULL); ++ ++ ret = NULL; ++ ++ connection = g_bus_get_sync (G_BUS_TYPE_SYSTEM, cancellable, error); ++ if (connection == NULL) ++ goto out; ++ ++ result = g_dbus_connection_call_sync (connection, ++ "org.freedesktop.DBus", /* name */ ++ "/org/freedesktop/DBus", /* object path */ ++ "org.freedesktop.DBus", /* interface name */ ++ "GetConnectionUnixUser", /* method */ ++ g_variant_new ("(s)", system_bus_name->name), ++ G_VARIANT_TYPE ("(u)"), ++ G_DBUS_CALL_FLAGS_NONE, ++ -1, ++ cancellable, ++ error); ++ if (result == NULL) ++ goto out; ++ ++ g_variant_get (result, "(u)", &uid); ++ g_variant_unref (result); ++ ++ ret = (PolkitUnixUser*)polkit_unix_user_new (uid); ++ ++ out: ++ if (connection != NULL) ++ g_object_unref (connection); ++ return ret; ++} +diff --git a/src/polkit/polkitsystembusname.h b/src/polkit/polkitsystembusname.h +index 1fc464fc41ef..38d31f715d10 100644 +--- a/src/polkit/polkitsystembusname.h ++++ b/src/polkit/polkitsystembusname.h +@@ -56,6 +56,10 @@ PolkitSubject *polkit_system_bus_name_get_process_sync (PolkitSystemBusName + GCancellable *cancellable, + GError **error); + ++PolkitUnixUser * polkit_system_bus_name_get_user_sync (PolkitSystemBusName *system_bus_name, ++ GCancellable *cancellable, ++ GError **error); ++ + G_END_DECLS + + #endif /* __POLKIT_SYSTEM_BUS_NAME_H */ +diff --git a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +index 58593c323508..018531051714 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +@@ -277,25 +277,7 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + } + else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + { +- GVariant *result; +- +- result = g_dbus_connection_call_sync (monitor->system_bus, +- "org.freedesktop.DBus", +- "/org/freedesktop/DBus", +- "org.freedesktop.DBus", +- "GetConnectionUnixUser", +- g_variant_new ("(s)", polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject))), +- G_VARIANT_TYPE ("(u)"), +- G_DBUS_CALL_FLAGS_NONE, +- -1, /* timeout_msec */ +- NULL, /* GCancellable */ +- error); +- if (result == NULL) +- goto out; +- g_variant_get (result, "(u)", &uid); +- g_variant_unref (result); +- +- ret = polkit_unix_user_new (uid); ++ ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); + } + else if (POLKIT_IS_UNIX_SESSION (subject)) + { +diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c +index 9c331b64a0ec..4075d3ff06ad 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor.c +@@ -306,25 +306,7 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + } + else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + { +- GVariant *result; +- +- result = g_dbus_connection_call_sync (monitor->system_bus, +- "org.freedesktop.DBus", +- "/org/freedesktop/DBus", +- "org.freedesktop.DBus", +- "GetConnectionUnixUser", +- g_variant_new ("(s)", polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject))), +- G_VARIANT_TYPE ("(u)"), +- G_DBUS_CALL_FLAGS_NONE, +- -1, /* timeout_msec */ +- NULL, /* GCancellable */ +- error); +- if (result == NULL) +- goto out; +- g_variant_get (result, "(u)", &uid); +- g_variant_unref (result); +- +- ret = polkit_unix_user_new (uid); ++ ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject)); + } + else if (POLKIT_IS_UNIX_SESSION (subject)) + { diff --git a/patches/polkit-0.105/0015-0.113-Fixed-compilation-problem-in-the-backend.patch b/patches/polkit-0.105/0015-0.113-Fixed-compilation-problem-in-the-backend.patch new file mode 100644 index 000000000..a61daa192 --- /dev/null +++ b/patches/polkit-0.105/0015-0.113-Fixed-compilation-problem-in-the-backend.patch @@ -0,0 +1,27 @@ +From: Xabier Rodriguez Calvar <calvaris@igalia.com> +Date: Sun, 10 Nov 2013 19:16:41 +0100 +Subject: [PATCH] 0.113: Fixed compilation problem in the backend + +Origin: upstream, 0.113, commit: dbbb7dc60abdd970af0a8fae404484181fa909c9 +Bug-Debian: https://bugs.debian.org/798769 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitbackend/polkitbackendsessionmonitor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c +index 4075d3ff06ad..05f51c581479 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor.c +@@ -306,7 +306,7 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + } + else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + { +- ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject)); ++ ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, NULL); + } + else if (POLKIT_IS_UNIX_SESSION (subject)) + { diff --git a/patches/polkit-0.105/0016-0.113-Don-t-discard-error-data-returned-by-polkit_sy.patch b/patches/polkit-0.105/0016-0.113-Don-t-discard-error-data-returned-by-polkit_sy.patch new file mode 100644 index 000000000..de3da552f --- /dev/null +++ b/patches/polkit-0.105/0016-0.113-Don-t-discard-error-data-returned-by-polkit_sy.patch @@ -0,0 +1,29 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Mon, 11 Nov 2013 23:51:23 +0100 +Subject: [PATCH] 0.113: Don't discard error data returned by + polkit_system_bus_name_get_user_sync + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=71458 +Origin: upstream, 0.113, commit: 145d43b9c891f248ad68ebe597cb151a865bdb3a +Bug-Debian: https://bugs.debian.org/798769 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitbackend/polkitbackendsessionmonitor.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c +index 05f51c581479..e1a9ab3a32cc 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor.c +@@ -306,7 +306,7 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + } + else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + { +- ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, NULL); ++ ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); + } + else if (POLKIT_IS_UNIX_SESSION (subject)) + { diff --git a/patches/polkit-0.105/0017-0.113-sessionmonitor-systemd-Deduplicate-code-paths.patch b/patches/polkit-0.105/0017-0.113-sessionmonitor-systemd-Deduplicate-code-paths.patch new file mode 100644 index 000000000..756701aa4 --- /dev/null +++ b/patches/polkit-0.105/0017-0.113-sessionmonitor-systemd-Deduplicate-code-paths.patch @@ -0,0 +1,108 @@ +From: Colin Walters <walters@verbum.org> +Date: Thu, 7 Nov 2013 15:57:50 -0500 +Subject: [PATCH] 0.113: sessionmonitor-systemd: Deduplicate code paths + +We had the code to go from pid -> session duplicated. If we have a +PolkitSystemBusName, convert it to a PolkitUnixProcess. +Then we can do PolkitUnixProcess -> pid -> session in one place. + +This is just a code cleanup. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69538 +Origin: upstream, 0.113, commit:26d0c0578211fb96fc8fe75572aa11ad6ecbf9b8 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + .../polkitbackendsessionmonitor-systemd.c | 63 +++++++------------ + 1 file changed, 22 insertions(+), 41 deletions(-) + +diff --git a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +index 018531051714..756b728ab952 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +@@ -313,61 +313,42 @@ polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMoni + PolkitSubject *subject, + GError **error) + { +- PolkitSubject *session; +- +- session = NULL; ++ PolkitUnixProcess *tmp_process = NULL; ++ PolkitUnixProcess *process = NULL; ++ PolkitSubject *session = NULL; ++ char *session_id = NULL; ++ pid_t pid; + + if (POLKIT_IS_UNIX_PROCESS (subject)) +- { +- gchar *session_id; +- pid_t pid; +- +- pid = polkit_unix_process_get_pid (POLKIT_UNIX_PROCESS (subject)); +- if (sd_pid_get_session (pid, &session_id) < 0) +- goto out; +- +- session = polkit_unix_session_new (session_id); +- free (session_id); +- } ++ process = POLKIT_UNIX_PROCESS (subject); /* We already have a process */ + else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + { +- guint32 pid; +- gchar *session_id; +- GVariant *result; +- +- result = g_dbus_connection_call_sync (monitor->system_bus, +- "org.freedesktop.DBus", +- "/org/freedesktop/DBus", +- "org.freedesktop.DBus", +- "GetConnectionUnixProcessID", +- g_variant_new ("(s)", polkit_system_bus_name_get_name (POLKIT_SYSTEM_BUS_NAME (subject))), +- G_VARIANT_TYPE ("(u)"), +- G_DBUS_CALL_FLAGS_NONE, +- -1, /* timeout_msec */ +- NULL, /* GCancellable */ +- error); +- if (result == NULL) +- goto out; +- g_variant_get (result, "(u)", &pid); +- g_variant_unref (result); +- +- if (sd_pid_get_session (pid, &session_id) < 0) +- goto out; +- +- session = polkit_unix_session_new (session_id); +- free (session_id); ++ /* Convert bus name to process */ ++ tmp_process = (PolkitUnixProcess*)polkit_system_bus_name_get_process_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); ++ if (!tmp_process) ++ goto out; ++ process = tmp_process; + } + else + { + g_set_error (error, + POLKIT_ERROR, + POLKIT_ERROR_NOT_SUPPORTED, +- "Cannot get user for subject of type %s", ++ "Cannot get session for subject of type %s", + g_type_name (G_TYPE_FROM_INSTANCE (subject))); + } + +- out: ++ /* Now do process -> pid -> session */ ++ g_assert (process != NULL); ++ pid = polkit_unix_process_get_pid (process); + ++ if (sd_pid_get_session (pid, &session_id) < 0) ++ goto out; ++ ++ session = polkit_unix_session_new (session_id); ++ free (session_id); ++ out: ++ if (tmp_process) g_object_unref (tmp_process); + return session; + } + diff --git a/patches/polkit-0.105/0018-0.113-sessionmonitor-systemd-prepare-for-D-Bus-user-.patch b/patches/polkit-0.105/0018-0.113-sessionmonitor-systemd-prepare-for-D-Bus-user-.patch new file mode 100644 index 000000000..ffd729a55 --- /dev/null +++ b/patches/polkit-0.105/0018-0.113-sessionmonitor-systemd-prepare-for-D-Bus-user-.patch @@ -0,0 +1,94 @@ +From: Kay Sievers <kay@vrfy.org> +Date: Mon, 19 May 2014 10:19:49 +0900 +Subject: [PATCH] 0.113: sessionmonitor-systemd: prepare for D-Bus "user bus" + model + +In the D-Bus "user bus" model, all sessions of a user share the same +D-Bus instance, a polkit requesting process might live outside the +login session which registered the user's polkit agent. + +In case a polkit requesting process is not part of the user's login +session, we ask systemd-logind for the user's "display" session +instead. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=78905 +Bug-Debian: https://bugs.debian.org/779988 +Applied-upstream: 0.113, commit:a68f5dfd7662767b7b9822090b70bc5bd145c50c +[smcv: backport configure.ac changes; fail with #error if the required +API is not found] + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + configure.ac | 4 +++ + .../polkitbackendsessionmonitor-systemd.c | 29 +++++++++++++++---- + 2 files changed, 28 insertions(+), 5 deletions(-) + +diff --git a/configure.ac b/configure.ac +index f4a0c4177fbf..aa2760f90606 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -165,6 +165,10 @@ if test "$enable_systemd" != "no"; then + have_systemd=no) + if test "$have_systemd" = "yes"; then + SESSION_TRACKING=systemd ++ save_LIBS=$LIBS ++ LIBS=$SYSTEMD_LIBS ++ AC_CHECK_FUNCS(sd_uid_get_display) ++ LIBS=$save_LIBS + else + if test "$enable_systemd" = "yes"; then + AC_MSG_ERROR([systemd support requested but libsystemd-login1 library not found]) +diff --git a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +index 756b728ab952..ebd05cea45dc 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +@@ -318,6 +318,9 @@ polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMoni + PolkitSubject *session = NULL; + char *session_id = NULL; + pid_t pid; ++#if HAVE_SD_UID_GET_DISPLAY ++ uid_t uid; ++#endif + + if (POLKIT_IS_UNIX_PROCESS (subject)) + process = POLKIT_UNIX_PROCESS (subject); /* We already have a process */ +@@ -338,16 +341,32 @@ polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMoni + g_type_name (G_TYPE_FROM_INSTANCE (subject))); + } + +- /* Now do process -> pid -> session */ ++ /* Now do process -> pid -> same session */ + g_assert (process != NULL); + pid = polkit_unix_process_get_pid (process); + +- if (sd_pid_get_session (pid, &session_id) < 0) ++ if (sd_pid_get_session (pid, &session_id) >= 0) ++ { ++ session = polkit_unix_session_new (session_id); ++ goto out; ++ } ++ ++#if HAVE_SD_UID_GET_DISPLAY ++ /* Now do process -> uid -> graphical session (systemd version 213)*/ ++ if (sd_pid_get_owner_uid (pid, &uid) < 0) + goto out; +- +- session = polkit_unix_session_new (session_id); +- free (session_id); ++ ++ if (sd_uid_get_display (uid, &session_id) >= 0) ++ { ++ session = polkit_unix_session_new (session_id); ++ goto out; ++ } ++#else ++#error Debian should have sd_uid_get_display() ++#endif ++ + out: ++ free (session_id); + if (tmp_process) g_object_unref (tmp_process); + return session; + } diff --git a/patches/polkit-0.105/0019-0.113-Refuse-duplicate-user-arguments-to-pkexec.patch b/patches/polkit-0.105/0019-0.113-Refuse-duplicate-user-arguments-to-pkexec.patch new file mode 100644 index 000000000..65708c9d5 --- /dev/null +++ b/patches/polkit-0.105/0019-0.113-Refuse-duplicate-user-arguments-to-pkexec.patch @@ -0,0 +1,42 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Tue, 26 Aug 2014 17:59:47 +0200 +Subject: [PATCH] 0.113: Refuse duplicate --user arguments to pkexec + +This usage is clearly erroneous, so we should tell the users they are +making a mistake. + +Besides, this allows an attacker to cause a high number of heap +allocations with attacker-controlled sizes ( +http://googleprojectzero.blogspot.cz/2014/08/the-poisoned-nul-byte-2014-edition.html +), making some exploits easier. + +(To be clear, this is not a pkexec vulnerability, and we will not +refuse attacker-affected malloc() usage as a matter of policy; but this +commit is both user-friendly and adding some hardening.) + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=83093 +Origin: upstream, 0.113, commit:6c992bc8aefa195a41eaa41c07f46f17de18e25c + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/programs/pkexec.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/src/programs/pkexec.c b/src/programs/pkexec.c +index 5e99044311ac..abc660dfddc6 100644 +--- a/src/programs/pkexec.c ++++ b/src/programs/pkexec.c +@@ -533,6 +533,11 @@ main (int argc, char *argv[]) + goto out; + } + ++ if (opt_user != NULL) ++ { ++ g_printerr ("--user specified twice\n"); ++ goto out; ++ } + opt_user = g_strdup (argv[n]); + } + else if (strcmp (argv[n], "--disable-internal-agent") == 0) diff --git a/patches/polkit-0.105/0020-0.113-authority-Fix-memory-leak-in-EnumerateActions-.patch b/patches/polkit-0.105/0020-0.113-authority-Fix-memory-leak-in-EnumerateActions-.patch new file mode 100644 index 000000000..6b5668119 --- /dev/null +++ b/patches/polkit-0.105/0020-0.113-authority-Fix-memory-leak-in-EnumerateActions-.patch @@ -0,0 +1,31 @@ +From: "Max A. Dednev" <dednev@rambler.ru> +Date: Sun, 11 Jan 2015 20:00:44 -0500 +Subject: [PATCH] 0.113: authority: Fix memory leak in EnumerateActions call + results handler + +Policykit-1 doesn't release reference counters of GVariant data for +org.freedesktop.PolicyKit1.Authority.EnumerateActions dbus call. This +patch fixed reference counting and following memory leak. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=88288 +Origin: upstream, 0.113, commit:f4d71e0de885010494b8b0b8d62ca910011d7544 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitauthority.c | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/src/polkit/polkitauthority.c b/src/polkit/polkitauthority.c +index 9947cf3273b2..84dab72c6f0f 100644 +--- a/src/polkit/polkitauthority.c ++++ b/src/polkit/polkitauthority.c +@@ -715,7 +715,6 @@ polkit_authority_enumerate_actions_finish (PolkitAuthority *authority, + while ((child = g_variant_iter_next_value (&iter)) != NULL) + { + ret = g_list_prepend (ret, polkit_action_description_new_for_gvariant (child)); +- g_variant_ref_sink (child); + g_variant_unref (child); + } + ret = g_list_reverse (ret); diff --git a/patches/polkit-0.105/0021-0.113-CVE-2015-3218-backend-Handle-invalid-object-pa.patch b/patches/polkit-0.105/0021-0.113-CVE-2015-3218-backend-Handle-invalid-object-pa.patch new file mode 100644 index 000000000..688d87e55 --- /dev/null +++ b/patches/polkit-0.105/0021-0.113-CVE-2015-3218-backend-Handle-invalid-object-pa.patch @@ -0,0 +1,120 @@ +From: Colin Walters <walters@redhat.com> +Date: Sat, 30 May 2015 09:06:23 -0400 +Subject: [PATCH] 0.113: 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 + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=90829 +Bug-Debian: https://bugs.debian.org/787932 +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> +Origin: upstream, 0.113, commit:48e646918efb2bf0b3b505747655726d7869f31c + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + .../polkitbackendinteractiveauthority.c | 53 +++++++++++-------- + 1 file changed, 30 insertions(+), 23 deletions(-) + +diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c +index b237e9db0be8..25e13fb0907e 100644 +--- a/src/polkitbackend/polkitbackendinteractiveauthority.c ++++ b/src/polkitbackend/polkitbackendinteractiveauthority.c +@@ -1558,36 +1558,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; + } +@@ -2234,8 +2240,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); + +@@ -2322,7 +2326,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), diff --git a/patches/polkit-0.105/0022-0.113-sessionmonitor-systemd-Use-sd_uid_get_state-to.patch b/patches/polkit-0.105/0022-0.113-sessionmonitor-systemd-Use-sd_uid_get_state-to.patch new file mode 100644 index 000000000..6f10b2954 --- /dev/null +++ b/patches/polkit-0.105/0022-0.113-sessionmonitor-systemd-Use-sd_uid_get_state-to.patch @@ -0,0 +1,77 @@ +From: Philip Withnall <philip.withnall@collabora.co.uk> +Date: Tue, 2 Jun 2015 16:19:51 +0100 +Subject: [PATCH] 0.113: sessionmonitor-systemd: Use sd_uid_get_state() to + check session activity +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Instead of using sd_pid_get_session() then sd_session_is_active() to +determine whether the user is active, use sd_uid_get_state() directly. +This gets the maximum of the states of all the user’s sessions, rather +than the state of the session containing the subject process. Since the +user is the security boundary, this is fine. + +This change is necessary for `systemd --user` sessions, where most user +code will be forked off user@.service, rather than running inside the +logind session (whether that be a foreground/active or background/online +session). + +Policy-wise, the change is from checking whether the subject process is +in an active session; to checking whether the subject process is owned +by a user with at least one active session. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=76358 +Applied-upstream: 0.113, commit:a29653ffa99e0809e15aa34afcd7b2df8593871c +Bug-Debian: https://bugs.debian.org/779988 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + .../polkitbackendsessionmonitor-systemd.c | 33 ++++++++++++++++++- + 1 file changed, 32 insertions(+), 1 deletion(-) + +diff --git a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +index ebd05cea45dc..6bd517abb169 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +@@ -391,6 +391,37 @@ gboolean + polkit_backend_session_monitor_is_session_active (PolkitBackendSessionMonitor *monitor, + PolkitSubject *session) + { +- return sd_session_is_active (polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session))); ++ const char *session_id; ++ char *state; ++ uid_t uid; ++ gboolean is_active = FALSE; ++ ++ session_id = polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (session)); ++ ++ g_debug ("Checking whether session %s is active.", session_id); ++ ++ /* Check whether *any* of the user's current sessions are active. */ ++ if (sd_session_get_uid (session_id, &uid) < 0) ++ goto fallback; ++ ++ g_debug ("Session %s has UID %u.", session_id, uid); ++ ++ if (sd_uid_get_state (uid, &state) < 0) ++ goto fallback; ++ ++ g_debug ("UID %u has state %s.", uid, state); ++ ++ is_active = (g_strcmp0 (state, "active") == 0); ++ free (state); ++ ++ return is_active; ++ ++fallback: ++ /* Fall back to checking the session. This is not ideal, since the user ++ * might have multiple sessions, and we cannot guarantee to have chosen ++ * the active one. ++ * ++ * See: https://bugs.freedesktop.org/show_bug.cgi?id=76358. */ ++ return sd_session_is_active (session_id); + } + diff --git a/patches/polkit-0.105/0023-0.113-Fix-a-possible-NULL-dereference.patch b/patches/polkit-0.105/0023-0.113-Fix-a-possible-NULL-dereference.patch new file mode 100644 index 000000000..5bcc45010 --- /dev/null +++ b/patches/polkit-0.105/0023-0.113-Fix-a-possible-NULL-dereference.patch @@ -0,0 +1,39 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Wed, 11 Jun 2014 22:36:50 +0200 +Subject: [PATCH] 0.113: Fix a possible NULL dereference. +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +polkit_backend_session_monitor_get_user_for_subject() may return NULL +(and because it is using external processes, we can’t really rule it +out). The code was already anticipating NULL in the cleanup section, so +handle it also when actually using the value. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=80767 +Origin: upstream, 0.113, commit:6109543303def367b84eaac97d2ff9cefe735efb + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitbackend/polkitbackendinteractiveauthority.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c +index 25e13fb0907e..00ee0446445f 100644 +--- a/src/polkitbackend/polkitbackendinteractiveauthority.c ++++ b/src/polkitbackend/polkitbackendinteractiveauthority.c +@@ -557,7 +557,11 @@ log_result (PolkitBackendInteractiveAuthority *authority, + user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL); + + subject_str = polkit_subject_to_string (subject); +- user_of_subject_str = polkit_identity_to_string (user_of_subject); ++ ++ if (user_of_subject != NULL) ++ user_of_subject_str = polkit_identity_to_string (user_of_subject); ++ else ++ user_of_subject_str = g_strdup ("<unknown>"); + caller_str = polkit_subject_to_string (caller); + + subject_cmdline = _polkit_subject_get_cmdline (subject); diff --git a/patches/polkit-0.105/0024-0.113-Remove-a-redundant-assignment.patch b/patches/polkit-0.105/0024-0.113-Remove-a-redundant-assignment.patch new file mode 100644 index 000000000..aab9d157d --- /dev/null +++ b/patches/polkit-0.105/0024-0.113-Remove-a-redundant-assignment.patch @@ -0,0 +1,30 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Wed, 11 Jun 2014 22:44:28 +0200 +Subject: [PATCH] 0.113: Remove a redundant assignment. + +Instead of a nonsensical (data = data), use the more customary +((void)data) to silence the warning about an unused parameter. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=80767 +Origin: upstream, 0.113, commit:37143eb06cb0c4dffca67079dd1c10c5b191b6a7 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitagent/polkitagenthelper-pam.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/polkitagent/polkitagenthelper-pam.c b/src/polkitagent/polkitagenthelper-pam.c +index 292abbe44e88..937386e8f1d3 100644 +--- a/src/polkitagent/polkitagenthelper-pam.c ++++ b/src/polkitagent/polkitagenthelper-pam.c +@@ -230,7 +230,7 @@ conversation_function (int n, const struct pam_message **msg, struct pam_respons + gchar *tmp = NULL; + size_t len; + +- data = data; ++ (void)data; + if (n <= 0 || n > PAM_MAX_NUM_MSG) + return PAM_CONV_ERR; + diff --git a/patches/polkit-0.105/0025-0.113-Fix-duplicate-GError-use-when-uid-is-missing.patch b/patches/polkit-0.105/0025-0.113-Fix-duplicate-GError-use-when-uid-is-missing.patch new file mode 100644 index 000000000..eca000906 --- /dev/null +++ b/patches/polkit-0.105/0025-0.113-Fix-duplicate-GError-use-when-uid-is-missing.patch @@ -0,0 +1,36 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Mon, 15 Sep 2014 19:45:15 +0200 +Subject: [PATCH] 0.113: Fix duplicate GError use when "uid" is missing + +Some GLib versions complain loudly about this. + +To reproduce, call e.g. RegisterAuthenticationAgent with the following +parameters: +("unix-process", {"pid": __import__('gi.repository.GLib', globals(), +locals(), ['Variant']).Variant("u", 1), "start-time": +__import__('gi.repository.GLib', globals(), locals(), +['Variant']).Variant("t", 1)}), "cs", "/" + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=90877 +Origin: upstream, 0.113, commit:2c8738941be18ef05ce724df46547f41dbc02fb5 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitsubject.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c +index aed57951bb6b..78ec745a4df2 100644 +--- a/src/polkit/polkitsubject.c ++++ b/src/polkit/polkitsubject.c +@@ -424,7 +424,7 @@ polkit_subject_new_for_gvariant (GVariant *variant, + start_time = g_variant_get_uint64 (v); + g_variant_unref (v); + +- v = lookup_asv (details_gvariant, "uid", G_VARIANT_TYPE_INT32, error); ++ v = lookup_asv (details_gvariant, "uid", G_VARIANT_TYPE_INT32, NULL); + if (v != NULL) + { + uid = g_variant_get_int32 (v); diff --git a/patches/polkit-0.105/0026-0.113-Fix-a-crash-when-two-authentication-requests-a.patch b/patches/polkit-0.105/0026-0.113-Fix-a-crash-when-two-authentication-requests-a.patch new file mode 100644 index 000000000..46dd4293d --- /dev/null +++ b/patches/polkit-0.105/0026-0.113-Fix-a-crash-when-two-authentication-requests-a.patch @@ -0,0 +1,41 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Sat, 6 Jun 2015 01:07:08 +0200 +Subject: [PATCH] 0.113: Fix a crash when two authentication requests are in + flight. + +To reproduce: +1. pkttyagent -p $$ # or another suitable PID +2. pkcheck -p $that_pid -a org.freedesktop.policykit.exec -u +3. pkcheck -p $that_pid -a org.freedesktop.policykit.exec -u +4. Then, in the pkttyagent prompt, press Enter. + +polkit_agent_text_listener_initiate_authentication was already setting +an appropriate error code, so the g_assert was unnecessary. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=90879 +Origin: upstream, 0.113, commit:e2d2fafd106624ddfea4b17d3f40704b2031c00b + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitagent/polkitagenttextlistener.c | 2 -- + 1 file changed, 2 deletions(-) + +diff --git a/src/polkitagent/polkitagenttextlistener.c b/src/polkitagent/polkitagenttextlistener.c +index b5c8a3f370e1..e63c2853cfe5 100644 +--- a/src/polkitagent/polkitagenttextlistener.c ++++ b/src/polkitagent/polkitagenttextlistener.c +@@ -546,12 +546,10 @@ polkit_agent_text_listener_initiate_authentication_finish (PolkitAgentListener + GAsyncResult *res, + GError **error) + { +- PolkitAgentTextListener *listener = POLKIT_AGENT_TEXT_LISTENER (_listener); + gboolean ret; + + g_warn_if_fail (g_simple_async_result_get_source_tag (G_SIMPLE_ASYNC_RESULT (res)) == + polkit_agent_text_listener_initiate_authentication); +- g_assert (listener->active_session == NULL); + + ret = FALSE; + diff --git a/patches/polkit-0.105/0027-0.113-CVE-2015-4625-Use-unpredictable-cookie-values-.patch b/patches/polkit-0.105/0027-0.113-CVE-2015-4625-Use-unpredictable-cookie-values-.patch new file mode 100644 index 000000000..612bc4ef7 --- /dev/null +++ b/patches/polkit-0.105/0027-0.113-CVE-2015-4625-Use-unpredictable-cookie-values-.patch @@ -0,0 +1,545 @@ +From: Colin Walters <walters@redhat.com> +Date: Thu, 4 Jun 2015 12:15:18 -0400 +Subject: [PATCH] 0.113: 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> +Origin: upstream, 0.113, commit:ea544ffc18405237ccd95d28d7f45afef49aca17 +Bug-Debian: https://bugs.debian.org/796134 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + configure.ac | 2 +- + src/polkitagent/polkitagenthelper-pam.c | 12 ++- + src/polkitagent/polkitagenthelper-shadow.c | 12 ++- + src/polkitagent/polkitagenthelperprivate.c | 33 +++++++ + src/polkitagent/polkitagenthelperprivate.h | 2 + + src/polkitagent/polkitagentsession.c | 30 +++--- + .../polkitbackendinteractiveauthority.c | 99 +++++++++++++++---- + 7 files changed, 150 insertions(+), 40 deletions(-) + +diff --git a/configure.ac b/configure.ac +index aa2760f90606..388605d2cb08 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -123,7 +123,7 @@ if test "x$GCC" = "xyes"; then + changequote([,])dnl + fi + +-PKG_CHECK_MODULES(GLIB, [gio-2.0 >= 2.28.0]) ++PKG_CHECK_MODULES(GLIB, [gmodule-2.0 gio-unix-2.0 >= 2.30.0]) + AC_SUBST(GLIB_CFLAGS) + AC_SUBST(GLIB_LIBS) + +diff --git a/src/polkitagent/polkitagenthelper-pam.c b/src/polkitagent/polkitagenthelper-pam.c +index 937386e8f1d3..19062aa8d0da 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 a4f73acff3a9..e87791541a9c 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 4417e70f6ef7..a99de7dd5c16 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 aeca2c74d44a..547fdccfd2e2 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 a658a2295da7..6a3d6bc94c49 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_LIBEXEC_DIR "/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 00ee0446445f..10eda2c7fb36 100644 +--- a/src/polkitbackend/polkitbackendinteractiveauthority.c ++++ b/src/polkitbackend/polkitbackendinteractiveauthority.c +@@ -212,6 +212,8 @@ typedef struct + + GDBusConnection *system_bus_connection; + guint name_owner_changed_signal_id; ++ ++ guint64 agent_serial; + } PolkitBackendInteractiveAuthorityPrivate; + + /* ---------------------------------------------------------------------------------------------------- */ +@@ -430,11 +432,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; + +@@ -1430,9 +1436,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, +@@ -1449,7 +1500,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; + } + +@@ -2083,7 +2147,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent, + gpointer user_data) + { + AuthenticationSession *session; +- gchar *cookie; + GList *l; + GList *identities; + gchar *localized_message; +@@ -2104,8 +2167,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 */ +@@ -2125,7 +2186,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent, + } + + session = authentication_session_new (agent, +- cookie, + subject, + user_of_subject, + caller, +@@ -2179,7 +2239,6 @@ authentication_agent_initiate_challenge (AuthenticationAgent *agent, + + 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); +@@ -2326,7 +2385,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, diff --git a/patches/polkit-0.105/0028-0.113-CVE-2015-4625-Bind-use-of-cookies-to-specific-.patch b/patches/polkit-0.105/0028-0.113-CVE-2015-4625-Bind-use-of-cookies-to-specific-.patch new file mode 100644 index 000000000..871bf9fbc --- /dev/null +++ b/patches/polkit-0.105/0028-0.113-CVE-2015-4625-Bind-use-of-cookies-to-specific-.patch @@ -0,0 +1,488 @@ +From: Colin Walters <walters@redhat.com> +Date: Wed, 17 Jun 2015 13:07:02 -0400 +Subject: [PATCH] 0.113: 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> +Origin: upstream, 0.113, commit:493aa5dc1d278ab9097110c1262f5229bbaf1766 +Bug-Debian: https://bugs.debian.org/796134 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + ...desktop.PolicyKit1.AuthenticationAgent.xml | 14 ++++- + data/org.freedesktop.PolicyKit1.Authority.xml | 24 +++++++- + ...e-org.freedesktop.PolicyKit1.Authority.xml | 46 +++++++++++++- + docs/polkit/overview.xml | 18 +++--- + src/polkit/polkitauthority.c | 13 +++- + src/polkitbackend/polkitbackendauthority.c | 61 ++++++++++++++++++- + src/polkitbackend/polkitbackendauthority.h | 2 + + .../polkitbackendinteractiveauthority.c | 39 ++++++++++-- + 8 files changed, 198 insertions(+), 19 deletions(-) + +diff --git a/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml b/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml +index 3b519c2fb2c2..5beef7d4ef92 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 fbfb9cdcfbad..f9021ee2e7c8 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 6525e250acc2..e66bf5349c61 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,9 +779,51 @@ 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> +diff --git a/docs/polkit/overview.xml b/docs/polkit/overview.xml +index 24440d2ed03d..c29d8da242c6 100644 +--- a/docs/polkit/overview.xml ++++ b/docs/polkit/overview.xml +@@ -66,16 +66,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 84dab72c6f0f..f45abc4ad946 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 fd4f161c3a61..d1b1a257e435 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 a564054f433a..1c212e0d4937 100644 +--- a/src/polkitbackend/polkitbackendauthority.h ++++ b/src/polkitbackend/polkitbackendauthority.h +@@ -154,6 +154,7 @@ struct _PolkitBackendAuthorityClass + + gboolean (*authentication_agent_response) (PolkitBackendAuthority *authority, + PolkitSubject *caller, ++ uid_t uid, + const gchar *cookie, + PolkitIdentity *identity, + GError **error); +@@ -256,6 +257,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 10eda2c7fb36..5e29af2c83ce 100644 +--- a/src/polkitbackend/polkitbackendinteractiveauthority.c ++++ b/src/polkitbackend/polkitbackendinteractiveauthority.c +@@ -106,8 +106,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); +@@ -167,6 +168,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); +@@ -431,6 +433,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; +@@ -2388,6 +2415,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, +@@ -2601,6 +2629,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) +@@ -2643,7 +2672,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, diff --git a/patches/polkit-0.105/0029-0.113-docs-Update-for-changes-to-uid-binding-Authent.patch b/patches/polkit-0.105/0029-0.113-docs-Update-for-changes-to-uid-binding-Authent.patch new file mode 100644 index 000000000..ff1e8bd29 --- /dev/null +++ b/patches/polkit-0.105/0029-0.113-docs-Update-for-changes-to-uid-binding-Authent.patch @@ -0,0 +1,264 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Wed, 17 Jun 2015 01:01:27 +0200 +Subject: [PATCH] 0.113: docs: Update for changes to uid + binding/AuthenticationAgentResponse2 + + - Refer to PolkitAgentSession in general instead of to _response only + - Revert to the original description of authentication cancellation, the + agent really needs to return an error to the caller (in addition to dealing + with the session if any). + - Explicitly document the UID assumption; in the process fixing bug #69980. + - Keep documenting that we need a sufficiently privileged caller. + - Refer to the ...Response2 API in more places. + - Also update docbook documentation. + - Drop a paragraph suggesting non-PolkitAgentSession implementations are + expected and commonplace. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=90837 +Reviewed-by: Colin Walters <walters@redhat.com> +Origin: upstream, 0.113, commit:fb5076b7c05d01a532d593a4079a29cf2d63a228 +Bug-Debian: https://bugs.debian.org/796134 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + ...desktop.PolicyKit1.AuthenticationAgent.xml | 6 ++--- + data/org.freedesktop.PolicyKit1.Authority.xml | 11 +++++---- + ...desktop.PolicyKit1.AuthenticationAgent.xml | 7 ++++-- + ...e-org.freedesktop.PolicyKit1.Authority.xml | 12 ++++++---- + docs/polkit/overview.xml | 8 +++---- + src/polkit/polkitauthority.c | 24 +++++++++++++++++-- + src/polkitagent/polkitagentlistener.c | 5 +--- + src/polkitbackend/polkitbackendauthority.c | 1 + + 8 files changed, 51 insertions(+), 23 deletions(-) + +diff --git a/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml b/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml +index 5beef7d4ef92..482332f6fc35 100644 +--- a/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml ++++ b/data/org.freedesktop.PolicyKit1.AuthenticationAgent.xml +@@ -13,14 +13,14 @@ + 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 ++ PolkitAgentSession 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>"/> ++ authentication dialog, the authentication agent should return an ++ error.</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 f9021ee2e7c8..88da3c052cbe 100644 +--- a/data/org.freedesktop.PolicyKit1.Authority.xml ++++ b/data/org.freedesktop.PolicyKit1.Authority.xml +@@ -283,7 +283,7 @@ + <!-- ---------------------------------------------------------------------------------------------------- --> + + <method name="RegisterAuthenticationAgent"> +- <annotation name="org.gtk.EggDBus.DocString" value="<para>Register an authentication agent.</para><para>Note that current versions of PolicyKit will only work if @session_id is set to the empty string. In the future it might work for non-empty strings if the caller is sufficiently privileged.</para>"/> ++ <annotation name="org.gtk.EggDBus.DocString" value="<para>Register an authentication agent.</para><para>Note that this should be called by the same effective UID which will be passed to org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse2().</para>"/> + + <arg name="subject" direction="in" type="(sa{sv})"> + <annotation name="org.gtk.EggDBus.Type" value="Subject"/> +@@ -315,7 +315,8 @@ + <method name="AuthenticationAgentResponse"> + <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."/> ++internal to polkit. This method will fail unless a sufficiently privileged ++caller invokes it. Deprecated in favor of org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse2."/> + + <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."/> +@@ -330,11 +331,13 @@ internal to polkit."/> + <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 ++internal to polkit. This method will fail unless a sufficiently privileged ++caller invokes it. Note this method was added in 0.114, and should be preferred over org.freedesktop.PolicyKit1.Authority.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."/> ++ <annotation name="org.gtk.EggDBus.DocString" value="The real uid of the agent. Normally set by the setuid helper program. ++Must match the effective UID of the caller of org.freedesktop.PolicyKit1.Authority.RegisterAuthenticationAgent()."/> + </arg> + + <arg name="cookie" direction="in" type="s"> +diff --git a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml +index ec596268cc3c..ab27b2f6638c 100644 +--- a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml ++++ b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.AuthenticationAgent.xml +@@ -47,10 +47,13 @@ BeginAuthentication (IN String action_id, + identifier <parameter>action_id</parameter>.</para><para>Upon + succesful authentication, the authentication agent must invoke + the <link +- linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse">AuthenticationAgentResponse()</link> ++ linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse2">AuthenticationAgentResponse2()</link> + method on the <link + linkend="eggdbus-interface-org.freedesktop.PolicyKit1.Authority">org.freedesktop.PolicyKit1.Authority</link> +- interface of the PolicyKit daemon before returning. ++ interface of the PolicyKit daemon before returning. This is normally ++ achieved via the <link linkend="PolkitAgentSession">PolkitAgentSession</link> ++ API, which invokes a private setuid helper process to verify the ++ authentication. + </para> + <para> + The authentication agent should not return until after authentication is complete. +diff --git a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml +index e66bf5349c61..f2eed63999de 100644 +--- a/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml ++++ b/docs/polkit/docbook-interface-org.freedesktop.PolicyKit1.Authority.xml +@@ -42,7 +42,7 @@ 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, ++<link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse2">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) +@@ -701,7 +701,7 @@ RegisterAuthenticationAgent (IN <link linkend="eggdbus-struct-Subject">Subject< + IN String object_path) + </programlisting> + <para> +-<para>Register an authentication agent.</para><para>Note that current versions of PolicyKit will only work if <parameter>session_id</parameter> is set to the empty string. In the future it might work for non-empty strings if the caller is sufficiently privileged.</para> ++<para>Register an authentication agent.</para><para>Note that this should be called by same effective UID which will be passed to <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse2">AuthenticationAgentResponse2()</link>.</para> + </para> + <variablelist role="params"> + <varlistentry> +@@ -781,7 +781,8 @@ AuthenticationAgentResponse (IN String cookie, + <para> + 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. ++internal to polkit. This method will fail unless a sufficiently privileged +++caller invokes it. Deprecated in favor of <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse2">AuthenticationAgentResponse2()</link>. + </para> + <variablelist role="params"> + <varlistentry> +@@ -812,7 +813,10 @@ AuthenticationAgentResponse2 (IN uint32 uid, + <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. ++internal to polkit. This method will fail unless a sufficiently privileged ++caller invokes it. Note this method was introduced in 0.114 and should be ++preferred over <link linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse">AuthenticationAgentResponse()</link> ++as it fixes a security issue. + </para> + <variablelist role="params"> + <varlistentry> +diff --git a/docs/polkit/overview.xml b/docs/polkit/overview.xml +index c29d8da242c6..8ddb34ccb1de 100644 +--- a/docs/polkit/overview.xml ++++ b/docs/polkit/overview.xml +@@ -73,11 +73,11 @@ + 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> ++ linkend="eggdbus-method-org.freedesktop.PolicyKit1.Authority.AuthenticationAgentResponse2">AuthenticationAgentResponse2()</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. ++ implementation detail, and callers should use the ++ <link linkend="PolkitAgentSession">PolkitAgentSession</link> 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 f45abc4ad946..4e882e6412ea 100644 +--- a/src/polkit/polkitauthority.c ++++ b/src/polkit/polkitauthority.c +@@ -1038,6 +1038,10 @@ polkit_authority_check_authorization_sync (PolkitAuthority *author + * + * Asynchronously registers an authentication agent. + * ++ * Note that this should be called by the same effective UID which will be ++ * the real UID using the #PolkitAgentSession API or otherwise calling ++ * polkit_authority_authentication_agent_response(). ++ * + * When the operation is finished, @callback will be invoked in the + * <link linkend="g-main-context-push-thread-default">thread-default + * main loop</link> of the thread you are calling this method +@@ -1129,7 +1133,13 @@ polkit_authority_register_authentication_agent_finish (PolkitAuthority *authorit + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: (allow-none): Return location for error or %NULL. + * +- * Registers an authentication agent. The calling thread is blocked ++ * Registers an authentication agent. ++ * ++ * Note that this should be called by the same effective UID which will be ++ * the real UID using the #PolkitAgentSession API or otherwise calling ++ * polkit_authority_authentication_agent_response(). ++ * ++ * The calling thread is blocked + * until a reply is received. See + * polkit_authority_register_authentication_agent() for the + * asynchronous version. +@@ -1178,6 +1188,10 @@ polkit_authority_register_authentication_agent_sync (PolkitAuthority *author + * + * Asynchronously registers an authentication agent. + * ++ * Note that this should be called by the same effective UID which will be ++ * the real UID using the #PolkitAgentSession API or otherwise calling ++ * polkit_authority_authentication_agent_response(). ++ * + * When the operation is finished, @callback will be invoked in the + * <link linkend="g-main-context-push-thread-default">thread-default + * main loop</link> of the thread you are calling this method +@@ -1292,7 +1306,13 @@ polkit_authority_register_authentication_agent_with_options_finish (PolkitAuthor + * @cancellable: (allow-none): A #GCancellable or %NULL. + * @error: (allow-none): Return location for error or %NULL. + * +- * Registers an authentication agent. The calling thread is blocked ++ * Registers an authentication agent. ++ * ++ * Note that this should be called by the same effective UID which will be ++ * the real UID using the #PolkitAgentSession API or otherwise calling ++ * polkit_authority_authentication_agent_response(). ++ * ++ * The calling thread is blocked + * until a reply is received. See + * polkit_authority_register_authentication_agent_with_options() for the + * asynchronous version. +diff --git a/src/polkitagent/polkitagentlistener.c b/src/polkitagent/polkitagentlistener.c +index 0d97501a028c..10dbfb9c0d4e 100644 +--- a/src/polkitagent/polkitagentlistener.c ++++ b/src/polkitagent/polkitagentlistener.c +@@ -37,10 +37,7 @@ + * + * Typically authentication agents use #PolkitAgentSession to + * authenticate users (via passwords) and communicate back the +- * authentication result to the PolicyKit daemon. This is however not +- * requirement. Depending on the system an authentication agent may +- * use other means (such as a Yes/No dialog) to obtain sufficient +- * evidence that the user is one of the requested identities. ++ * authentication result to the PolicyKit daemon. + * + * To register a #PolkitAgentListener with the PolicyKit daemon, use + * polkit_agent_listener_register() or +diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c +index d1b1a257e435..10b8af34205c 100644 +--- a/src/polkitbackend/polkitbackendauthority.c ++++ b/src/polkitbackend/polkitbackendauthority.c +@@ -343,6 +343,7 @@ polkit_backend_authority_unregister_authentication_agent (PolkitBackendAuthority + * polkit_backend_authority_authentication_agent_response: + * @authority: A #PolkitBackendAuthority. + * @caller: The system bus name that initiated the query. ++ * @uid: The real UID of the registered agent, or (uid_t)-1 if unknown. + * @cookie: The cookie passed to the authentication agent from the authority. + * @identity: The identity that was authenticated. + * @error: Return location for error or %NULL. diff --git a/patches/polkit-0.105/0030-0.113-Fix-a-per-authorization-memory-leak.patch b/patches/polkit-0.105/0030-0.113-Fix-a-per-authorization-memory-leak.patch new file mode 100644 index 000000000..a3428746e --- /dev/null +++ b/patches/polkit-0.105/0030-0.113-Fix-a-per-authorization-memory-leak.patch @@ -0,0 +1,53 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Tue, 1 Jul 2014 20:00:48 +0200 +Subject: [PATCH] 0.113: Fix a per-authorization memory leak + +We were leaking PolkitAuthorizationResult on every request, primarily on +the success path, but also on various error paths as well. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69501 +Origin: upstream, 0.113, commit:0f5852a4bdabe377ddcdbed09a0c1f95710e17fe + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitbackend/polkitbackendauthority.c | 1 + + src/polkitbackend/polkitbackendinteractiveauthority.c | 5 ++++- + 2 files changed, 5 insertions(+), 1 deletion(-) + +diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c +index 10b8af34205c..39eb5b9d29fa 100644 +--- a/src/polkitbackend/polkitbackendauthority.c ++++ b/src/polkitbackend/polkitbackendauthority.c +@@ -714,6 +714,7 @@ check_auth_cb (GObject *source_object, + g_variant_ref_sink (value); + g_dbus_method_invocation_return_value (data->invocation, g_variant_new ("(@(bba{ss}))", value)); + g_variant_unref (value); ++ g_object_unref (result); + } + + check_auth_data_free (data); +diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c +index 5e29af2c83ce..73d0a0e29e24 100644 +--- a/src/polkitbackend/polkitbackendinteractiveauthority.c ++++ b/src/polkitbackend/polkitbackendinteractiveauthority.c +@@ -1015,7 +1015,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + + /* Otherwise just return the result */ + g_simple_async_result_set_op_res_gpointer (simple, +- result, ++ g_object_ref (result), + g_object_unref); + g_simple_async_result_complete (simple); + g_object_unref (simple); +@@ -1032,6 +1032,9 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + g_free (subject_str); + g_free (user_of_caller_str); + g_free (user_of_subject_str); ++ ++ if (result != NULL) ++ g_object_unref (result); + } + + /* ---------------------------------------------------------------------------------------------------- */ diff --git a/patches/polkit-0.105/0031-0.113-Fix-a-memory-leak-when-registering-an-authenti.patch b/patches/polkit-0.105/0031-0.113-Fix-a-memory-leak-when-registering-an-authenti.patch new file mode 100644 index 000000000..aa649cf24 --- /dev/null +++ b/patches/polkit-0.105/0031-0.113-Fix-a-memory-leak-when-registering-an-authenti.patch @@ -0,0 +1,27 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Tue, 1 Jul 2014 20:00:48 +0200 +Subject: [PATCH] 0.113: Fix a memory leak when registering an authentication + agent + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=69501 +Origin: upstream, 0.113, commit:ec039f9d7ede5b839f5511e26d5cd6ae9107cb2e + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitbackend/polkitbackendauthority.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/polkitbackend/polkitbackendauthority.c b/src/polkitbackend/polkitbackendauthority.c +index 39eb5b9d29fa..afe5b90c140e 100644 +--- a/src/polkitbackend/polkitbackendauthority.c ++++ b/src/polkitbackend/polkitbackendauthority.c +@@ -900,6 +900,7 @@ server_handle_register_authentication_agent (Server *server, + g_dbus_method_invocation_return_value (invocation, g_variant_new ("()")); + + out: ++ g_variant_unref (subject_gvariant); + if (subject != NULL) + g_object_unref (subject); + } diff --git a/patches/polkit-0.105/0032-0.113-CVE-2015-3255-Fix-GHashTable-usage.patch b/patches/polkit-0.105/0032-0.113-CVE-2015-3255-Fix-GHashTable-usage.patch new file mode 100644 index 000000000..9303bf791 --- /dev/null +++ b/patches/polkit-0.105/0032-0.113-CVE-2015-3255-Fix-GHashTable-usage.patch @@ -0,0 +1,72 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Wed, 1 Apr 2015 05:22:37 +0200 +Subject: [PATCH] 0.113: 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 +Origin: upstream, 0.113, commit:9f5e0c731784003bd4d6fc75ab739ff8b2ea269f +Bug-Debian: https://bugs.debian.org/796134 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitbackend/polkitbackendactionpool.c | 8 +++----- + 1 file changed, 3 insertions(+), 5 deletions(-) + +diff --git a/src/polkitbackend/polkitbackendactionpool.c b/src/polkitbackend/polkitbackendactionpool.c +index e3ed38d4a81e..4270d4ed2b41 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; diff --git a/patches/polkit-0.105/0033-0.113-Fix-use-after-free-in-polkitagentsession.c.patch b/patches/polkit-0.105/0033-0.113-Fix-use-after-free-in-polkitagentsession.c.patch new file mode 100644 index 000000000..ee35b7cb2 --- /dev/null +++ b/patches/polkit-0.105/0033-0.113-Fix-use-after-free-in-polkitagentsession.c.patch @@ -0,0 +1,36 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Tue, 14 Apr 2015 22:27:41 +0200 +Subject: [PATCH] 0.113: Fix use-after-free in polkitagentsession.c + +PolkitAgentTextListener's "completed" handler drops the last reference +to the session; in fact this is explicitly recommended in the signal's +documentation. So we must not access any members of session after +emitting the signal. + +Found while dealing with +https://bugs.freedesktop.org/show_bug.cgi?id=69501 + +Origin: upstream, 0.113, commit:efb6cd56a423ba15bb1f44ee3c4987aad5a5fd45 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitagent/polkitagentsession.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/src/polkitagent/polkitagentsession.c b/src/polkitagent/polkitagentsession.c +index 6a3d6bc94c49..46fbaf06f469 100644 +--- a/src/polkitagent/polkitagentsession.c ++++ b/src/polkitagent/polkitagentsession.c +@@ -412,8 +412,9 @@ complete_session (PolkitAgentSession *session, + { + if (G_UNLIKELY (_show_debug ())) + g_print ("PolkitAgentSession: emitting ::completed(%s)\n", result ? "TRUE" : "FALSE"); +- g_signal_emit_by_name (session, "completed", result); + session->have_emitted_completed = TRUE; ++ /* Note that the signal handler may drop the last reference to session. */ ++ g_signal_emit_by_name (session, "completed", result); + } + } + diff --git a/patches/polkit-0.105/0034-0.114-Fix-multi-line-pam-text-info.patch b/patches/polkit-0.105/0034-0.114-Fix-multi-line-pam-text-info.patch new file mode 100644 index 000000000..5c51de5a7 --- /dev/null +++ b/patches/polkit-0.105/0034-0.114-Fix-multi-line-pam-text-info.patch @@ -0,0 +1,43 @@ +From: Dariusz Gadomski <dariusz.gadomski@canonical.com> +Date: Tue, 10 Nov 2015 10:52:02 +0100 +Subject: [PATCH] 0.114: Fix multi-line pam text info. + +There are pam modules (e.g. pam_vas) that may attempt to display multi-line +PAM_TEXT_INFO messages. Polkit was interpreting the lines after the first one +as a separate message that was not recognized causing the authorization +to fail. Escaping these strings and unescaping them fixes the issue. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=92886 +Origin: upstream, 0.114, commit:10597322eccc320f9053821750ae9af51e918d74 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitagent/polkitagenthelper-pam.c | 13 +++++++++---- + 1 file changed, 9 insertions(+), 4 deletions(-) + +diff --git a/src/polkitagent/polkitagenthelper-pam.c b/src/polkitagent/polkitagenthelper-pam.c +index 19062aa8d0da..063d656dcbef 100644 +--- a/src/polkitagent/polkitagenthelper-pam.c ++++ b/src/polkitagent/polkitagenthelper-pam.c +@@ -302,10 +302,15 @@ conversation_function (int n, const struct pam_message **msg, struct pam_respons + case PAM_TEXT_INFO: + fprintf (stdout, "PAM_TEXT_INFO "); + conv2: +- fputs (msg[i]->msg, stdout); +- if (strlen (msg[i]->msg) > 0 && +- msg[i]->msg[strlen (msg[i]->msg) - 1] != '\n') +- fputc ('\n', stdout); ++ tmp = g_strdup (msg[i]->msg); ++ len = strlen (tmp); ++ if (len > 0 && tmp[len - 1] == '\n') ++ tmp[len - 1] = '\0'; ++ escaped = g_strescape (tmp, NULL); ++ g_free (tmp); ++ fputs (escaped, stdout); ++ g_free (escaped); ++ fputc ('\n', stdout); + fflush (stdout); + break; + diff --git a/patches/polkit-0.105/0035-0.114-Refactor-send_to_helper-usage.patch b/patches/polkit-0.105/0035-0.114-Refactor-send_to_helper-usage.patch new file mode 100644 index 000000000..8be72ef26 --- /dev/null +++ b/patches/polkit-0.105/0035-0.114-Refactor-send_to_helper-usage.patch @@ -0,0 +1,153 @@ +From: Dariusz Gadomski <dariusz.gadomski@canonical.com> +Date: Thu, 12 Nov 2015 15:01:19 +0100 +Subject: [PATCH] 0.114: Refactor send_to_helper usage + +There were duplicated pieces of code detecting EOLs and escaping the code. +Those actions has been delegated to already-existing send_to_helper function. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=92886 +Origin: upstream, 0.114, commit:2690cd0312b310946c86674c8dd1f55c63f7dd6a + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitagent/polkitagenthelper-pam.c | 81 ++++++++----------------- + 1 file changed, 26 insertions(+), 55 deletions(-) + +diff --git a/src/polkitagent/polkitagenthelper-pam.c b/src/polkitagent/polkitagenthelper-pam.c +index 063d656dcbef..3ea3a3f2e801 100644 +--- a/src/polkitagent/polkitagenthelper-pam.c ++++ b/src/polkitagent/polkitagenthelper-pam.c +@@ -39,25 +39,35 @@ static void + send_to_helper (const gchar *str1, + const gchar *str2) + { ++ char *escaped; ++ char *tmp2; ++ size_t len2; ++ ++ tmp2 = g_strdup(str2); ++ len2 = strlen(tmp2); + #ifdef PAH_DEBUG +- fprintf (stderr, "polkit-agent-helper-1: writing `%s' to stdout\n", str1); ++ fprintf (stderr, "polkit-agent-helper-1: writing `%s ' to stdout\n", str1); + #endif /* PAH_DEBUG */ +- fprintf (stdout, "%s", str1); ++ fprintf (stdout, "%s ", str1); ++ ++ if (len2 > 0 && tmp2[len2 - 1] == '\n') ++ tmp2[len2 - 1] = '\0'; ++ escaped = g_strescape (tmp2, NULL); + #ifdef PAH_DEBUG +- fprintf (stderr, "polkit-agent-helper-1: writing `%s' to stdout\n", str2); ++ fprintf (stderr, "polkit-agent-helper-1: writing `%s' to stdout\n", escaped); + #endif /* PAH_DEBUG */ +- fprintf (stdout, "%s", str2); +- if (strlen (str2) > 0 && str2[strlen (str2) - 1] != '\n') +- { ++ fprintf (stdout, "%s", escaped); + #ifdef PAH_DEBUG +- fprintf (stderr, "polkit-agent-helper-1: writing newline to stdout\n"); ++ fprintf (stderr, "polkit-agent-helper-1: writing newline to stdout\n"); + #endif /* PAH_DEBUG */ +- fputc ('\n', stdout); +- } ++ fputc ('\n', stdout); + #ifdef PAH_DEBUG + fprintf (stderr, "polkit-agent-helper-1: flushing stdout\n"); + #endif /* PAH_DEBUG */ + fflush (stdout); ++ ++ g_free (escaped); ++ g_free (tmp2); + } + + int +@@ -89,7 +99,7 @@ main (int argc, char *argv[]) + + /* Special-case a very common error triggered in jhbuild setups */ + s = g_strdup_printf ("Incorrect permissions on %s (needs to be setuid root)", argv[0]); +- send_to_helper ("PAM_ERROR_MSG ", s); ++ send_to_helper ("PAM_ERROR_MSG", s); + g_free (s); + goto error; + } +@@ -232,9 +242,6 @@ conversation_function (int n, const struct pam_message **msg, struct pam_respons + struct pam_response *aresp; + char buf[PAM_MAX_RESP_SIZE]; + int i; +- gchar *escaped = NULL; +- gchar *tmp = NULL; +- size_t len; + + (void)data; + if (n <= 0 || n > PAM_MAX_NUM_MSG) +@@ -251,38 +258,13 @@ conversation_function (int n, const struct pam_message **msg, struct pam_respons + { + + case PAM_PROMPT_ECHO_OFF: +-#ifdef PAH_DEBUG +- fprintf (stderr, "polkit-agent-helper-1: writing `PAM_PROMPT_ECHO_OFF ' to stdout\n"); +-#endif /* PAH_DEBUG */ +- fprintf (stdout, "PAM_PROMPT_ECHO_OFF "); ++ send_to_helper ("PAM_PROMPT_ECHO_OFF", msg[i]->msg); + goto conv1; + + case PAM_PROMPT_ECHO_ON: +-#ifdef PAH_DEBUG +- fprintf (stderr, "polkit-agent-helper-1: writing `PAM_PROMPT_ECHO_ON ' to stdout\n"); +-#endif /* PAH_DEBUG */ +- fprintf (stdout, "PAM_PROMPT_ECHO_ON "); +- conv1: +-#ifdef PAH_DEBUG +- fprintf (stderr, "polkit-agent-helper-1: writing `%s' to stdout\n", msg[i]->msg); +-#endif /* PAH_DEBUG */ +- tmp = g_strdup (msg[i]->msg); +- len = strlen (tmp); +- if (len > 0 && tmp[len - 1] == '\n') +- tmp[len - 1] = '\0'; +- escaped = g_strescape (tmp, NULL); +- g_free (tmp); +- fputs (escaped, stdout); +- g_free (escaped); +-#ifdef PAH_DEBUG +- fprintf (stderr, "polkit-agent-helper-1: writing newline to stdout\n"); +-#endif /* PAH_DEBUG */ +- fputc ('\n', stdout); +-#ifdef PAH_DEBUG +- fprintf (stderr, "polkit-agent-helper-1: flushing stdout\n"); +-#endif /* PAH_DEBUG */ +- fflush (stdout); ++ send_to_helper ("PAM_PROMPT_ECHO_ON", msg[i]->msg); + ++ conv1: + if (fgets (buf, sizeof buf, stdin) == NULL) + goto error; + +@@ -296,22 +278,11 @@ conversation_function (int n, const struct pam_message **msg, struct pam_respons + break; + + case PAM_ERROR_MSG: +- fprintf (stdout, "PAM_ERROR_MSG "); +- goto conv2; ++ send_to_helper ("PAM_ERROR_MSG", msg[i]->msg); ++ break; + + case PAM_TEXT_INFO: +- fprintf (stdout, "PAM_TEXT_INFO "); +- conv2: +- tmp = g_strdup (msg[i]->msg); +- len = strlen (tmp); +- if (len > 0 && tmp[len - 1] == '\n') +- tmp[len - 1] = '\0'; +- escaped = g_strescape (tmp, NULL); +- g_free (tmp); +- fputs (escaped, stdout); +- g_free (escaped); +- fputc ('\n', stdout); +- fflush (stdout); ++ send_to_helper ("PAM_TEXT_INFO", msg[i]->msg); + break; + + default: diff --git a/patches/polkit-0.105/0036-0.114-Support-polkit-session-agent-running-outside-u.patch b/patches/polkit-0.105/0036-0.114-Support-polkit-session-agent-running-outside-u.patch new file mode 100644 index 000000000..49ee8a807 --- /dev/null +++ b/patches/polkit-0.105/0036-0.114-Support-polkit-session-agent-running-outside-u.patch @@ -0,0 +1,56 @@ +From: Sebastien Bacher <seb128@ubuntu.com> +Date: Mon, 2 Apr 2018 10:52:47 -0400 +Subject: [PATCH] 0.114: Support polkit session agent running outside user + session + +commit a68f5dfd7662767b7b9822090b70bc5bd145c50c made +session applications that are running from a user bus +work with polkitd, by falling back to using the currently +active session. + +This commit is similar, but for the polkit agent. It allows, +a polkit agent to be run from a systemd --user service +that's not running directly in the users session. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=96977 +Applied-upstream: 0.114, commit:00a663e3fb14d8023e7cb6a66d091872bf4f2851 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitunixsession-systemd.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/polkit/polkitunixsession-systemd.c b/src/polkit/polkitunixsession-systemd.c +index 8a8bf65b9995..c34f36a909cf 100644 +--- a/src/polkit/polkitunixsession-systemd.c ++++ b/src/polkit/polkitunixsession-systemd.c +@@ -451,6 +451,7 @@ polkit_unix_session_initable_init (GInitable *initable, + PolkitUnixSession *session = POLKIT_UNIX_SESSION (initable); + gboolean ret = FALSE; + char *s; ++ uid_t uid; + + if (session->session_id != NULL) + { +@@ -467,6 +468,19 @@ polkit_unix_session_initable_init (GInitable *initable, + goto out; + } + ++ /* Now do process -> uid -> graphical session (systemd version 213)*/ ++ if (sd_pid_get_owner_uid (session->pid, &uid) < 0) ++ goto error; ++ ++ if (sd_uid_get_display (uid, &s) >= 0) ++ { ++ session->session_id = g_strdup (s); ++ free (s); ++ ret = TRUE; ++ goto out; ++ } ++ ++error: + g_set_error (error, + POLKIT_ERROR, + POLKIT_ERROR_FAILED, diff --git a/patches/polkit-0.105/0037-0.115-Fix-CVE-2018-1116-Trusting-client-supplied-UID.patch b/patches/polkit-0.105/0037-0.115-Fix-CVE-2018-1116-Trusting-client-supplied-UID.patch new file mode 100644 index 000000000..eaffd94a7 --- /dev/null +++ b/patches/polkit-0.105/0037-0.115-Fix-CVE-2018-1116-Trusting-client-supplied-UID.patch @@ -0,0 +1,573 @@ +From: =?UTF-8?q?Miloslav=20Trma=C4=8D?= <mitr@redhat.com> +Date: Mon, 25 Jun 2018 19:24:06 +0200 +Subject: [PATCH] 0.115: Fix CVE-2018-1116: Trusting client-supplied UID +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +As part of CVE-2013-4288, the D-Bus clients were allowed (and +encouraged) to submit the UID of the subject of authorization checks +to avoid races against UID changes (notably using executables +set-UID to root). + +However, that also allowed any client to submit an arbitrary UID, and +that could be used to bypass "can only ask about / affect the same UID" +checks in CheckAuthorization / RegisterAuthenticationAgent / +UnregisterAuthenticationAgent. This allowed an attacker: + +- With CheckAuthorization, to cause the registered authentication + agent in victim's session to pop up a dialog, or to determine whether + the victim currently has a temporary authorization to perform an + operation. + + (In principle, the attacker can also determine whether JavaScript + rules allow the victim process to perform an operation; however, + usually rules base their decisions on information determined from + the supplied UID, so the attacker usually won't learn anything new.) + +- With RegisterAuthenticationAgent, to prevent the victim's + authentication agent to work (for a specific victim process), + or to learn about which operations requiring authorization + the victim is attempting. + +To fix this, expose internal _polkit_unix_process_get_owner() / +obsolete polkit_unix_process_get_owner() as a private +polkit_unix_process_get_racy_uid__() (being more explicit about the +dangers on relying on it), and use it in +polkit_backend_session_monitor_get_user_for_subject() to return +a boolean indicating whether the subject UID may be caller-chosen. + +Then, in the permission checks that require the subject to be +equal to the caller, fail on caller-chosen UIDs (and continue +through the pre-existing code paths which allow root, or root-designated +server processes, to ask about arbitrary subjects.) + +Signed-off-by: Miloslav Trmač <mitr@redhat.com> +Origin: upstream, 0.115, commit:bc7ffad53643a9c80231fc41f5582d6a8931c32c + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitprivate.h | 2 + + src/polkit/polkitunixprocess.c | 60 +++++++++++++++---- + .../polkitbackendinteractiveauthority.c | 39 +++++++----- + .../polkitbackendsessionmonitor-systemd.c | 38 ++++++++++-- + .../polkitbackendsessionmonitor.c | 40 +++++++++++-- + .../polkitbackendsessionmonitor.h | 1 + + 6 files changed, 147 insertions(+), 33 deletions(-) + +diff --git a/src/polkit/polkitprivate.h b/src/polkit/polkitprivate.h +index 579cc2535014..d6cd45d46aa5 100644 +--- a/src/polkit/polkitprivate.h ++++ b/src/polkit/polkitprivate.h +@@ -34,6 +34,8 @@ GVariant *polkit_action_description_to_gvariant (PolkitActionDescription *action + GVariant *polkit_subject_to_gvariant (PolkitSubject *subject); + GVariant *polkit_identity_to_gvariant (PolkitIdentity *identity); + ++gint polkit_unix_process_get_racy_uid__ (PolkitUnixProcess *process, GError **error); ++ + PolkitSubject *polkit_subject_new_for_gvariant (GVariant *variant, GError **error); + PolkitIdentity *polkit_identity_new_for_gvariant (GVariant *variant, GError **error); + +diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c +index 913be3ac6a0a..464f034c0a21 100644 +--- a/src/polkit/polkitunixprocess.c ++++ b/src/polkit/polkitunixprocess.c +@@ -49,6 +49,14 @@ + * To uniquely identify processes, both the process id and the start + * time of the process (a monotonic increasing value representing the + * time since the kernel was started) is used. ++ * ++ * NOTE: This object stores, and provides access to, the real UID of the ++ * process. That value can change over time (with set*uid*(2) and exec*(2)). ++ * Checks whether an operation is allowed need to take care to use the UID ++ * value as of the time when the operation was made (or, following the open() ++ * privilege check model, when the connection making the operation possible ++ * was initiated). That is usually done by initializing this with ++ * polkit_unix_process_new_for_owner() with trusted data. + */ + + /** +@@ -83,9 +91,6 @@ static void subject_iface_init (PolkitSubjectIface *subject_iface); + static guint64 get_start_time_for_pid (gint pid, + GError **error); + +-static gint _polkit_unix_process_get_owner (PolkitUnixProcess *process, +- GError **error); +- + #ifdef HAVE_FREEBSD + static gboolean get_kinfo_proc (gint pid, struct kinfo_proc *p); + #endif +@@ -170,7 +175,7 @@ polkit_unix_process_constructed (GObject *object) + { + GError *error; + error = NULL; +- process->uid = _polkit_unix_process_get_owner (process, &error); ++ process->uid = polkit_unix_process_get_racy_uid__ (process, &error); + if (error != NULL) + { + process->uid = -1; +@@ -259,6 +264,12 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass) + * Gets the user id for @process. Note that this is the real user-id, + * not the effective user-id. + * ++ * NOTE: The UID may change over time, so the returned value may not match the ++ * current state of the underlying process; or the UID may have been set by ++ * polkit_unix_process_new_for_owner() or polkit_unix_process_set_uid(), ++ * in which case it may not correspond to the actual UID of the referenced ++ * process at all (at any point in time). ++ * + * Returns: The user id for @process or -1 if unknown. + */ + gint +@@ -655,18 +666,26 @@ out: + return start_time; + } + +-static gint +-_polkit_unix_process_get_owner (PolkitUnixProcess *process, +- GError **error) ++/* ++ * Private: Return the "current" UID. Note that this is inherently racy, ++ * and the value may already be obsolete by the time this function returns; ++ * this function only guarantees that the UID was valid at some point during ++ * its execution. ++ */ ++gint ++polkit_unix_process_get_racy_uid__ (PolkitUnixProcess *process, ++ GError **error) + { + gint result; + gchar *contents; + gchar **lines; ++ guint64 start_time; + #ifdef HAVE_FREEBSD + struct kinfo_proc p; + #else + gchar filename[64]; + guint n; ++ GError *local_error; + #endif + + g_return_val_if_fail (POLKIT_IS_UNIX_PROCESS (process), 0); +@@ -689,6 +708,7 @@ _polkit_unix_process_get_owner (PolkitUnixProcess *process, + } + + result = p.ki_uid; ++ start_time = (guint64) p.ki_start.tv_sec; + #else + + /* see 'man proc' for layout of the status file +@@ -722,17 +742,37 @@ _polkit_unix_process_get_owner (PolkitUnixProcess *process, + else + { + result = real_uid; +- goto out; ++ goto found; + } + } +- + g_set_error (error, + POLKIT_ERROR, + POLKIT_ERROR_FAILED, + "Didn't find any line starting with `Uid:' in file %s", + filename); ++ goto out; ++ ++found: ++ /* The UID and start time are, sadly, not available in a single file. So, ++ * read the UID first, and then the start time; if the start time is the same ++ * before and after reading the UID, it couldn't have changed. ++ */ ++ local_error = NULL; ++ start_time = get_start_time_for_pid (process->pid, &local_error); ++ if (local_error != NULL) ++ { ++ g_propagate_error (error, local_error); ++ goto out; ++ } + #endif + ++ if (process->start_time != start_time) ++ { ++ g_set_error (error, POLKIT_ERROR, POLKIT_ERROR_FAILED, ++ "process with PID %d has been replaced", process->pid); ++ goto out; ++ } ++ + out: + g_strfreev (lines); + g_free (contents); +@@ -744,5 +784,5 @@ gint + polkit_unix_process_get_owner (PolkitUnixProcess *process, + GError **error) + { +- return _polkit_unix_process_get_owner (process, error); ++ return polkit_unix_process_get_racy_uid__ (process, error); + } +diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c +index 73d0a0e29e24..97a8d8009886 100644 +--- a/src/polkitbackend/polkitbackendinteractiveauthority.c ++++ b/src/polkitbackend/polkitbackendinteractiveauthority.c +@@ -563,7 +563,7 @@ log_result (PolkitBackendInteractiveAuthority *authority, + if (polkit_authorization_result_get_is_authorized (result)) + log_result_str = "ALLOWING"; + +- user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL); ++ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL, NULL); + + subject_str = polkit_subject_to_string (subject); + +@@ -837,6 +837,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + gchar *subject_str; + PolkitIdentity *user_of_caller; + PolkitIdentity *user_of_subject; ++ gboolean user_of_subject_matches; + gchar *user_of_caller_str; + gchar *user_of_subject_str; + PolkitAuthorizationResult *result; +@@ -882,7 +883,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + action_id); + + user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, +- caller, ++ caller, NULL, + &error); + if (error != NULL) + { +@@ -897,7 +898,7 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + g_debug (" user of caller is %s", user_of_caller_str); + + user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, +- subject, ++ subject, &user_of_subject_matches, + &error); + if (error != NULL) + { +@@ -927,7 +928,10 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + * We only allow this if, and only if, + * + * - processes may check for another process owned by the *same* user but not +- * if details are passed (otherwise you'd be able to spoof the dialog) ++ * if details are passed (otherwise you'd be able to spoof the dialog); ++ * the caller supplies the user_of_subject value, so we additionally ++ * require it to match at least at one point in time (via ++ * user_of_subject_matches). + * + * - processes running as uid 0 may check anything and pass any details + * +@@ -935,7 +939,9 @@ polkit_backend_interactive_authority_check_authorization (PolkitBackendAuthority + * then any uid referenced by that annotation is also allowed to check + * to check anything and pass any details + */ +- if (!polkit_identity_equal (user_of_caller, user_of_subject) || has_details) ++ if (!user_of_subject_matches ++ || !polkit_identity_equal (user_of_caller, user_of_subject) ++ || has_details) + { + if (!may_identity_check_authorization (interactive_authority, action_id, user_of_caller)) + { +@@ -1102,9 +1108,10 @@ check_authorization_sync (PolkitBackendAuthority *authority, + goto out; + } + +- /* every subject has a user */ ++ /* every subject has a user; this is supplied by the client, so we rely ++ * on the caller to validate its acceptability. */ + user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, +- subject, ++ subject, NULL, + error); + if (user_of_subject == NULL) + goto out; +@@ -2319,6 +2326,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken + PolkitSubject *session_for_caller; + PolkitIdentity *user_of_caller; + PolkitIdentity *user_of_subject; ++ gboolean user_of_subject_matches; + AuthenticationAgent *agent; + gboolean ret; + gchar *caller_cmdline; +@@ -2371,7 +2379,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken + goto out; + } + +- user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL); ++ user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL, NULL); + if (user_of_caller == NULL) + { + g_set_error (error, +@@ -2380,7 +2388,7 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken + "Cannot determine user of caller"); + goto out; + } +- user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL); ++ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, &user_of_subject_matches, NULL); + if (user_of_subject == NULL) + { + g_set_error (error, +@@ -2389,7 +2397,8 @@ polkit_backend_interactive_authority_register_authentication_agent (PolkitBacken + "Cannot determine user of subject"); + goto out; + } +- if (!polkit_identity_equal (user_of_caller, user_of_subject)) ++ if (!user_of_subject_matches ++ || !polkit_identity_equal (user_of_caller, user_of_subject)) + { + if (POLKIT_IS_UNIX_USER (user_of_caller) && polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_caller)) == 0) + { +@@ -2482,6 +2491,7 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack + PolkitSubject *session_for_caller; + PolkitIdentity *user_of_caller; + PolkitIdentity *user_of_subject; ++ gboolean user_of_subject_matches; + AuthenticationAgent *agent; + gboolean ret; + gchar *scope_str; +@@ -2530,7 +2540,7 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack + goto out; + } + +- user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL); ++ user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, caller, NULL, NULL); + if (user_of_caller == NULL) + { + g_set_error (error, +@@ -2539,7 +2549,7 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack + "Cannot determine user of caller"); + goto out; + } +- user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, NULL); ++ user_of_subject = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, subject, &user_of_subject_matches, NULL); + if (user_of_subject == NULL) + { + g_set_error (error, +@@ -2548,7 +2558,8 @@ polkit_backend_interactive_authority_unregister_authentication_agent (PolkitBack + "Cannot determine user of subject"); + goto out; + } +- if (!polkit_identity_equal (user_of_caller, user_of_subject)) ++ if (!user_of_subject_matches ++ || !polkit_identity_equal (user_of_caller, user_of_subject)) + { + if (POLKIT_IS_UNIX_USER (user_of_caller) && polkit_unix_user_get_uid (POLKIT_UNIX_USER (user_of_caller)) == 0) + { +@@ -2658,7 +2669,7 @@ polkit_backend_interactive_authority_authentication_agent_response (PolkitBacken + identity_str); + + user_of_caller = polkit_backend_session_monitor_get_user_for_subject (priv->session_monitor, +- caller, ++ caller, NULL, + error); + if (user_of_caller == NULL) + goto out; +diff --git a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +index 6bd517abb169..773256e37ae0 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor-systemd.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor-systemd.c +@@ -29,6 +29,7 @@ + #include <stdlib.h> + + #include <polkit/polkit.h> ++#include <polkit/polkitprivate.h> + #include "polkitbackendsessionmonitor.h" + + /* <internal> +@@ -246,26 +247,40 @@ polkit_backend_session_monitor_get_sessions (PolkitBackendSessionMonitor *monito + * polkit_backend_session_monitor_get_user: + * @monitor: A #PolkitBackendSessionMonitor. + * @subject: A #PolkitSubject. ++ * @result_matches: If not %NULL, set to indicate whether the return value matches current (RACY) state. + * @error: Return location for error. + * + * Gets the user corresponding to @subject or %NULL if no user exists. + * ++ * NOTE: For a #PolkitUnixProcess, the UID is read from @subject (which may ++ * come from e.g. a D-Bus client), so it may not correspond to the actual UID ++ * of the referenced process (at any point in time). This is indicated by ++ * setting @result_matches to %FALSE; the caller may reject such subjects or ++ * require additional privileges. @result_matches == %TRUE only indicates that ++ * the UID matched the underlying process at ONE point in time, it may not match ++ * later. ++ * + * Returns: %NULL if @error is set otherwise a #PolkitUnixUser that should be freed with g_object_unref(). + */ + PolkitIdentity * + polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor, + PolkitSubject *subject, ++ gboolean *result_matches, + GError **error) + { + PolkitIdentity *ret; +- guint32 uid; ++ gboolean matches; + + ret = NULL; ++ matches = FALSE; + + if (POLKIT_IS_UNIX_PROCESS (subject)) + { +- uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); +- if ((gint) uid == -1) ++ gint subject_uid, current_uid; ++ GError *local_error; ++ ++ subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); ++ if (subject_uid == -1) + { + g_set_error (error, + POLKIT_ERROR, +@@ -273,14 +288,24 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + "Unix process subject does not have uid set"); + goto out; + } +- ret = polkit_unix_user_new (uid); ++ local_error = NULL; ++ current_uid = polkit_unix_process_get_racy_uid__ (POLKIT_UNIX_PROCESS (subject), &local_error); ++ if (local_error != NULL) ++ { ++ g_propagate_error (error, local_error); ++ goto out; ++ } ++ ret = polkit_unix_user_new (subject_uid); ++ matches = (subject_uid == current_uid); + } + else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + { + ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); ++ matches = TRUE; + } + else if (POLKIT_IS_UNIX_SESSION (subject)) + { ++ uid_t uid; + + if (sd_session_get_uid (polkit_unix_session_get_session_id (POLKIT_UNIX_SESSION (subject)), &uid) < 0) + { +@@ -292,9 +317,14 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + } + + ret = polkit_unix_user_new (uid); ++ matches = TRUE; + } + + out: ++ if (result_matches != NULL) ++ { ++ *result_matches = matches; ++ } + return ret; + } + +diff --git a/src/polkitbackend/polkitbackendsessionmonitor.c b/src/polkitbackend/polkitbackendsessionmonitor.c +index e1a9ab3a32cc..ed3075595dfb 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor.c ++++ b/src/polkitbackend/polkitbackendsessionmonitor.c +@@ -27,6 +27,7 @@ + #include <glib/gstdio.h> + + #include <polkit/polkit.h> ++#include <polkit/polkitprivate.h> + #include "polkitbackendsessionmonitor.h" + + #define CKDB_PATH "/var/run/ConsoleKit/database" +@@ -273,28 +274,40 @@ polkit_backend_session_monitor_get_sessions (PolkitBackendSessionMonitor *monito + * polkit_backend_session_monitor_get_user: + * @monitor: A #PolkitBackendSessionMonitor. + * @subject: A #PolkitSubject. ++ * @result_matches: If not %NULL, set to indicate whether the return value matches current (RACY) state. + * @error: Return location for error. + * + * Gets the user corresponding to @subject or %NULL if no user exists. + * ++ * NOTE: For a #PolkitUnixProcess, the UID is read from @subject (which may ++ * come from e.g. a D-Bus client), so it may not correspond to the actual UID ++ * of the referenced process (at any point in time). This is indicated by ++ * setting @result_matches to %FALSE; the caller may reject such subjects or ++ * require additional privileges. @result_matches == %TRUE only indicates that ++ * the UID matched the underlying process at ONE point in time, it may not match ++ * later. ++ * + * Returns: %NULL if @error is set otherwise a #PolkitUnixUser that should be freed with g_object_unref(). + */ + PolkitIdentity * + polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor, + PolkitSubject *subject, ++ gboolean *result_matches, + GError **error) + { + PolkitIdentity *ret; ++ gboolean matches; + GError *local_error; +- gchar *group; +- guint32 uid; + + ret = NULL; ++ matches = FALSE; + + if (POLKIT_IS_UNIX_PROCESS (subject)) + { +- uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); +- if ((gint) uid == -1) ++ gint subject_uid, current_uid; ++ ++ subject_uid = polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)); ++ if (subject_uid == -1) + { + g_set_error (error, + POLKIT_ERROR, +@@ -302,14 +315,26 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + "Unix process subject does not have uid set"); + goto out; + } +- ret = polkit_unix_user_new (uid); ++ local_error = NULL; ++ current_uid = polkit_unix_process_get_racy_uid__ (POLKIT_UNIX_PROCESS (subject), &local_error); ++ if (local_error != NULL) ++ { ++ g_propagate_error (error, local_error); ++ goto out; ++ } ++ ret = polkit_unix_user_new (subject_uid); ++ matches = (subject_uid == current_uid); + } + else if (POLKIT_IS_SYSTEM_BUS_NAME (subject)) + { + ret = (PolkitIdentity*)polkit_system_bus_name_get_user_sync (POLKIT_SYSTEM_BUS_NAME (subject), NULL, error); ++ matches = TRUE; + } + else if (POLKIT_IS_UNIX_SESSION (subject)) + { ++ gint uid; ++ gchar *group; ++ + if (!ensure_database (monitor, error)) + { + g_prefix_error (error, "Error getting user for session: Error ensuring CK database at " CKDB_PATH ": "); +@@ -328,9 +353,14 @@ polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor + g_free (group); + + ret = polkit_unix_user_new (uid); ++ matches = TRUE; + } + + out: ++ if (result_matches != NULL) ++ { ++ *result_matches = matches; ++ } + return ret; + } + +diff --git a/src/polkitbackend/polkitbackendsessionmonitor.h b/src/polkitbackend/polkitbackendsessionmonitor.h +index 8f8a2caefd6b..3972326bf9f3 100644 +--- a/src/polkitbackend/polkitbackendsessionmonitor.h ++++ b/src/polkitbackend/polkitbackendsessionmonitor.h +@@ -47,6 +47,7 @@ GList *polkit_backend_session_monitor_get_sessions (Polkit + + PolkitIdentity *polkit_backend_session_monitor_get_user_for_subject (PolkitBackendSessionMonitor *monitor, + PolkitSubject *subject, ++ gboolean *result_matches, + GError **error); + + PolkitSubject *polkit_backend_session_monitor_get_session_for_subject (PolkitBackendSessionMonitor *monitor, diff --git a/patches/polkit-0.105/0038-0.116-Allow-negative-uids-gids-in-PolkitUnixUser-and.patch b/patches/polkit-0.105/0038-0.116-Allow-negative-uids-gids-in-PolkitUnixUser-and.patch new file mode 100644 index 000000000..5ac4f582e --- /dev/null +++ b/patches/polkit-0.105/0038-0.116-Allow-negative-uids-gids-in-PolkitUnixUser-and.patch @@ -0,0 +1,191 @@ +From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl> +Date: Mon, 3 Dec 2018 10:28:58 +0100 +Subject: [PATCH] 0.116: Allow negative uids/gids in PolkitUnixUser and Group + objects + +(uid_t) -1 is still used as placeholder to mean "unset". This is OK, since +there should be no users with such number, see +https://systemd.io/UIDS-GIDS#special-linux-uids. + +(uid_t) -1 is used as the default value in class initialization. + +When a user or group above INT32_MAX is created, the numeric uid or +gid wraps around to negative when the value is assigned to gint, and +polkit gets confused. Let's accept such gids, except for -1. + +A nicer fix would be to change the underlying type to e.g. uint32 to +not have negative values. But this cannot be done without breaking the +API, so likely new functions will have to be added (a +polkit_unix_user_new variant that takes a unsigned, and the same for +_group_new, _set_uid, _get_uid, _set_gid, _get_gid, etc.). This will +require a bigger patch. + +Fixes https://gitlab.freedesktop.org/polkit/polkit/issues/74. + +(cherry picked from commit 2cb40c4d5feeaa09325522bd7d97910f1b59e379) + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitunixgroup.c | 15 +++++++++++---- + src/polkit/polkitunixprocess.c | 12 ++++++++---- + src/polkit/polkitunixuser.c | 13 ++++++++++--- + 3 files changed, 29 insertions(+), 11 deletions(-) + +diff --git a/src/polkit/polkitunixgroup.c b/src/polkit/polkitunixgroup.c +index c57a1aaacbb1..309f68918895 100644 +--- a/src/polkit/polkitunixgroup.c ++++ b/src/polkit/polkitunixgroup.c +@@ -71,6 +71,7 @@ G_DEFINE_TYPE_WITH_CODE (PolkitUnixGroup, polkit_unix_group, G_TYPE_OBJECT, + static void + polkit_unix_group_init (PolkitUnixGroup *unix_group) + { ++ unix_group->gid = -1; /* (git_t) -1 is not a valid GID under Linux */ + } + + static void +@@ -100,11 +101,14 @@ polkit_unix_group_set_property (GObject *object, + GParamSpec *pspec) + { + PolkitUnixGroup *unix_group = POLKIT_UNIX_GROUP (object); ++ gint val; + + switch (prop_id) + { + case PROP_GID: +- unix_group->gid = g_value_get_int (value); ++ val = g_value_get_int (value); ++ g_return_if_fail (val != -1); ++ unix_group->gid = val; + break; + + default: +@@ -131,9 +135,9 @@ polkit_unix_group_class_init (PolkitUnixGroupClass *klass) + g_param_spec_int ("gid", + "Group ID", + "The UNIX group ID", +- 0, ++ G_MININT, + G_MAXINT, +- 0, ++ -1, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | +@@ -166,9 +170,10 @@ polkit_unix_group_get_gid (PolkitUnixGroup *group) + */ + void + polkit_unix_group_set_gid (PolkitUnixGroup *group, +- gint gid) ++ gint gid) + { + g_return_if_fail (POLKIT_IS_UNIX_GROUP (group)); ++ g_return_if_fail (gid != -1); + group->gid = gid; + } + +@@ -183,6 +188,8 @@ polkit_unix_group_set_gid (PolkitUnixGroup *group, + PolkitIdentity * + polkit_unix_group_new (gint gid) + { ++ g_return_val_if_fail (gid != -1, NULL); ++ + return POLKIT_IDENTITY (g_object_new (POLKIT_TYPE_UNIX_GROUP, + "gid", gid, + NULL)); +diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c +index 464f034c0a21..02a083f70a1c 100644 +--- a/src/polkit/polkitunixprocess.c ++++ b/src/polkit/polkitunixprocess.c +@@ -147,9 +147,14 @@ polkit_unix_process_set_property (GObject *object, + polkit_unix_process_set_pid (unix_process, g_value_get_int (value)); + break; + +- case PROP_UID: +- polkit_unix_process_set_uid (unix_process, g_value_get_int (value)); ++ case PROP_UID: { ++ gint val; ++ ++ val = g_value_get_int (value); ++ g_return_if_fail (val != -1); ++ polkit_unix_process_set_uid (unix_process, val); + break; ++ } + + case PROP_START_TIME: + polkit_unix_process_set_start_time (unix_process, g_value_get_uint64 (value)); +@@ -227,7 +232,7 @@ polkit_unix_process_class_init (PolkitUnixProcessClass *klass) + g_param_spec_int ("uid", + "User ID", + "The UNIX user ID", +- -1, ++ G_MININT, + G_MAXINT, + -1, + G_PARAM_CONSTRUCT | +@@ -291,7 +296,6 @@ polkit_unix_process_set_uid (PolkitUnixProcess *process, + gint uid) + { + g_return_if_fail (POLKIT_IS_UNIX_PROCESS (process)); +- g_return_if_fail (uid >= -1); + process->uid = uid; + } + +diff --git a/src/polkit/polkitunixuser.c b/src/polkit/polkitunixuser.c +index 8bfd3a1fb05d..234a6976c573 100644 +--- a/src/polkit/polkitunixuser.c ++++ b/src/polkit/polkitunixuser.c +@@ -72,6 +72,7 @@ G_DEFINE_TYPE_WITH_CODE (PolkitUnixUser, polkit_unix_user, G_TYPE_OBJECT, + static void + polkit_unix_user_init (PolkitUnixUser *unix_user) + { ++ unix_user->uid = -1; /* (uid_t) -1 is not a valid UID under Linux */ + unix_user->name = NULL; + } + +@@ -112,11 +113,14 @@ polkit_unix_user_set_property (GObject *object, + GParamSpec *pspec) + { + PolkitUnixUser *unix_user = POLKIT_UNIX_USER (object); ++ gint val; + + switch (prop_id) + { + case PROP_UID: +- unix_user->uid = g_value_get_int (value); ++ val = g_value_get_int (value); ++ g_return_if_fail (val != -1); ++ unix_user->uid = val; + break; + + default: +@@ -144,9 +148,9 @@ polkit_unix_user_class_init (PolkitUnixUserClass *klass) + g_param_spec_int ("uid", + "User ID", + "The UNIX user ID", +- 0, ++ G_MININT, + G_MAXINT, +- 0, ++ -1, + G_PARAM_CONSTRUCT | + G_PARAM_READWRITE | + G_PARAM_STATIC_NAME | +@@ -182,6 +186,7 @@ polkit_unix_user_set_uid (PolkitUnixUser *user, + gint uid) + { + g_return_if_fail (POLKIT_IS_UNIX_USER (user)); ++ g_return_if_fail (uid != -1); + user->uid = uid; + } + +@@ -196,6 +201,8 @@ polkit_unix_user_set_uid (PolkitUnixUser *user, + PolkitIdentity * + polkit_unix_user_new (gint uid) + { ++ g_return_val_if_fail (uid != -1, NULL); ++ + return POLKIT_IDENTITY (g_object_new (POLKIT_TYPE_UNIX_USER, + "uid", uid, + NULL)); diff --git a/patches/polkit-0.105/0039-0.116-Allow-uid-of-1-for-a-PolkitUnixProcess.patch b/patches/polkit-0.105/0039-0.116-Allow-uid-of-1-for-a-PolkitUnixProcess.patch new file mode 100644 index 000000000..cdb6c31d9 --- /dev/null +++ b/patches/polkit-0.105/0039-0.116-Allow-uid-of-1-for-a-PolkitUnixProcess.patch @@ -0,0 +1,47 @@ +From: Matthew Leeds <matthew.leeds@endlessm.com> +Date: Tue, 11 Dec 2018 12:04:26 -0800 +Subject: [PATCH] 0.116: Allow uid of -1 for a PolkitUnixProcess + +Commit 2cb40c4d5 changed PolkitUnixUser, PolkitUnixGroup, and +PolkitUnixProcess to allow negative values for their uid/gid properties, +since these are values above INT_MAX which wrap around but are still +valid, with the exception of -1 which is not valid. However, +PolkitUnixProcess allows a uid of -1 to be passed to +polkit_unix_process_new_for_owner() which means polkit is expected to +figure out the uid on its own (this happens in the _constructed +function). So this commit removes the check in +polkit_unix_process_set_property() so that new_for_owner() can be used +as documented without producing a critical error message. + +This does not affect the protection against CVE-2018-19788 which is +based on creating a user with a UID up to but not including 4294967295 +(-1). + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitunixprocess.c | 9 ++------- + 1 file changed, 2 insertions(+), 7 deletions(-) + +diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c +index 02a083f70a1c..4a4256746d6e 100644 +--- a/src/polkit/polkitunixprocess.c ++++ b/src/polkit/polkitunixprocess.c +@@ -147,14 +147,9 @@ polkit_unix_process_set_property (GObject *object, + polkit_unix_process_set_pid (unix_process, g_value_get_int (value)); + break; + +- case PROP_UID: { +- gint val; +- +- val = g_value_get_int (value); +- g_return_if_fail (val != -1); +- polkit_unix_process_set_uid (unix_process, val); ++ case PROP_UID: ++ polkit_unix_process_set_uid (unix_process, g_value_get_int (value)); + break; +- } + + case PROP_START_TIME: + polkit_unix_process_set_start_time (unix_process, g_value_get_uint64 (value)); diff --git a/patches/polkit-0.105/0040-Revert-Default-to-AdminIdentities-unix-group-wheel-f.patch b/patches/polkit-0.105/0040-Revert-Default-to-AdminIdentities-unix-group-wheel-f.patch new file mode 100644 index 000000000..cd41f00be --- /dev/null +++ b/patches/polkit-0.105/0040-Revert-Default-to-AdminIdentities-unix-group-wheel-f.patch @@ -0,0 +1,39 @@ +From: Michael Biebl <biebl@debian.org> +Date: Fri, 9 Dec 2011 00:31:21 +0100 +Subject: [PATCH] Revert "Default to AdminIdentities=unix-group:wheel for local + authority" + +This reverts commit 763faf434b445c20ae9529100d3ef5290976d0c9. + +On Red Hat derivatives, every member of group 'wheel' is necessarily +privileged. On Debian derivatives, there is no wheel group, and gid 0 +(root) is not used in this way. Change the default rule to consider +uid 0 to be privileged, instead. + +On Red Hat derivatives, 50-default.rules is not preserved by upgrades; +on dpkg-based systems, it is a proper conffile and may be edited +(at the sysadmin's own risk), so the comment about not editing it is +misleading. + +[smcv: added longer explanation of why we make this change; +remove unrelated cosmetic change to a man page] + +Forwarded: no, Debian-specific + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkitbackend/50-localauthority.conf | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/polkitbackend/50-localauthority.conf b/src/polkitbackend/50-localauthority.conf +index 5e44bde08869..20e0ba344e83 100644 +--- a/src/polkitbackend/50-localauthority.conf ++++ b/src/polkitbackend/50-localauthority.conf +@@ -7,4 +7,4 @@ + # + + [Configuration] +-AdminIdentities=unix-group:wheel ++AdminIdentities=unix-user:0 diff --git a/patches/polkit-0.105/0041-Build-against-libsystemd.patch b/patches/polkit-0.105/0041-Build-against-libsystemd.patch new file mode 100644 index 000000000..76ef40029 --- /dev/null +++ b/patches/polkit-0.105/0041-Build-against-libsystemd.patch @@ -0,0 +1,36 @@ +From: Michael Biebl <biebl@debian.org> +Date: Wed, 8 Jul 2015 02:08:33 +0200 +Subject: [PATCH] Build against libsystemd + +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=779756 +Forwarded: no, obsoleted by upstream commit 2291767a014f5a04a92ca6f0eb472794f212ca67 in 0.113 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + configure.ac | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/configure.ac b/configure.ac +index 388605d2cb08..f55ddb7fa002 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -160,7 +160,7 @@ AC_ARG_ENABLE([systemd], + [enable_systemd=auto]) + if test "$enable_systemd" != "no"; then + PKG_CHECK_MODULES(SYSTEMD, +- [libsystemd-login], ++ [libsystemd], + have_systemd=yes, + have_systemd=no) + if test "$have_systemd" = "yes"; then +@@ -171,7 +171,7 @@ if test "$enable_systemd" != "no"; then + LIBS=$save_LIBS + else + if test "$enable_systemd" = "yes"; then +- AC_MSG_ERROR([systemd support requested but libsystemd-login1 library not found]) ++ AC_MSG_ERROR([systemd support requested but libsystemd library not found]) + fi + fi + fi diff --git a/patches/polkit-0.105/0042-Move-D-Bus-policy-file-to-usr-share-dbus-1-system.d.patch b/patches/polkit-0.105/0042-Move-D-Bus-policy-file-to-usr-share-dbus-1-system.d.patch new file mode 100644 index 000000000..89ecb9e66 --- /dev/null +++ b/patches/polkit-0.105/0042-Move-D-Bus-policy-file-to-usr-share-dbus-1-system.d.patch @@ -0,0 +1,35 @@ +From: Michael Biebl <biebl@debian.org> +Date: Tue, 27 Nov 2018 18:36:27 +0100 +Subject: [PATCH] Move D-Bus policy file to /usr/share/dbus-1/system.d/ + +To better support stateless systems with an empty /etc, the old location +in /etc/dbus-1/system.d/ should only be used for local admin changes. +Package provided D-Bus policy files are supposed to be installed in +/usr/share/dbus-1/system.d/. + +This is supported since dbus 1.9.18. + +https://lists.freedesktop.org/archives/dbus/2015-July/016746.html + +https://gitlab.freedesktop.org/polkit/polkit/merge_requests/11 + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + data/Makefile.am | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/data/Makefile.am b/data/Makefile.am +index f0beeba42cd2..ec41433b48d9 100644 +--- a/data/Makefile.am ++++ b/data/Makefile.am +@@ -9,7 +9,7 @@ service_DATA = $(service_in_files:.service.in=.service) + $(service_DATA): $(service_in_files) Makefile + @sed -e "s|\@libexecdir\@|$(libexecdir)|" $< > $@ + +-dbusconfdir = $(sysconfdir)/dbus-1/system.d ++dbusconfdir = $(datadir)/dbus-1/system.d + dbusconf_DATA = org.freedesktop.PolicyKit1.conf + + if POLKIT_AUTHFW_PAM diff --git a/patches/polkit-0.105/0043-0.116-backend-Compare-PolkitUnixProcess-uids-for-tem.patch b/patches/polkit-0.105/0043-0.116-backend-Compare-PolkitUnixProcess-uids-for-tem.patch new file mode 100644 index 000000000..93af341dc --- /dev/null +++ b/patches/polkit-0.105/0043-0.116-backend-Compare-PolkitUnixProcess-uids-for-tem.patch @@ -0,0 +1,186 @@ +From: Colin Walters <walters@verbum.org> +Date: Fri, 4 Jan 2019 14:24:48 -0500 +Subject: [PATCH] 0.116: backend: Compare PolkitUnixProcess uids for temporary + authorizations + +It turns out that the combination of `(pid, start time)` is not +enough to be unique. For temporary authorizations, we can avoid +separate users racing on pid reuse by simply comparing the uid. + +https://bugs.chromium.org/p/project-zero/issues/detail?id=1692 + +And the above original email report is included in full in a new comment. + +Reported-by: Jann Horn <jannh@google.com> + +Closes: https://gitlab.freedesktop.org/polkit/polkit/issues/75 +(cherry picked from commit 6cc6aafee135ba44ea748250d7d29b562ca190e3) + +Imported from policykit-1_0.105-25.debian.tar.xz + +Signed-off-by: Michael Olbrich <m.olbrich@pengutronix.de> +--- + src/polkit/polkitsubject.c | 2 + + src/polkit/polkitunixprocess.c | 71 ++++++++++++++++++- + .../polkitbackendinteractiveauthority.c | 39 +++++++++- + 3 files changed, 110 insertions(+), 2 deletions(-) + +diff --git a/src/polkit/polkitsubject.c b/src/polkit/polkitsubject.c +index 78ec745a4df2..fadcfe9b624e 100644 +--- a/src/polkit/polkitsubject.c ++++ b/src/polkit/polkitsubject.c +@@ -99,6 +99,8 @@ polkit_subject_hash (PolkitSubject *subject) + * @b: A #PolkitSubject. + * + * Checks if @a and @b are equal, ie. represent the same subject. ++ * However, avoid calling polkit_subject_equal() to compare two processes; ++ * for more information see the `PolkitUnixProcess` documentation. + * + * This function can be used in e.g. g_hash_table_new(). + * +diff --git a/src/polkit/polkitunixprocess.c b/src/polkit/polkitunixprocess.c +index 4a4256746d6e..0f33598a7401 100644 +--- a/src/polkit/polkitunixprocess.c ++++ b/src/polkit/polkitunixprocess.c +@@ -44,7 +44,10 @@ + * @title: PolkitUnixProcess + * @short_description: Unix processs + * +- * An object for representing a UNIX process. ++ * An object for representing a UNIX process. NOTE: This object as ++ * designed is now known broken; a mechanism to exploit a delay in ++ * start time in the Linux kernel was identified. Avoid ++ * calling polkit_subject_equal() to compare two processes. + * + * To uniquely identify processes, both the process id and the start + * time of the process (a monotonic increasing value representing the +@@ -59,6 +62,72 @@ + * polkit_unix_process_new_for_owner() with trusted data. + */ + ++/* See https://gitlab.freedesktop.org/polkit/polkit/issues/75 ++ ++ But quoting the original email in full here to ensure it's preserved: ++ ++ From: Jann Horn <jannh@google.com> ++ Subject: 0.116: [SECURITY] polkit: temporary auth hijacking via PID reuse and non-atomic fork ++ Date: Wednesday, October 10, 2018 5:34 PM ++ ++When a (non-root) user attempts to e.g. control systemd units in the system ++instance from an active session over DBus, the access is gated by a polkit ++policy that requires "auth_admin_keep" auth. This results in an auth prompt ++being shown to the user, asking the user to confirm the action by entering the ++password of an administrator account. ++ ++After the action has been confirmed, the auth decision for "auth_admin_keep" is ++cached for up to five minutes. Subject to some restrictions, similar actions can ++then be performed in this timespan without requiring re-auth: ++ ++ - The PID of the DBus client requesting the new action must match the PID of ++ the DBus client requesting the old action (based on SO_PEERCRED information ++ forwarded by the DBus daemon). ++ - The "start time" of the client's PID (as seen in /proc/$pid/stat, field 22) ++ must not have changed. The granularity of this timestamp is in the ++ millisecond range. ++ - polkit polls every two seconds whether a process with the expected start time ++ still exists. If not, the temporary auth entry is purged. ++ ++Without the start time check, this would obviously be buggy because an attacker ++could simply wait for the legitimate client to disappear, then create a new ++client with the same PID. ++ ++Unfortunately, the start time check is bypassable because fork() is not atomic. ++Looking at the source code of copy_process() in the kernel: ++ ++ p->start_time = ktime_get_ns(); ++ p->real_start_time = ktime_get_boot_ns(); ++ [...] ++ retval = copy_thread_tls(clone_flags, stack_start, stack_size, p, tls); ++ if (retval) ++ goto bad_fork_cleanup_io; ++ ++ if (pid != &init_struct_pid) { ++ pid = alloc_pid(p->nsproxy->pid_ns_for_children); ++ if (IS_ERR(pid)) { ++ retval = PTR_ERR(pid); ++ goto bad_fork_cleanup_thread; ++ } ++ } ++ ++The ktime_get_boot_ns() call is where the "start time" of the process is ++recorded. The alloc_pid() call is where a free PID is allocated. In between ++these, some time passes; and because the copy_thread_tls() call between them can ++access userspace memory when sys_clone() is invoked through the 32-bit syscall ++entry point, an attacker can even stall the kernel arbitrarily long at this ++point (by supplying a pointer into userspace memory that is associated with a ++userfaultfd or is backed by a custom FUSE filesystem). ++ ++This means that an attacker can immediately call sys_clone() when the victim ++process is created, often resulting in a process that has the exact same start ++time reported in procfs; and then the attacker can delay the alloc_pid() call ++until after the victim process has died and the PID assignment has cycled ++around. This results in an attacker process that polkit can't distinguish from ++the victim process. ++*/ ++ ++ + /** + * PolkitUnixProcess: + * +diff --git a/src/polkitbackend/polkitbackendinteractiveauthority.c b/src/polkitbackend/polkitbackendinteractiveauthority.c +index 97a8d8009886..1e17dfd5b695 100644 +--- a/src/polkitbackend/polkitbackendinteractiveauthority.c ++++ b/src/polkitbackend/polkitbackendinteractiveauthority.c +@@ -2870,6 +2870,43 @@ temporary_authorization_store_free (TemporaryAuthorizationStore *store) + g_free (store); + } + ++/* See the comment at the top of polkitunixprocess.c */ ++static gboolean ++subject_equal_for_authz (PolkitSubject *a, ++ PolkitSubject *b) ++{ ++ if (!polkit_subject_equal (a, b)) ++ return FALSE; ++ ++ /* Now special case unix processes, as we want to protect against ++ * pid reuse by including the UID. ++ */ ++ if (POLKIT_IS_UNIX_PROCESS (a) && POLKIT_IS_UNIX_PROCESS (b)) { ++ PolkitUnixProcess *ap = (PolkitUnixProcess*)a; ++ int uid_a = polkit_unix_process_get_uid ((PolkitUnixProcess*)a); ++ PolkitUnixProcess *bp = (PolkitUnixProcess*)b; ++ int uid_b = polkit_unix_process_get_uid ((PolkitUnixProcess*)b); ++ ++ if (uid_a != -1 && uid_b != -1) ++ { ++ if (uid_a == uid_b) ++ { ++ return TRUE; ++ } ++ else ++ { ++ g_printerr ("denying slowfork; pid %d uid %d != %d!\n", ++ polkit_unix_process_get_pid (ap), ++ uid_a, uid_b); ++ return FALSE; ++ } ++ } ++ /* Fall through; one of the uids is unset so we can't reliably compare */ ++ } ++ ++ return TRUE; ++} ++ + static gboolean + temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *store, + PolkitSubject *subject, +@@ -2912,7 +2949,7 @@ temporary_authorization_store_has_authorization (TemporaryAuthorizationStore *st + TemporaryAuthorization *authorization = l->data; + + if (strcmp (action_id, authorization->action_id) == 0 && +- polkit_subject_equal (subject_to_use, authorization->subject)) ++ subject_equal_for_authz (subject_to_use, authorization->subject)) + { + ret = TRUE; + if (out_tmp_authz_id != NULL) diff --git a/patches/polkit-0.105/0002-automake-add-missing-conditional-HAVE_INTROSPECTION.patch b/patches/polkit-0.105/0100-automake-add-missing-conditional-HAVE_INTROSPECTION.patch index 88afa7a00..88afa7a00 100644 --- a/patches/polkit-0.105/0002-automake-add-missing-conditional-HAVE_INTROSPECTION.patch +++ b/patches/polkit-0.105/0100-automake-add-missing-conditional-HAVE_INTROSPECTION.patch diff --git a/patches/polkit-0.105/series b/patches/polkit-0.105/series index 28afbfe9d..19b896b01 100644 --- a/patches/polkit-0.105/series +++ b/patches/polkit-0.105/series @@ -1,5 +1,49 @@ # generated by git-ptx-patches #tag:base --start-number 1 -0001-check-for-libsystemd-instead-of-libsystemd-login.patch -0002-automake-add-missing-conditional-HAVE_INTROSPECTION.patch -# 4b827c19ffc3dd77b57d89f9c2c9ab8d - git-ptx-patches magic +#tag:debian --start-number 1 +0001-0.106-agenthelper-pam-Fix-newline-trimming-code.patch +0002-0.108-build-Fix-.gir-generation-for-parallel-make.patch +0003-0.110-Set-XAUTHORITY-environment-variable-if-is-unse.patch +0004-0.110-Fix-build-on-GNU-Hurd.patch +0005-0.111-pkexec-Set-process-environment-from-pam_getenv.patch +0006-0.111-Fix-a-memory-leak.patch +0007-0.112-Use-GOnce-for-interface-type-registration.patch +0008-0.112-polkitunixprocess-Deprecate-racy-APIs.patch +0009-0.112-pkcheck-Support-process-pid-start-time-uid-syn.patch +0010-0.113-Port-internals-non-deprecated-PolkitProcess-AP.patch +0011-0.113-pkexec-Work-around-systemd-injecting-broken-XD.patch +0012-0.113-PolkitAgentSession-fix-race-between-child-and-.patch +0013-0.113-polkitd-Fix-problem-with-removing-non-existent.patch +0014-0.113-PolkitSystemBusName-Add-public-API-to-retrieve.patch +0015-0.113-Fixed-compilation-problem-in-the-backend.patch +0016-0.113-Don-t-discard-error-data-returned-by-polkit_sy.patch +0017-0.113-sessionmonitor-systemd-Deduplicate-code-paths.patch +0018-0.113-sessionmonitor-systemd-prepare-for-D-Bus-user-.patch +0019-0.113-Refuse-duplicate-user-arguments-to-pkexec.patch +0020-0.113-authority-Fix-memory-leak-in-EnumerateActions-.patch +0021-0.113-CVE-2015-3218-backend-Handle-invalid-object-pa.patch +0022-0.113-sessionmonitor-systemd-Use-sd_uid_get_state-to.patch +0023-0.113-Fix-a-possible-NULL-dereference.patch +0024-0.113-Remove-a-redundant-assignment.patch +0025-0.113-Fix-duplicate-GError-use-when-uid-is-missing.patch +0026-0.113-Fix-a-crash-when-two-authentication-requests-a.patch +0027-0.113-CVE-2015-4625-Use-unpredictable-cookie-values-.patch +0028-0.113-CVE-2015-4625-Bind-use-of-cookies-to-specific-.patch +0029-0.113-docs-Update-for-changes-to-uid-binding-Authent.patch +0030-0.113-Fix-a-per-authorization-memory-leak.patch +0031-0.113-Fix-a-memory-leak-when-registering-an-authenti.patch +0032-0.113-CVE-2015-3255-Fix-GHashTable-usage.patch +0033-0.113-Fix-use-after-free-in-polkitagentsession.c.patch +0034-0.114-Fix-multi-line-pam-text-info.patch +0035-0.114-Refactor-send_to_helper-usage.patch +0036-0.114-Support-polkit-session-agent-running-outside-u.patch +0037-0.115-Fix-CVE-2018-1116-Trusting-client-supplied-UID.patch +0038-0.116-Allow-negative-uids-gids-in-PolkitUnixUser-and.patch +0039-0.116-Allow-uid-of-1-for-a-PolkitUnixProcess.patch +0040-Revert-Default-to-AdminIdentities-unix-group-wheel-f.patch +0041-Build-against-libsystemd.patch +0042-Move-D-Bus-policy-file-to-usr-share-dbus-1-system.d.patch +0043-0.116-backend-Compare-PolkitUnixProcess-uids-for-tem.patch +#tag:ptxdist --start-number 100 +0100-automake-add-missing-conditional-HAVE_INTROSPECTION.patch +# 37496f3f986e77c3040a96c75cf68f42 - git-ptx-patches magic |