mirror of
https://gitlab.freedesktop.org/dbus/dbus.git
synced 2026-05-05 06:28:00 +02:00
config: change DEFAULT_MESSAGE_UNIX_FDS to 16
This addresses CVE-2014-3636. Based on a patch by Alban Crequy. Now that it's the same on all platforms, there's little point in it being set by configure/cmake. This change fixes two distinct denials of service: fd.o#82820, part A ------------------ Before this patch, the system bus had the following default configuration: - max_connections_per_user: 256 - DBUS_DEFAULT_MESSAGE_UNIX_FDS: usually 1024 (or 256 on QNX, see fd.o#61176) as defined by configure.ac - max_incoming_unix_fds: DBUS_DEFAULT_MESSAGE_UNIX_FDS*4 = usually 4096 - max_outgoing_unix_fds: DBUS_DEFAULT_MESSAGE_UNIX_FDS*4 = usually 4096 - max_message_unix_fds: DBUS_DEFAULT_MESSAGE_UNIX_FDS = usually 1024 This means that a single user could create 256 connections and transmit 256*4096 = 1048576 file descriptors. The file descriptors stay attached to the dbus-daemon process while they are in the message loader, in the outgoing queue or waiting to be dispatched before D-Bus activation. dbus-daemon is usually limited to 65536 file descriptors (ulimit -n). If the limit is reached and dbus-daemon needs to receive a message with a file descriptor attached, this is signalled by recvfrom with the flag MSG_CTRUNC. Dbus-daemon cannot recover from that error because the kernel does not have any API to retrieve a file descriptor which has been discarded with MSG_CTRUNC. Therefore, it closes the connection of the sender. This is not necessarily the connection which generated the most file descriptors so it can lead to denial-of-service attacks. In order to prevent DoS issues, this patch reduces DEFAULT_MESSAGE_UNIX_FDS to 16: max_connections_per_user * max_incoming_unix_fds = 256 * 64 = 16384 This is less than the usual "ulimit -n" (65536) with a good margin to accomodate the other sources of file descriptors (stdin/stdout/stderr, listening sockets, message loader, etc.). Distributors on non-Linux may need to configure a smaller limit in system.conf, if their limit on the number of fds is smaller than Linux's. fd.o#82820, part B ------------------ On Linux, it's not possible to send more than 253 fds in a single sendmsg() call: sendmsg() would return -EINVAL. #define SCM_MAX_FD 253 SCM_MAX_FD changed value during Linux history: - it used to be (OPEN_MAX-1) - commit c09edd6eb (Jul 2007) changed it to 255 - commit bba14de98 (Nov 2010) changed it to 253 Libdbus always sends all of a message's fds, and the beginning of the message itself, in a single sendmsg() call. Combining these two, a malicious sender could split a message across two or more sendmsg() calls to construct a composite message with 254 or more fds. When dbus-daemon attempted to relay that message to its recipient in a single sendmsg() call, it would receive EINVAL, interpret that as a fatal socket error and disconnect the recipient, resulting in denial of service. This is fixed by keeping max_message_unix_fds <= SCM_MAX_FD. Bug: https://bugs.freedesktop.org/show_bug.cgi?id=82820 Reviewed-by: Alban Crequy <alban.crequy@collabora.co.uk>
This commit is contained in:
parent
5bc7f9519e
commit
6465e37c8f
6 changed files with 11 additions and 18 deletions
|
|
@ -49,7 +49,8 @@
|
|||
<limit name="max_outgoing_bytes">1000000000</limit>
|
||||
<limit name="max_outgoing_unix_fds">250000000</limit>
|
||||
<limit name="max_message_size">1000000000</limit>
|
||||
<limit name="max_message_unix_fds">@DEFAULT_MESSAGE_UNIX_FDS@</limit>
|
||||
<!-- We do not override max_message_unix_fds here since the in-kernel
|
||||
limit is also relatively low -->
|
||||
<limit name="service_start_timeout">120000</limit>
|
||||
<limit name="auth_timeout">240000</limit>
|
||||
<limit name="max_completed_connections">100000</limit>
|
||||
|
|
|
|||
|
|
@ -417,10 +417,6 @@ endif (WIN32)
|
|||
|
||||
set (DBUS_USER )
|
||||
|
||||
# In Autotools this has a different default on QNX, but there seems little
|
||||
# point in replicating that here; if you're on an unusual Unix, use Autotools.
|
||||
set (DEFAULT_MESSAGE_UNIX_FDS 1024)
|
||||
|
||||
# This won't work on Windows. It's not meant to - the system bus is
|
||||
# meaningless on Windows anyway.
|
||||
#
|
||||
|
|
|
|||
|
|
@ -82,8 +82,6 @@
|
|||
# define DBUS_ENABLE_X11_AUTOLAUNCH 1
|
||||
#endif
|
||||
|
||||
#define DBUS_DEFAULT_MESSAGE_UNIX_FDS @DEFAULT_MESSAGE_UNIX_FDS@
|
||||
|
||||
#define _DBUS_VA_COPY_ASSIGN(a1,a2) { a1 = a2; }
|
||||
|
||||
#cmakedefine DBUS_VA_COPY_FUNC
|
||||
|
|
|
|||
11
configure.ac
11
configure.ac
|
|
@ -1242,17 +1242,6 @@ if test x$with_valgrind != xno; then
|
|||
AC_DEFINE([WITH_VALGRIND], [1], [Define to add Valgrind instrumentation])
|
||||
fi
|
||||
|
||||
# Determine maximum number of Unix fds which may be passed
|
||||
AS_CASE([$host_os],
|
||||
[*qnx*],
|
||||
[DEFAULT_MESSAGE_UNIX_FDS=256],
|
||||
[*],
|
||||
[DEFAULT_MESSAGE_UNIX_FDS=1024])
|
||||
AC_DEFINE_UNQUOTED([DBUS_DEFAULT_MESSAGE_UNIX_FDS],
|
||||
[$DEFAULT_MESSAGE_UNIX_FDS],
|
||||
[Default for dbus_connection_get_max_message_unix_fds()])
|
||||
AC_SUBST([DEFAULT_MESSAGE_UNIX_FDS])
|
||||
|
||||
#### Set up final flags
|
||||
LIBDBUS_LIBS="$THREAD_LIBS $NETWORK_libs"
|
||||
AC_SUBST([LIBDBUS_LIBS])
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@
|
|||
#include "dbus-list.h"
|
||||
#include "dbus-threads-internal.h"
|
||||
#ifdef HAVE_UNIX_FD_PASSING
|
||||
#include "dbus-sysdeps.h"
|
||||
#include "dbus-sysdeps-unix.h"
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -558,6 +558,14 @@ void _dbus_request_file_descriptor_limit (unsigned int limit);
|
|||
const char *
|
||||
_dbus_replace_install_prefix (const char *configure_time_path);
|
||||
|
||||
/* Do not set this too high: it is a denial-of-service risk.
|
||||
* See <https://bugs.freedesktop.org/show_bug.cgi?id=82820>
|
||||
*
|
||||
* (This needs to be in the non-Unix-specific header so that
|
||||
* the config-parser can use it.)
|
||||
*/
|
||||
#define DBUS_DEFAULT_MESSAGE_UNIX_FDS 16
|
||||
|
||||
/** @} */
|
||||
|
||||
DBUS_END_DECLS
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue