Package: release.debian.org Severity: normal Tags: stretch User: release.debian....@packages.debian.org Usertags: pu
I would like to update dbus in stable to fix a regression that was introduced during the stretch freeze. dbus 1.10.18-1 fixed the audit log for SELinux AVC notifications (#857660) but in doing so, it reordered dbus-daemon startup so that code intended to raise the system bus file descriptor limit to the maximum was never run as root, making it ineffective, with the result that resource exhaustion is more likely. The attached debdiff has been filtered to exclude Autotools-generated files, and is mostly test coverage. bus/bus.c is the functional change. May I upload? Thanks, smcv
diffstat for dbus-1.10.24 dbus-1.10.26 NEWS | 13 ++ bus/bus.c | 7 + cmake/ConfigureChecks.cmake | 3 cmake/config.h.cmake | 3 configure.ac | 7 - debian/changelog | 15 +++ debian/tests/control | 2 debian/tests/root | 20 +++- test/Makefile.am | 3 test/data/valid-config-files/as-another-user.conf.in | 28 +++++ test/dbus-daemon.c | 95 ++++++++++++++++++- 11 files changed, 181 insertions(+), 15 deletions(-) diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/bus/bus.c dbus-1.10.26/bus/bus.c --- dbus-1.10.24/bus/bus.c 2017-07-28 07:24:16.000000000 +0100 +++ dbus-1.10.26/bus/bus.c 2018-02-23 10:27:26.000000000 +0000 @@ -704,8 +704,6 @@ DBusHashTable *service_context_table; DBusList *watched_dirs = NULL; - raise_file_descriptor_limit (context); - service_context_table = bus_config_parser_steal_service_context_table (parser); if (!bus_registry_set_service_context_table (context->registry, service_context_table)) @@ -931,6 +929,11 @@ !_dbus_pipe_is_stdout_or_stderr (print_pid_pipe)) _dbus_pipe_close (print_pid_pipe, NULL); + /* Raise the file descriptor limits before dropping the privileges + * required to do so. + */ + raise_file_descriptor_limit (context); + /* Here we change our credentials if required, * as soon as we've set up our sockets and pidfile. * This must be done before initializing LSMs, so that the netlink diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/cmake/config.h.cmake dbus-1.10.26/cmake/config.h.cmake --- dbus-1.10.24/cmake/config.h.cmake 2017-07-28 07:24:16.000000000 +0100 +++ dbus-1.10.26/cmake/config.h.cmake 2018-02-23 10:27:26.000000000 +0000 @@ -227,6 +227,9 @@ #cmakedefine HAVE_ACCEPT4 1 #cmakedefine HAVE_DIRFD 1 #cmakedefine HAVE_INOTIFY_INIT1 1 +#cmakedefine HAVE_GETRLIMIT 1 +#cmakedefine HAVE_PRLIMIT 1 +#cmakedefine HAVE_SETRLIMIT 1 #cmakedefine HAVE_UNIX_FD_PASSING 1 // structs diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/cmake/ConfigureChecks.cmake dbus-1.10.26/cmake/ConfigureChecks.cmake --- dbus-1.10.24/cmake/ConfigureChecks.cmake 2015-09-30 15:48:40.000000000 +0100 +++ dbus-1.10.26/cmake/ConfigureChecks.cmake 2018-02-23 10:27:26.000000000 +0000 @@ -62,6 +62,9 @@ check_symbol_exists(SCM_RIGHTS "sys/types.h;sys/socket.h;sys/un.h" HAVE_UNIX_FD_PASSING) check_symbol_exists(prctl "sys/prctl.h" HAVE_PRCTL) check_symbol_exists(raise "signal.h" HAVE_RAISE) +check_symbol_exists(getrlimit "sys/resource.h;sys/time.h" HAVE_GETRLIMIT) +check_symbol_exists(prlimit "sys/resource.h;sys/time.h" HAVE_PRLIMIT) +check_symbol_exists(setrlimit "sys/resource.h;sys/time.h" HAVE_SETRLIMIT) check_struct_member(cmsgcred cmcred_pid "sys/types.h sys/socket.h" HAVE_CMSGCRED) # dbus-sysdeps.c diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/configure.ac dbus-1.10.26/configure.ac --- dbus-1.10.24/configure.ac 2017-09-25 21:02:34.000000000 +0100 +++ dbus-1.10.26/configure.ac 2018-02-23 10:33:49.000000000 +0000 @@ -3,7 +3,7 @@ m4_define([dbus_major_version], [1]) m4_define([dbus_minor_version], [10]) -m4_define([dbus_micro_version], [24]) +m4_define([dbus_micro_version], [26]) m4_define([dbus_version], [dbus_major_version.dbus_minor_version.dbus_micro_version]) AC_INIT([dbus],[dbus_version],[https://bugs.freedesktop.org/enter_bug.cgi?product=dbus],[dbus]) @@ -38,7 +38,7 @@ ## increment any time the source changes; set to ## 0 if you increment CURRENT -LT_REVISION=14 +LT_REVISION=15 ## increment if any interfaces have been added; set to 0 ## if any interfaces have been changed or removed. removal has @@ -606,7 +606,7 @@ AC_SEARCH_LIBS(socket,[socket network]) AC_CHECK_FUNC(gethostbyname,,[AC_CHECK_LIB(nsl,gethostbyname)]) -AC_CHECK_FUNCS([vsnprintf vasprintf nanosleep usleep setenv clearenv unsetenv socketpair getgrouplist fpathconf setrlimit poll setlocale localeconv strtoll strtoull issetugid getresuid setresuid getrlimit]) +AC_CHECK_FUNCS([vsnprintf vasprintf nanosleep usleep setenv clearenv unsetenv socketpair getgrouplist fpathconf setrlimit poll setlocale localeconv strtoll strtoull issetugid getresuid setresuid getrlimit prlimit]) AC_CHECK_HEADERS([syslog.h]) if test "x$ac_cv_header_syslog_h" = "xyes"; then @@ -681,6 +681,7 @@ fi AC_CHECK_HEADERS(sys/resource.h) +AC_CHECK_HEADERS([sys/time.h]) AC_CHECK_HEADERS(dirent.h) diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/debian/changelog dbus-1.10.26/debian/changelog --- dbus-1.10.24/debian/changelog 2017-10-01 12:09:14.000000000 +0100 +++ dbus-1.10.26/debian/changelog 2018-03-02 08:59:25.000000000 +0000 @@ -1,3 +1,18 @@ +dbus (1.10.26-0+deb9u1) stretch; urgency=medium + + * New upstream stable release + - bus/bus.c: Raise file descriptor limit sooner, while we still can + (before we drop privileges), fixing a regression in 1.10.18 which + negated a previous fix for local denial of service via resource + exhaustion + - test/*, build system: Add a regression test for the above + * d/tests/root: Re-run test-dbus-daemon as root, since it now contains + tests that are skipped as non-root + * d/tests/root: Allow stderr output, because test-dbus-daemon emits + some (and it is not a problem) + + -- Simon McVittie <s...@debian.org> Fri, 02 Mar 2018 08:59:25 +0000 + dbus (1.10.24-0+deb9u1) stretch; urgency=medium * New upstream stable release diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/debian/tests/control dbus-1.10.26/debian/tests/control --- dbus-1.10.24/debian/tests/control 2017-10-01 12:09:14.000000000 +0100 +++ dbus-1.10.26/debian/tests/control 2018-03-02 08:59:25.000000000 +0000 @@ -11,7 +11,7 @@ Depends: dbus, dbus-1-dbg, dpkg-dev, gcc, gnome-desktop-testing Tests: root -Restrictions: needs-root +Restrictions: allow-stderr, needs-root Depends: dbus, dbus-tests Tests: root-debug-build diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/debian/tests/root dbus-1.10.26/debian/tests/root --- dbus-1.10.24/debian/tests/root 2017-10-01 12:09:14.000000000 +0100 +++ dbus-1.10.26/debian/tests/root 2018-03-02 08:59:25.000000000 +0000 @@ -1,4 +1,4 @@ -#!/bin/sh +#!/bin/bash # Run some tests as root. Output TAP format because why not set -e @@ -9,15 +9,25 @@ for d in /usr/lib/dbus-1.0/installed-tests/dbus do - DBUS_TEST_DATA="$d/data" - export DBUS_TEST_DATA + export DBUS_TEST_DATA="$d/data" + export DBUS_TEST_EXEC="$d" - for t in $d/test-uid-permissions + for t in \ + $d/test-dbus-daemon \ + $d/test-uid-permissions \ + ${NULL} do i=$(( $i + 1 )) echo "# $i - $t ..." echo "x" > "$ADTTMP/result" - ( set +e; $timeout $t; echo "$?" > "$ADTTMP/result" ) 2>&1 | sed 's/^/# /' + ( + set +e + # One test needs us to have a small fd limit + ulimit -S -n 1024 + ulimit -H -n 1024 + $timeout $t --tap + echo "$?" > "$ADTTMP/result" + ) | sed 's/^/ /' e="$(cat "$ADTTMP/result")" case "$e" in (0) diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/NEWS dbus-1.10.26/NEWS --- dbus-1.10.24/NEWS 2017-09-25 21:01:00.000000000 +0100 +++ dbus-1.10.26/NEWS 2018-03-01 17:41:52.000000000 +0000 @@ -1,3 +1,16 @@ +D-Bus 1.10.26 (2018-03-01) +== + +The “village's rustic aesthetic” release. + +Fixes: + +• Increase system dbus-daemon's RLIMIT_NOFILE rlimit before it drops + privileges, because it won't have permission afterwards. This fixes a + regression in dbus 1.10.18 and 1.11.0 which made the standard system bus + more susceptible to deliberate or accidental denial of service. + (fd.o #105165, David King) + D-Bus 1.10.24 (2017-09-25) == diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/test/data/valid-config-files/as-another-user.conf.in dbus-1.10.26/test/data/valid-config-files/as-another-user.conf.in --- dbus-1.10.24/test/data/valid-config-files/as-another-user.conf.in 1970-01-01 01:00:00.000000000 +0100 +++ dbus-1.10.26/test/data/valid-config-files/as-another-user.conf.in 2018-02-23 10:27:26.000000000 +0000 @@ -0,0 +1,28 @@ +<!-- +Configuration similar to the system bus, to be used when testing rlimit +handling. +--> + +<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-Bus Bus Configuration 1.0//EN" + "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd"> +<busconfig> + <type>system</type> + <user>@DBUS_USER@</user> + <auth>EXTERNAL</auth> + + <!-- This is not the same as the real system bus: we don't want to collide --> + <listen>@TEST_LISTEN@</listen> + + <policy context="default"> + <allow user="*"/> + <deny own="*"/> + <deny send_type="method_call"/> + <allow send_type="signal"/> + <allow send_requested_reply="true" send_type="method_return"/> + <allow send_requested_reply="true" send_type="error"/> + <allow receive_type="method_call"/> + <allow receive_type="method_return"/> + <allow receive_type="error"/> + <allow receive_type="signal"/> + </policy> +</busconfig> diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/test/dbus-daemon.c dbus-1.10.26/test/dbus-daemon.c --- dbus-1.10.24/test/dbus-daemon.c 2017-07-28 07:24:16.000000000 +0100 +++ dbus-1.10.26/test/dbus-daemon.c 2018-02-23 10:27:26.000000000 +0000 @@ -40,8 +40,17 @@ #include <string.h> #ifdef DBUS_UNIX +# include <pwd.h> # include <unistd.h> # include <sys/types.h> + +# ifdef HAVE_SYS_RESOURCE_H +# include <sys/resource.h> +# endif + +# ifdef HAVE_SYS_TIME_H +# include <sys/time.h> +# endif #endif /* Platforms where we know that credentials-passing passes both the @@ -124,6 +133,7 @@ const char *bug_ref; guint min_messages; const char *config_file; + TestUser user; enum { SPECIFY_ADDRESS = 0, RELY_ON_DEFAULT } connect_mode; } Config; @@ -151,7 +161,7 @@ } address = test_get_dbus_daemon (config ? config->config_file : NULL, - TEST_USER_ME, + config ? config->user : TEST_USER_ME, &f->daemon_pid); if (address == NULL) @@ -646,6 +656,71 @@ dbus_message_unref (m); } +#define DESIRED_RLIMIT 65536 + +#ifdef DBUS_UNIX +static void +test_fd_limit (Fixture *f, + gconstpointer context) +{ +#ifdef HAVE_PRLIMIT + struct rlimit lim; + const struct passwd *pwd = NULL; +#endif + + if (f->skip) + return; + +#ifdef HAVE_PRLIMIT + + if (getuid () != 0) + { + g_test_skip ("Cannot test, only uid 0 is expected to raise fd limit"); + return; + } + + pwd = getpwnam (DBUS_USER); + + if (pwd == NULL) + { + gchar *message = g_strdup_printf ("user '%s' does not exist", + DBUS_USER); + + g_test_skip (message); + g_free (message); + return; + } + + if (prlimit (getpid (), RLIMIT_NOFILE, NULL, &lim) < 0) + g_error ("prlimit(): %s", g_strerror (errno)); + + g_test_message ("our RLIMIT_NOFILE: rlim_cur: %ld, rlim_max: %ld", + (long) lim.rlim_cur, (long) lim.rlim_max); + + if (lim.rlim_cur == RLIM_INFINITY || lim.rlim_cur >= DESIRED_RLIMIT) + { + /* The dbus-daemon will have inherited our large rlimit */ + g_test_skip ("Cannot test, our own fd limit was already large"); + return; + } + + if (prlimit (f->daemon_pid, RLIMIT_NOFILE, NULL, &lim) < 0) + g_error ("prlimit(): %s", g_strerror (errno)); + + g_test_message ("dbus-daemon's RLIMIT_NOFILE: rlim_cur: %ld, rlim_max: %ld", + (long) lim.rlim_cur, (long) lim.rlim_max); + + if (lim.rlim_cur != RLIM_INFINITY) + g_assert_cmpint (lim.rlim_cur, >=, DESIRED_RLIMIT); + +#else /* !HAVE_PRLIMIT */ + + g_test_skip ("prlimit() not supported on this platform"); + +#endif /* !HAVE_PRLIMIT */ +} +#endif + static void teardown (Fixture *f, gconstpointer context G_GNUC_UNUSED) @@ -705,18 +780,25 @@ static Config limited_config = { "34393", 10000, "valid-config-files/incoming-limit.conf", - SPECIFY_ADDRESS + TEST_USER_ME, SPECIFY_ADDRESS }; static Config finite_timeout_config = { NULL, 1, "valid-config-files/finite-timeout.conf", - SPECIFY_ADDRESS + TEST_USER_ME, SPECIFY_ADDRESS }; #ifdef DBUS_UNIX static Config listen_unix_runtime_config = { "61303", 1, "valid-config-files/listen-unix-runtime.conf", - RELY_ON_DEFAULT + TEST_USER_ME, RELY_ON_DEFAULT +}; + +static Config as_another_user_config = { + NULL, 1, "valid-config-files/as-another-user.conf", + /* We start the dbus-daemon as root and drop privileges, like the + * real system bus does */ + TEST_USER_ROOT, SPECIFY_ADDRESS }; #endif @@ -743,6 +825,11 @@ * and that blocks on a round-trip to the dbus-daemon */ g_test_add ("/unix-runtime-is-default", Fixture, &listen_unix_runtime_config, setup, test_echo, teardown); + + g_test_add ("/fd-limit/session", Fixture, NULL, + setup, test_fd_limit, teardown); + g_test_add ("/fd-limit/system", Fixture, &as_another_user_config, + setup, test_fd_limit, teardown); #endif return g_test_run (); diff -Nru --exclude Makefile.in --exclude doc/Makefile.in --exclude test/Makefile.in --exclude configure --exclude config.h.in --exclude config.guess --exclude config.sub dbus-1.10.24/test/Makefile.am dbus-1.10.26/test/Makefile.am --- dbus-1.10.24/test/Makefile.am 2017-07-28 07:24:16.000000000 +0100 +++ dbus-1.10.26/test/Makefile.am 2018-02-23 10:27:26.000000000 +0000 @@ -339,6 +339,7 @@ in_data = \ data/valid-config-files-system/debug-allow-all-fail.conf.in \ data/valid-config-files-system/debug-allow-all-pass.conf.in \ + data/valid-config-files/as-another-user.conf.in \ data/valid-config-files/debug-allow-all-sha1.conf.in \ data/valid-config-files/debug-allow-all.conf.in \ data/valid-config-files/finite-timeout.conf.in \ @@ -468,6 +469,7 @@ sed \ -e 's,[@]DBUS_TEST_DATA[@],@abs_builddir@/data,' \ -e 's,[@]DBUS_TEST_EXEC[@],@abs_builddir@,' \ + -e 's,[@]DBUS_USER[@],$(DBUS_USER),' \ -e 's,[@]EXEEXT[@],$(EXEEXT),' \ -e 's,[@]TEST_LAUNCH_HELPER_BINARY[@],@abs_top_builddir@/bus/dbus-daemon-launch-helper-test$(EXEEXT),' \ -e 's,[@]TEST_LISTEN[@],$(TEST_LISTEN),' \ @@ -482,6 +484,7 @@ sed \ -e 's,[@]DBUS_TEST_DATA[@],$(testexecdir)/data,' \ -e 's,[@]DBUS_TEST_EXEC[@],$(testexecdir),' \ + -e 's,[@]DBUS_USER[@],$(DBUS_USER),' \ -e 's,[@]EXEEXT[@],$(EXEEXT),' \ -e 's,[@]TEST_LAUNCH_HELPER_BINARY[@],/bin/false,' \ -e 's,[@]TEST_LISTEN[@],$(TEST_LISTEN),' \