aboutsummaryrefslogtreecommitdiffstats
path: root/main/dbus/CVE-2020-12049.patch
diff options
context:
space:
mode:
Diffstat (limited to 'main/dbus/CVE-2020-12049.patch')
-rw-r--r--main/dbus/CVE-2020-12049.patch103
1 files changed, 103 insertions, 0 deletions
diff --git a/main/dbus/CVE-2020-12049.patch b/main/dbus/CVE-2020-12049.patch
new file mode 100644
index 00000000000..f1b04b4a650
--- /dev/null
+++ b/main/dbus/CVE-2020-12049.patch
@@ -0,0 +1,103 @@
+This is a combination of
+
+https://gitlab.freedesktop.org/dbus/dbus/-/commit/8bc1381819e5a845331650bfa28dacf6d2ac1748.patch
+https://gitlab.freedesktop.org/dbus/dbus/-/commit/272d484283883fa9ff95b69d924fff6cd34842f5.patch
+
+Applied against the 1.10 tree (the commits are for 1.12)
+
+diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
+index b730971..4b0e390 100644
+--- a/dbus/dbus-sysdeps-unix.c
++++ b/dbus/dbus-sysdeps-unix.c
+@@ -432,18 +432,6 @@ _dbus_read_socket_with_unix_fds (DBusSocket fd,
+ struct cmsghdr *cm;
+ dbus_bool_t found = FALSE;
+
+- if (m.msg_flags & MSG_CTRUNC)
+- {
+- /* Hmm, apparently the control data was truncated. The bad
+- thing is that we might have completely lost a couple of fds
+- without chance to recover them. Hence let's treat this as a
+- serious error. */
+-
+- errno = ENOSPC;
+- _dbus_string_set_length (buffer, start);
+- return -1;
+- }
+-
+ for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
+ if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
+ {
+@@ -498,6 +486,26 @@ _dbus_read_socket_with_unix_fds (DBusSocket fd,
+ if (!found)
+ *n_fds = 0;
+
++ if (m.msg_flags & MSG_CTRUNC)
++ {
++ unsigned int i;
++
++ /* Hmm, apparently the control data was truncated. The bad
++ thing is that we might have completely lost a couple of fds
++ without chance to recover them. Hence let's treat this as a
++ serious error. */
++
++ /* We still need to close whatever fds we *did* receive,
++ * otherwise they'll never get closed. (CVE-2020-12049) */
++ for (i = 0; i < *n_fds; i++)
++ close (fds[i]);
++
++ *n_fds = 0;
++ errno = ENOSPC;
++ _dbus_string_set_length (buffer, start);
++ return -1;
++ }
++
+ /* put length back (doesn't actually realloc) */
+ _dbus_string_set_length (buffer, start + bytes_read);
+
+diff --git a/test/fdpass.c b/test/fdpass.c
+index 665b4a1..d8d9c67 100644
+--- a/test/fdpass.c
++++ b/test/fdpass.c
+@@ -50,6 +50,14 @@
+
+ #include "test-utils-glib.h"
+
++#ifdef DBUS_ENABLE_EMBEDDED_TESTS
++#include <dbus/dbus-message-internal.h>
++#else
++typedef struct _DBusInitialFDs DBusInitialFDs;
++#define _dbus_check_fdleaks_enter() NULL
++#define _dbus_check_fdleaks_leave(fds) do {} while (0)
++#endif
++
+ /* Arbitrary; included here to avoid relying on the default */
+ #define MAX_MESSAGE_UNIX_FDS 20
+ /* This test won't work on Linux unless this is true. */
+@@ -91,6 +99,7 @@ typedef struct {
+ GQueue messages;
+
+ int fd_before;
++ DBusInitialFDs *initial_fds;
+ } Fixture;
+
+ static void oom (const gchar *doing) G_GNUC_NORETURN;
+@@ -172,6 +181,8 @@ test_connect (Fixture *f,
+ {
+ char *address;
+
++ f->initial_fds = _dbus_check_fdleaks_enter ();
++
+ g_assert (f->left_server_conn == NULL);
+ g_assert (f->right_server_conn == NULL);
+
+@@ -835,6 +846,9 @@ teardown (Fixture *f,
+ if (f->fd_before >= 0 && close (f->fd_before) < 0)
+ g_error ("%s", g_strerror (errno));
+ #endif
++
++ if (f->initial_fds != NULL)
++ _dbus_check_fdleaks_leave (f->initial_fds);
+ }
+
+ int