summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMart Raudsepp <leio@gentoo.org>2020-01-01 17:40:23 +0200
committerMart Raudsepp <leio@gentoo.org>2020-01-01 17:40:41 +0200
commit1ed2ea2d465969fba6a72c270d712287d2e3e116 (patch)
treeb56ce1d58d5a0ea948b15f07a3b7cb1e9c3d1eec /dev-libs/glib/files/2.60.7-gdbus-fixes.patch
parentnet-analyzer/tcpstat: Version 1.5_p8 (diff)
downloadgentoo-1ed2ea2d465969fba6a72c270d712287d2e3e116.tar.gz
gentoo-1ed2ea2d465969fba6a72c270d712287d2e3e116.tar.bz2
gentoo-1ed2ea2d465969fba6a72c270d712287d2e3e116.zip
dev-libs/glib: backport GDBus fixes necessary for ibus security fixes
Closes: https://bugs.gentoo.org/700538 Package-Manager: Portage-2.3.79, Repoman-2.3.12 Signed-off-by: Mart Raudsepp <leio@gentoo.org>
Diffstat (limited to 'dev-libs/glib/files/2.60.7-gdbus-fixes.patch')
-rw-r--r--dev-libs/glib/files/2.60.7-gdbus-fixes.patch301
1 files changed, 301 insertions, 0 deletions
diff --git a/dev-libs/glib/files/2.60.7-gdbus-fixes.patch b/dev-libs/glib/files/2.60.7-gdbus-fixes.patch
new file mode 100644
index 000000000000..e2a066beec73
--- /dev/null
+++ b/dev-libs/glib/files/2.60.7-gdbus-fixes.patch
@@ -0,0 +1,301 @@
+From 1cfab12a28d97716ad581c30fbbf3e94e4d7f303 Mon Sep 17 00:00:00 2001
+From: Simon McVittie <smcv@collabora.com>
+Date: Mon, 14 Oct 2019 08:22:24 +0100
+Subject: [PATCH 1/3] gcredentialsprivate: Document the various private macros
+
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+---
+ gio/gcredentialsprivate.h | 59 +++++++++++++++++++++++++++++++++++++++
+ 1 file changed, 59 insertions(+)
+
+diff --git a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h
+index 4d1c420a8..06f0aed19 100644
+--- a/gio/gcredentialsprivate.h
++++ b/gio/gcredentialsprivate.h
+@@ -22,6 +22,65 @@
+ #include "gio/gcredentials.h"
+ #include "gio/gnetworking.h"
+
++/*
++ * G_CREDENTIALS_SUPPORTED:
++ *
++ * Defined to 1 if GCredentials works.
++ */
++#undef G_CREDENTIALS_SUPPORTED
++
++/*
++ * G_CREDENTIALS_USE_LINUX_UCRED, etc.:
++ *
++ * Defined to 1 if GCredentials uses Linux `struct ucred`, etc.
++ */
++#undef G_CREDENTIALS_USE_LINUX_UCRED
++#undef G_CREDENTIALS_USE_FREEBSD_CMSGCRED
++#undef G_CREDENTIALS_USE_NETBSD_UNPCBID
++#undef G_CREDENTIALS_USE_OPENBSD_SOCKPEERCRED
++#undef G_CREDENTIALS_USE_SOLARIS_UCRED
++
++/*
++ * G_CREDENTIALS_NATIVE_TYPE:
++ *
++ * Defined to one of G_CREDENTIALS_TYPE_LINUX_UCRED, etc.
++ */
++#undef G_CREDENTIALS_NATIVE_TYPE
++
++/*
++ * G_CREDENTIALS_NATIVE_SIZE:
++ *
++ * Defined to the size of the %G_CREDENTIALS_NATIVE_TYPE
++ */
++#undef G_CREDENTIALS_NATIVE_SIZE
++
++/*
++ * G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED:
++ *
++ * Defined to 1 if we have a message-passing API in which credentials
++ * are attached to a particular message, such as `SCM_CREDENTIALS` on Linux
++ * or `SCM_CREDS` on FreeBSD.
++ */
++#undef G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED
++
++/*
++ * G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED:
++ *
++ * Defined to 1 if we have a `getsockopt()`-style API in which one end of
++ * a socket connection can directly query the credentials of the process
++ * that initiated the other end, such as `getsockopt SO_PEERCRED` on Linux
++ * or `getpeereid()` on multiple operating systems.
++ */
++#undef G_CREDENTIALS_SOCKET_GET_CREDENTIALS_SUPPORTED
++
++/*
++ * G_CREDENTIALS_SPOOFING_SUPPORTED:
++ *
++ * Defined to 1 if privileged processes can spoof their credentials when
++ * using the message-passing API.
++ */
++#undef G_CREDENTIALS_SPOOFING_SUPPORTED
++
+ #ifdef __linux__
+ #define G_CREDENTIALS_SUPPORTED 1
+ #define G_CREDENTIALS_USE_LINUX_UCRED 1
+--
+2.20.1
+
+
+From 5f9318af8f19756685c1b79cf8b76f3e66614d84 Mon Sep 17 00:00:00 2001
+From: Simon McVittie <smcv@collabora.com>
+Date: Fri, 18 Oct 2019 10:55:09 +0100
+Subject: [PATCH 2/3] credentials: Invalid Linux struct ucred means "no
+ information"
+
+On Linux, if getsockopt SO_PEERCRED is used on a TCP socket, one
+might expect it to fail with an appropriate error like ENOTSUP or
+EPROTONOSUPPORT. However, it appears that in fact it succeeds, but
+yields a credentials structure with pid 0, uid -1 and gid -1. These
+are not real process, user and group IDs that can be allocated to a
+real process (pid 0 needs to be reserved to give kill(0) its documented
+special semantics, and similarly uid and gid -1 need to be reserved for
+setresuid() and setresgid()) so it is not meaningful to signal them to
+high-level API users.
+
+An API user with Linux-specific knowledge can still inspect these fields
+via g_credentials_get_native() if desired.
+
+Similarly, if SO_PASSCRED is used to receive a SCM_CREDENTIALS message
+on a receiving Unix socket, but the sending socket had not enabled
+SO_PASSCRED at the time that the message was sent, it is possible
+for it to succeed but yield a credentials structure with pid 0, uid
+/proc/sys/kernel/overflowuid and gid /proc/sys/kernel/overflowgid. Even
+if we were to read those pseudo-files, we cannot distinguish between
+the overflow IDs and a real process that legitimately has the same IDs
+(typically they are set to 'nobody' and 'nogroup', which can be used
+by a real process), so we detect this situation by noticing that
+pid == 0, and to save syscalls we do not read the overflow IDs from
+/proc at all.
+
+This results in a small API change: g_credentials_is_same_user() now
+returns FALSE if we compare two credentials structures that are both
+invalid. This seems like reasonable, conservative behaviour: if we cannot
+prove that they are the same user, we should assume they are not.
+
+(Dropped new translatable string when backporting to `glib-2-62`.)
+
+Signed-off-by: Simon McVittie <smcv@collabora.com>
+---
+ gio/gcredentials.c | 42 +++++++++++++++++++++++++++++++++++++++---
+ 1 file changed, 39 insertions(+), 3 deletions(-)
+
+diff --git a/gio/gcredentials.c b/gio/gcredentials.c
+index 57a39f2a2..ff9b7e0b8 100644
+--- a/gio/gcredentials.c
++++ b/gio/gcredentials.c
+@@ -265,6 +265,35 @@ g_credentials_to_string (GCredentials *credentials)
+
+ /* ---------------------------------------------------------------------------------------------------- */
+
++#if G_CREDENTIALS_USE_LINUX_UCRED
++/*
++ * Check whether @native contains invalid data. If getsockopt SO_PEERCRED
++ * is used on a TCP socket, it succeeds but yields a credentials structure
++ * with pid 0, uid -1 and gid -1. Similarly, if SO_PASSCRED is used on a
++ * receiving Unix socket when the sending socket did not also enable
++ * SO_PASSCRED, it can succeed but yield a credentials structure with
++ * pid 0, uid /proc/sys/kernel/overflowuid and gid
++ * /proc/sys/kernel/overflowgid.
++ */
++static gboolean
++linux_ucred_check_valid (struct ucred *native,
++ GError **error)
++{
++ if (native->pid == 0
++ || native->uid == -1
++ || native->gid == -1)
++ {
++ g_set_error_literal (error,
++ G_IO_ERROR,
++ G_IO_ERROR_INVALID_DATA,
++ "GCredentials contains invalid data");
++ return FALSE;
++ }
++
++ return TRUE;
++}
++#endif
++
+ /**
+ * g_credentials_is_same_user:
+ * @credentials: A #GCredentials.
+@@ -294,7 +323,8 @@ g_credentials_is_same_user (GCredentials *credentials,
+
+ ret = FALSE;
+ #if G_CREDENTIALS_USE_LINUX_UCRED
+- if (credentials->native.uid == other_credentials->native.uid)
++ if (linux_ucred_check_valid (&credentials->native, NULL)
++ && credentials->native.uid == other_credentials->native.uid)
+ ret = TRUE;
+ #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+ if (credentials->native.cmcred_euid == other_credentials->native.cmcred_euid)
+@@ -453,7 +483,10 @@ g_credentials_get_unix_user (GCredentials *credentials,
+ g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+ #if G_CREDENTIALS_USE_LINUX_UCRED
+- ret = credentials->native.uid;
++ if (linux_ucred_check_valid (&credentials->native, error))
++ ret = credentials->native.uid;
++ else
++ ret = -1;
+ #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+ ret = credentials->native.cmcred_euid;
+ #elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+@@ -499,7 +532,10 @@ g_credentials_get_unix_pid (GCredentials *credentials,
+ g_return_val_if_fail (error == NULL || *error == NULL, -1);
+
+ #if G_CREDENTIALS_USE_LINUX_UCRED
+- ret = credentials->native.pid;
++ if (linux_ucred_check_valid (&credentials->native, error))
++ ret = credentials->native.pid;
++ else
++ ret = -1;
+ #elif G_CREDENTIALS_USE_FREEBSD_CMSGCRED
+ ret = credentials->native.cmcred_pid;
+ #elif G_CREDENTIALS_USE_NETBSD_UNPCBID
+--
+2.20.1
+
+
+From c7618cce3752e1f3681f75d0a26c7e07c15bd6a2 Mon Sep 17 00:00:00 2001
+From: Simon McVittie <smcv@collabora.com>
+Date: Mon, 14 Oct 2019 08:47:39 +0100
+Subject: [PATCH 3/3] GDBus: prefer getsockopt()-style credentials-passing APIs
+
+Closes: https://gitlab.gnome.org/GNOME/glib/issues/1831
+---
+ gio/gcredentialsprivate.h | 18 ++++++++++++++++++
+ gio/gdbusauth.c | 27 +++++++++++++++++++++++++--
+ 2 files changed, 43 insertions(+), 2 deletions(-)
+
+diff --git a/gio/gcredentialsprivate.h b/gio/gcredentialsprivate.h
+index 06f0aed19..e9ec09b9f 100644
+--- a/gio/gcredentialsprivate.h
++++ b/gio/gcredentialsprivate.h
+@@ -81,6 +81,18 @@
+ */
+ #undef G_CREDENTIALS_SPOOFING_SUPPORTED
+
++/*
++ * G_CREDENTIALS_PREFER_MESSAGE_PASSING:
++ *
++ * Defined to 1 if the data structure transferred by the message-passing
++ * API is strictly more informative than the one transferred by the
++ * `getsockopt()`-style API, and hence should be preferred, even for
++ * protocols like D-Bus that are defined in terms of the credentials of
++ * the (process that opened the) socket, as opposed to the credentials
++ * of an individual message.
++ */
++#undef G_CREDENTIALS_PREFER_MESSAGE_PASSING
++
+ #ifdef __linux__
+ #define G_CREDENTIALS_SUPPORTED 1
+ #define G_CREDENTIALS_USE_LINUX_UCRED 1
+@@ -100,6 +112,12 @@
+ #define G_CREDENTIALS_NATIVE_SIZE (sizeof (struct cmsgcred))
+ #define G_CREDENTIALS_UNIX_CREDENTIALS_MESSAGE_SUPPORTED 1
+ #define G_CREDENTIALS_SPOOFING_SUPPORTED 1
++/* GLib doesn't implement it yet, but FreeBSD's getsockopt()-style API
++ * is getpeereid(), which is not as informative as struct cmsgcred -
++ * it does not tell us the PID. As a result, libdbus prefers to use
++ * SCM_CREDS, and if we implement getpeereid() in future, we should
++ * do the same. */
++#define G_CREDENTIALS_PREFER_MESSAGE_PASSING 1
+
+ #elif defined(__NetBSD__)
+ #define G_CREDENTIALS_SUPPORTED 1
+diff --git a/gio/gdbusauth.c b/gio/gdbusauth.c
+index 752ec23fc..14cc5d70e 100644
+--- a/gio/gdbusauth.c
++++ b/gio/gdbusauth.c
+@@ -31,6 +31,7 @@
+ #include "gdbusutils.h"
+ #include "gioenumtypes.h"
+ #include "gcredentials.h"
++#include "gcredentialsprivate.h"
+ #include "gdbusprivate.h"
+ #include "giostream.h"
+ #include "gdatainputstream.h"
+@@ -969,9 +970,31 @@ _g_dbus_auth_run_server (GDBusAuth *auth,
+
+ g_data_input_stream_set_newline_type (dis, G_DATA_STREAM_NEWLINE_TYPE_CR_LF);
+
+- /* first read the NUL-byte */
++ /* read the NUL-byte, possibly with credentials attached */
+ #ifdef G_OS_UNIX
+- if (G_IS_UNIX_CONNECTION (auth->priv->stream))
++#ifndef G_CREDENTIALS_PREFER_MESSAGE_PASSING
++ if (G_IS_SOCKET_CONNECTION (auth->priv->stream))
++ {
++ GSocket *sock = g_socket_connection_get_socket (G_SOCKET_CONNECTION (auth->priv->stream));
++
++ local_error = NULL;
++ credentials = g_socket_get_credentials (sock, &local_error);
++
++ if (credentials == NULL && !g_error_matches (local_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
++ {
++ g_propagate_error (error, local_error);
++ goto out;
++ }
++ else
++ {
++ /* Clear the error indicator, so we can retry with
++ * g_unix_connection_receive_credentials() if necessary */
++ g_clear_error (&local_error);
++ }
++ }
++#endif
++
++ if (credentials == NULL && G_IS_UNIX_CONNECTION (auth->priv->stream))
+ {
+ local_error = NULL;
+ credentials = g_unix_connection_receive_credentials (G_UNIX_CONNECTION (auth->priv->stream),
+--
+2.20.1
+