diff options
author | Simon McVittie <simon.mcvittie@collabora.co.uk> | 2017-01-17 15:13:36 +0000 |
---|---|---|
committer | Simon McVittie <smcv@debian.org> | 2017-02-01 10:44:00 +0000 |
commit | 892f084eeda0806aab6f91f5bccd8989a04ed3f6 (patch) | |
tree | e2943401c322e5028ba7a2eac13d62816ba6c12a /dbus/dbus-message-util.c | |
parent | 529600397bcab47b9bed5da9208c2df05c8b86b4 (diff) | |
download | dbus-892f084eeda0806aab6f91f5bccd8989a04ed3f6.tar.gz |
Only read one message at a time if there are fds pending
systemd-logind's OpenSession() API call returns a fd. If there is a
flood of new sessions, it is possible that by the time we finish reading
message 1, message 2 will already be in our incoming buffer and so on.
This results in systemd-logind consistently having one or more fds enqueued
for an extended period, which we interpret as a denial of service
attack, and handle by kicking it off the bus (at least until we worked
around the resulting logind failure by making uid 0 immune to that
particular anti-DoS mechanism, but that workaround doesn't work for
other uids).
To avoid this without the complexity of tracking multiple countdowns
per connection (one for each message with fds), we can avoid reading
any additional messages while we already have a message with a fd
attached pending processing. To avoid stalling, we have to read the rest
of any partial message we might have, but we stop after that.
Assuming we are able to get rid of the pending fds within a reasonable
time, we'll eventually drain the incoming queue to a level of 0 bytes
and 0 fds, at which point the countdown stops.
To make this actually work, we need fd.o #95619 to be fixed first, so
that when we receive more fds and restart the countdown, it restarts
with its correct time remaining.
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=95263
Signed-off-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Tested-by: Kai-Heng Feng
Diffstat (limited to 'dbus/dbus-message-util.c')
-rw-r--r-- | dbus/dbus-message-util.c | 10 |
1 files changed, 5 insertions, 5 deletions
diff --git a/dbus/dbus-message-util.c b/dbus/dbus-message-util.c index 60133e11..74020610 100644 --- a/dbus/dbus-message-util.c +++ b/dbus/dbus-message-util.c @@ -489,7 +489,7 @@ dbus_internal_do_not_use_try_message_data (const DBusString *data, { DBusString *buffer; - _dbus_message_loader_get_buffer (loader, &buffer); + _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); _dbus_string_append_byte (buffer, _dbus_string_get_byte (data, i)); _dbus_message_loader_return_buffer (loader, buffer); @@ -508,7 +508,7 @@ dbus_internal_do_not_use_try_message_data (const DBusString *data, { DBusString *buffer; - _dbus_message_loader_get_buffer (loader, &buffer); + _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); _dbus_string_copy (data, 0, buffer, _dbus_string_get_length (buffer)); _dbus_message_loader_return_buffer (loader, buffer); @@ -529,7 +529,7 @@ dbus_internal_do_not_use_try_message_data (const DBusString *data, { DBusString *buffer; - _dbus_message_loader_get_buffer (loader, &buffer); + _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); _dbus_string_append_byte (buffer, _dbus_string_get_byte (data, i)); if ((i+1) < len) @@ -1497,7 +1497,7 @@ _dbus_message_test (const char *test_data_dir) { DBusString *buffer; - _dbus_message_loader_get_buffer (loader, &buffer); + _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); _dbus_string_append_byte (buffer, data[i]); _dbus_message_loader_return_buffer (loader, buffer); } @@ -1508,7 +1508,7 @@ _dbus_message_test (const char *test_data_dir) { DBusString *buffer; - _dbus_message_loader_get_buffer (loader, &buffer); + _dbus_message_loader_get_buffer (loader, &buffer, NULL, NULL); _dbus_string_append_byte (buffer, data[i]); _dbus_message_loader_return_buffer (loader, buffer); } |