CVE-2020-12049: File descriptor leak in _dbus_read_socket_with_unix_fds
GHSL-2020-057
GitHub Security Lab (GHSL) Vulnerability Report: The GitHub Security Lab team has identified a potential security vulnerability in dbus.
We are committed to working with you to help resolve these issues. In this report you will find everything you need to effectively coordinate a resolution of these issues with the GHSL team.
If at any point you have concerns or questions about this process, please do not hesitate to reach out to us at securitylab@github.com
(please include your GHSL-2020-057
as a reference).
If you are NOT the correct point of contact for this report, please let us know!
Summary
D-Bus has a file descriptor leak, which can lead to denial of service when the dbus-daemon runs out of file descriptors. An unprivileged local attacker can use this to attack the system dbus-daemon, leading to denial of service for all users of the machine.
Product
D-Bus (dbus-daemon)
Tested Version
1.12.2-1ubuntu1.1 (tested on Ubuntu 18.04.4 LTS)
Details
_dbus_read_socket_with_unix_fds
Issue 1: File descriptor leak in The function _dbus_read_socket_with_unix_fds
contains the following code at
dbus-sysdeps-unix.c, line 438:
if (m.msg_flags & MSG_CTRUNC)
{
/* Hmm, apparently the control data was truncated. The bad
thing is that we might have completely lost a couple of fds
without chance to recover them. Hence let's treat this as a
serious error. */
errno = ENOSPC;
_dbus_string_set_length (buffer, start);
return -1;
}
The intention of this code is to handle the case where too many file descriptors are sent over the unix socket, causing the control data to get truncated. That could be a deliberate attempt by an attacker to cause a denial of service. The problem with the code is that some file descriptors may still have been received, even though the message has been truncated. So we need to make sure that those file descriptors are closed. Otherwise an attacker can cause us to quickly run out of file descriptors.
In my opinion, the simplest solution is to just delete this block of code entirely. The loop below (starting at line 450) handles the file descriptors correctly, so it is better to ignore the MSG_CTRUNC flag and process the message as normal. File descriptors will be correctly closed if the message is invalid. I have confirmed that my proof-of-concept exploit does not work if this block of code is deleted. An alternative solution is to postpone checking the MSG_CTRUNC flag until after the loop at line 450 has finished, so that the file descriptors can be closed correctly.
Impact
This issue can lead to a local denial of service attack: an unprivileged local attacker can make the system unusable for all users. For example, on Ubuntu 18.04.4 LTS, my proof-of-concept exploit prevents all users from logging in, because the login screen needs to send a D-Bus message, but the dbus-daemon is no longer able to send or receive any messages because it cannot create any new file descriptors.
Remediation
As I mentioned above, my recommendation is to delete the block of code at dbus-sysdeps-unix.c, line 438 to 448.
Resources
I have attached the source code of my proof-of-concept exploit: fd_dos.cpp
.
Compile it and run it like this:
gcc fd_dos.cpp -o fd_dos
./fd_dos /var/run/dbus/system_bus_socket
Credit
This issue was discovered and reported by GHSL team member @kevinbackhouse (Kevin Backhouse).
Contact
You can contact the GHSL team at securitylab@github.com
, please include the GHSL-2020-057
in any communication regarding this issue.
Disclosure Policy
This report is subject to our coordinated disclosure policy.