From d07b99e21ab95d7af8dcd2b52c172bab36131dd7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 5 May 2016 12:59:52 +0200 Subject: [PATCH] bus: fix in-flight fd counting logic When a busy connection manages to always keep an fd queued, but still is processing messages, then this might cause dbus connection to kick it from the bus anyway, because the number of queued fds never goes down to zero. This patch changes that, and resets the in-flight timer each time any change on the fd queue is made, and thus is not stuck or stale. This also adds a log message whenever the fd-in-flight timer hits, since the timer elapsing should usually be a very exceptional condition, and a clear indication of a bug or attack somewhere. https://bugs.freedesktop.org/show_bug.cgi?id=95263 https://github.com/systemd/systemd/issues/1961 --- bus/connection.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/bus/connection.c b/bus/connection.c index 67793ba..05406f4 100644 --- a/bus/connection.c +++ b/bus/connection.c @@ -651,19 +651,19 @@ check_pending_fds_cb (DBusConnection *connection) _dbus_verbose ("Pending fds count changed on connection %p: %d -> %d\n", connection, n_pending_unix_fds_old, n_pending_unix_fds_new); - if (n_pending_unix_fds_old == 0 && n_pending_unix_fds_new > 0) + if (n_pending_unix_fds_new == 0) { + /* Stop timer if there are no fds left… */ + _dbus_timeout_set_enabled (d->pending_unix_fds_timeout, FALSE); + } + else if (n_pending_unix_fds_old != n_pending_unix_fds_new) + { + /* Start timer each time an fd is added or removed, i.e. the list of fds isn't stale or stuck */ _dbus_timeout_set_interval (d->pending_unix_fds_timeout, bus_context_get_pending_fd_timeout (d->connections->context)); _dbus_timeout_set_enabled (d->pending_unix_fds_timeout, TRUE); } - if (n_pending_unix_fds_old > 0 && n_pending_unix_fds_new == 0) - { - _dbus_timeout_set_enabled (d->pending_unix_fds_timeout, FALSE); - } - - d->n_pending_unix_fds = n_pending_unix_fds_new; } @@ -671,6 +671,7 @@ static dbus_bool_t pending_unix_fds_timeout_cb (void *data) { DBusConnection *connection = data; + _dbus_warn ("Client sent too many file descriptors, disconnecting."); dbus_connection_close (connection); return TRUE; } -- 2.7.4