From 12004575b92178ea0963f01e5ca5633735fc6777 Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 20 Feb 2018 11:45:39 +0000 Subject: [PATCH 2/2] Add a unit test for the dbus-daemon resetting its fd limit Signed-off-by: Simon McVittie Bug: https://bugs.freedesktop.org/show_bug.cgi?id=105165 --- configure.ac | 3 +- test/Makefile.am | 3 ++ test/dbus-daemon.c | 86 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ tools/ci-build.sh | 1 + 4 files changed, 92 insertions(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 5bcfed22..f86753a0 100644 --- a/configure.ac +++ b/configure.ac @@ -612,7 +612,7 @@ AC_DEFINE_UNQUOTED([DBUS_USE_SYNC], [$have_sync], [Use the gcc __sync extension] 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 @@ -687,6 +687,7 @@ closedir(dirp); fi AC_CHECK_HEADERS(sys/resource.h) +AC_CHECK_HEADERS([sys/time.h]) AC_CHECK_HEADERS(dirent.h) diff --git a/test/Makefile.am b/test/Makefile.am index 04bfc61c..5153ab6c 100644 --- a/test/Makefile.am +++ b/test/Makefile.am @@ -440,6 +440,7 @@ in_data = \ data/systemd-activation/com.example.SystemdActivatable3.service.in \ 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/count-fds.conf.in \ data/valid-config-files/debug-allow-all-sha1.conf.in \ data/valid-config-files/debug-allow-all.conf.in \ @@ -557,6 +558,7 @@ uninstalled-config-local: 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),' \ @@ -571,6 +573,7 @@ if DBUS_ENABLE_INSTALLED_TESTS 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),' \ diff --git a/test/dbus-daemon.c b/test/dbus-daemon.c index 7f990a7e..0c817763 100644 --- a/test/dbus-daemon.c +++ b/test/dbus-daemon.c @@ -42,6 +42,7 @@ #include #ifdef DBUS_UNIX +# include # include # include @@ -49,6 +50,14 @@ /* The CMake build system doesn't know how to check for this yet */ # include # endif + +# ifdef HAVE_SYS_RESOURCE_H +# include +# endif + +# ifdef HAVE_SYS_TIME_H +# include +# endif #endif /* Platforms where we know that credentials-passing passes both the @@ -1843,6 +1852,71 @@ test_get_all (Fixture *f, dbus_clear_message (&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) @@ -1962,6 +2036,13 @@ static Config count_fds_config = { }; #endif +#if defined(DBUS_UNIX) +static Config as_another_user_config = { + NULL, 1, "valid-config-files/as-another-user.conf", + SPECIFY_ADDRESS +}; +#endif + int main (int argc, char **argv) @@ -2036,6 +2117,11 @@ main (int argc, * 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 --git a/tools/ci-build.sh b/tools/ci-build.sh index 33d5ffe1..823360c7 100755 --- a/tools/ci-build.sh +++ b/tools/ci-build.sh @@ -244,6 +244,7 @@ case "$ci_buildsys" in # these tests benefit from being re-run as root sudo env LD_LIBRARY_PATH=/usr/local/lib \ gnome-desktop-testing-runner -d /usr/local/share \ + dbus/test-dbus-daemon_with_config.test \ dbus/test-uid-permissions_with_config.test || \ maybe_fail_tests fi -- 2.16.1