diff --git a/Solaris-and-derivatives-do-not-adjust-cmsg_len-on-MS.patch b/Solaris-and-derivatives-do-not-adjust-cmsg_len-on-MS.patch new file mode 100644 index 0000000000000000000000000000000000000000..5d0670643693cbe2ab4ffeccb1342ecd78a49fd3 --- /dev/null +++ b/Solaris-and-derivatives-do-not-adjust-cmsg_len-on-MS.patch @@ -0,0 +1,49 @@ +From b96ef23e406baa08648339a53b0161fc80de7ce4 Mon Sep 17 00:00:00 2001 +From: Andy Fiddaman +Date: Fri, 12 Jun 2020 12:32:20 +0000 +Subject: [PATCH] Solaris and derivatives do not adjust cmsg_len on MSG_CTRUNC + +--- + dbus/dbus-sysdeps-unix.c | 21 ++++++++++++++++++++- + 1 file changed, 20 insertions(+), 1 deletion(-) + +diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c +index b176dae1..0288dbc9 100644 +--- a/dbus/dbus-sysdeps-unix.c ++++ b/dbus/dbus-sysdeps-unix.c +@@ -441,13 +441,32 @@ _dbus_read_socket_with_unix_fds (DBusSocket fd, + size_t i; + int *payload = (int *) CMSG_DATA (cm); + size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0)); +- size_t payload_len_fds = payload_len_bytes / sizeof (int); ++ size_t payload_len_fds; + size_t fds_to_use; + + /* Every unsigned int fits in a size_t without truncation, so + * casting (size_t) *n_fds is OK */ + _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned int)); + ++ if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL && ++ (char *) payload + payload_len_bytes > ++ (char *) m.msg_control + m.msg_controllen) ++ { ++ /* This is the last cmsg in a truncated message and using ++ * cmsg_len would apparently overrun the allocated buffer. ++ * Some operating systems (illumos and Solaris are known) do ++ * not adjust cmsg_len in the last cmsg when truncation occurs. ++ * Adjust the payload length here. The calculation for ++ * payload_len_fds below will discard any trailing bytes that ++ * belong to an incomplete file descriptor - the kernel will ++ * have already closed that (at least for illumos and Solaris) ++ */ ++ payload_len_bytes = m.msg_controllen - ++ ((char *) payload - (char *) m.msg_control); ++ } ++ ++ payload_len_fds = payload_len_bytes / sizeof (int); ++ + if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds)) + { + /* The fds in the payload will fit in our buffer */ +-- + diff --git a/dbus-1.12.16.tar.gz b/dbus-1.12.16.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..e44857a578d54896e7dafa7bd64d1f2dc28260bf Binary files /dev/null and b/dbus-1.12.16.tar.gz differ diff --git a/dbus-1.12.20.tar.gz b/dbus-1.12.20.tar.gz deleted file mode 100644 index bb72ea6865c5bf5f4b314e53fe3ecf7a06421b18..0000000000000000000000000000000000000000 Binary files a/dbus-1.12.20.tar.gz and /dev/null differ diff --git a/dbus.spec b/dbus.spec index 6ce3b282fe8b0be87af3a2f4f27b736997d82913..2b25357e3ee110cd05c100b9f4c5400e3877a300 100644 --- a/dbus.spec +++ b/dbus.spec @@ -1,14 +1,19 @@ Name: dbus Epoch: 1 -Version: 1.12.20 -Release: 1 +Version: 1.12.16 +Release: 15 Summary: System Message Bus License: AFLv2.1 or GPLv2+ URL: http://www.freedesktop.org/Software/dbus/ Source0: https://dbus.freedesktop.org/releases/dbus/%{name}-%{version}.tar.gz Source1: 00-start-message-bus.sh -Patch0001: bugfix-let-systemd-restart-dbus-when-the-it-enters-failed.patch +# fix CVE-2020-12049 +Patch0000: sysdeps-unix-On-MSG_CTRUNC-close-the-fds-we-did-rece.patch +Patch0001: fdpass-test-Assert-that-we-don-t-leak-file-descripto.patch +Patch0002: Solaris-and-derivatives-do-not-adjust-cmsg_len-on-MS.patch + +Patch0010: bugfix-let-systemd-restart-dbus-when-the-it-enters-failed.patch BuildRequires: systemd-devel expat-devel libselinux-devel audit-libs-devel doxygen xmlto cmake BuildRequires: autoconf-archive libtool libX11-devel libcap-ng-devel libxslt gdb @@ -215,12 +220,6 @@ make check %exclude %{_pkgdocdir}/README %changelog -* Wed Jul 15 2020 shenyangyang - 1:1.12.20-1 -- Upgrade to 1.12.20 - -* Wed Jul 1 2020 shenyangyang - 1:1.12.18-1 -- Upgrade to 1.12.18 - * Mon Jun 22 2020 shenyangyang - 1:1.12.16-15 - Add more test cases modify for solving CVE-2020-12049 diff --git a/fdpass-test-Assert-that-we-don-t-leak-file-descripto.patch b/fdpass-test-Assert-that-we-don-t-leak-file-descripto.patch new file mode 100644 index 0000000000000000000000000000000000000000..fbb1266c7a079c7f86838d1ea0800d0ebfdc1a31 --- /dev/null +++ b/fdpass-test-Assert-that-we-don-t-leak-file-descripto.patch @@ -0,0 +1,64 @@ +From 8bc1381819e5a845331650bfa28dacf6d2ac1748 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 16 Apr 2020 14:41:48 +0100 +Subject: [PATCH] fdpass test: Assert that we don't leak file descriptors + +This version is for the dbus-1.12 branch, and doesn't rely on dbus!153 +or dbus!120. + +Reproduces: dbus#294 +Reproduces: CVE-2020-12049 +Reproduces: GHSL-2020-057 +Signed-off-by: Simon McVittie +--- + test/fdpass.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/test/fdpass.c b/test/fdpass.c +index 4a3edc4e..8bad675f 100644 +--- a/test/fdpass.c ++++ b/test/fdpass.c +@@ -50,6 +50,14 @@ + + #include "test-utils-glib.h" + ++#ifdef DBUS_ENABLE_EMBEDDED_TESTS ++#include ++#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. */ +@@ -92,6 +100,7 @@ typedef struct { + GQueue messages; + + int fd_before; ++ DBusInitialFDs *initial_fds; + } Fixture; + + static void oom (const gchar *doing) G_GNUC_NORETURN; +@@ -176,6 +185,8 @@ test_connect (Fixture *f, + if (f->skip) + return; + ++ f->initial_fds = _dbus_check_fdleaks_enter (); ++ + g_assert (f->left_server_conn == NULL); + g_assert (f->right_server_conn == NULL); + +@@ -871,6 +882,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 +-- + diff --git a/sysdeps-unix-On-MSG_CTRUNC-close-the-fds-we-did-rece.patch b/sysdeps-unix-On-MSG_CTRUNC-close-the-fds-we-did-rece.patch new file mode 100644 index 0000000000000000000000000000000000000000..95ffd861916c84156fa2084d93f312215319342c --- /dev/null +++ b/sysdeps-unix-On-MSG_CTRUNC-close-the-fds-we-did-rece.patch @@ -0,0 +1,73 @@ +From 872b085f12f56da25a2dbd9bd0b2dff31d5aea63 Mon Sep 17 00:00:00 2001 +From: Simon McVittie +Date: Thu, 16 Apr 2020 14:45:11 +0100 +Subject: [PATCH] sysdeps-unix: On MSG_CTRUNC, close the fds we did receive + +MSG_CTRUNC indicates that we have received fewer fds that we should +have done because the buffer was too small, but we were treating it +as though it indicated that we received *no* fds. If we received any, +we still have to make sure we close them, otherwise they will be leaked. + +On the system bus, if an attacker can induce us to leak fds in this +way, that's a local denial of service via resource exhaustion. + +Reported-by: Kevin Backhouse, GitHub Security Lab +Fixes: dbus#294 +Fixes: CVE-2020-12049 +Fixes: GHSL-2020-057 +--- + dbus/dbus-sysdeps-unix.c | 32 ++++++++++++++++++++------------ + 1 file changed, 20 insertions(+), 12 deletions(-) + +diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c +index b5fc2466..b176dae1 100644 +--- a/dbus/dbus-sysdeps-unix.c ++++ b/dbus/dbus-sysdeps-unix.c +@@ -435,18 +435,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) + { +@@ -501,6 +489,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); + +-- +