From 8d7d20f1ae6c10ef37723572b535c5c22814461e Mon Sep 17 00:00:00 2001 From: Sona Sarmadi Date: Fri, 4 Dec 2015 14:37:17 +0100 Subject: dbus: CVE-2014-3532 Fixes denial of service in file descriptor passing feature References: https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3532 https://bugs.freedesktop.org/show_bug.cgi?id=80163 http://openwall.com/lists/oss-security/2014/07/02/4 Upstream commit: http://cgit.freedesktop.org/dbus/dbus/commit/?id= 9ca90648fc870c24d852ce6d7ce9387a9fc9a94a Signed-off-by: Sona Sarmadi --- recipes-core/dbus/dbus_1.8.2.bbappend | 5 ++ recipes-core/dbus/files/CVE-2014-3532.patch | 112 ++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+) create mode 100644 recipes-core/dbus/dbus_1.8.2.bbappend create mode 100644 recipes-core/dbus/files/CVE-2014-3532.patch (limited to 'recipes-core') diff --git a/recipes-core/dbus/dbus_1.8.2.bbappend b/recipes-core/dbus/dbus_1.8.2.bbappend new file mode 100644 index 0000000..3a6cb06 --- /dev/null +++ b/recipes-core/dbus/dbus_1.8.2.bbappend @@ -0,0 +1,5 @@ +FILESEXTRAPATHS_prepend := "${THISDIR}/files:" + +SRC_URI += "\ + file://CVE-2014-3532.patch \ + " diff --git a/recipes-core/dbus/files/CVE-2014-3532.patch b/recipes-core/dbus/files/CVE-2014-3532.patch new file mode 100644 index 0000000..95f110c --- /dev/null +++ b/recipes-core/dbus/files/CVE-2014-3532.patch @@ -0,0 +1,112 @@ +Date: Tue, 24 Jun 2014 17:57:14 +0100 +Subject: Handle ETOOMANYREFS when sending recursive fds (SCM_RIGHTS) + +Since Linux commit 25888e (from 2.6.37-rc4, Nov 2010), sendmsg() on Unix +sockets returns -1 errno=ETOOMANYREFS ("Too many references: cannot splice") +when the passfd mechanism (SCM_RIGHTS) is "abusively" used recursively by +applications. A malicious client could use this to force a victim system +service to be disconnected from the system bus; the victim would likely +respond by exiting. This is a denial of service (fd.o #80163, +CVE-2014-3532). + +This patch silently drops the D-Bus message on ETOOMANYREFS and does not close +the connection. + +Upstream-Status: Backport + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=80163 +Reviewed-by: Thiago Macieira +[altered commit message to explain DoS significance -smcv] +Reviewed-by: Simon McVittie +Signed-off-by: Sona Sarmadi + +diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c +index de3a18c..f4ba0fa 100644 +--- a/dbus/dbus-sysdeps.c ++++ b/dbus/dbus-sysdeps.c +@@ -762,6 +762,20 @@ _dbus_get_is_errno_epipe (void) + } + + /** ++ * See if errno is ETOOMANYREFS ++ * @returns #TRUE if errno == ETOOMANYREFS ++ */ ++dbus_bool_t ++_dbus_get_is_errno_etoomanyrefs (void) ++{ ++#ifdef ETOOMANYREFS ++ return errno == ETOOMANYREFS; ++#else ++ return FALSE; ++#endif ++} ++ ++/** + * Get error message from errno + * @returns _dbus_strerror(errno) + */ +diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h +index e586946..21033eb 100644 +--- a/dbus/dbus-sysdeps.h ++++ b/dbus/dbus-sysdeps.h +@@ -384,6 +384,7 @@ dbus_bool_t _dbus_get_is_errno_eagain_or_ewouldblock (void); + dbus_bool_t _dbus_get_is_errno_enomem (void); + dbus_bool_t _dbus_get_is_errno_eintr (void); + dbus_bool_t _dbus_get_is_errno_epipe (void); ++dbus_bool_t _dbus_get_is_errno_etoomanyrefs (void); + const char* _dbus_strerror_from_errno (void); + + void _dbus_disable_sigpipe (void); +diff --git a/dbus/dbus-transport-socket.c b/dbus/dbus-transport-socket.c +index 774f459..199d3b5 100644 +--- a/dbus/dbus-transport-socket.c ++++ b/dbus/dbus-transport-socket.c +@@ -645,12 +645,44 @@ do_writing (DBusTransport *transport) + { + /* EINTR already handled for us */ + +- /* For some discussion of why we also ignore EPIPE here, see ++ /* If the other end closed the socket with close() or shutdown(), we ++ * receive EPIPE here but we must not close the socket yet: there ++ * might still be some data to read. See: + * http://lists.freedesktop.org/archives/dbus/2008-March/009526.html + */ + + if (_dbus_get_is_errno_eagain_or_ewouldblock () || _dbus_get_is_errno_epipe ()) + goto out; ++ ++ /* Since Linux commit 25888e (from 2.6.37-rc4, Nov 2010), sendmsg() ++ * on Unix sockets returns -1 errno=ETOOMANYREFS when the passfd ++ * mechanism (SCM_RIGHTS) is used recursively with a recursion level ++ * of maximum 4. The kernel does not have an API to check whether ++ * the passed fds can be forwarded and it can change asynchronously. ++ * See: ++ * https://bugs.freedesktop.org/show_bug.cgi?id=80163 ++ */ ++ ++ else if (_dbus_get_is_errno_etoomanyrefs ()) ++ { ++ /* We only send fds in the first byte of the message. ++ * ETOOMANYREFS cannot happen after. ++ */ ++ _dbus_assert (socket_transport->message_bytes_written == 0); ++ ++ _dbus_verbose (" discard message of %d bytes due to ETOOMANYREFS\n", ++ total_bytes_to_write); ++ ++ socket_transport->message_bytes_written = 0; ++ _dbus_string_set_length (&socket_transport->encoded_outgoing, 0); ++ _dbus_string_compact (&socket_transport->encoded_outgoing, 2048); ++ ++ /* The message was not actually sent but it needs to be removed ++ * from the outgoing queue ++ */ ++ _dbus_connection_message_sent_unlocked (transport->connection, ++ message); ++ } + else + { + _dbus_verbose ("Error writing to remote app: %s\n", +-- +cgit v0.10.2 + -- cgit v1.2.3-54-g00ecf