summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--dbus/dbus-sysdeps-unix.c32
1 files changed, 20 insertions, 12 deletions
diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
index b7309712..6303dbc4 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -432,18 +432,6 @@ _dbus_read_socket_with_unix_fds (DBusSocket fd,
struct cmsghdr *cm;
dbus_bool_t found = FALSE;
- 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;
- }
-
for (cm = CMSG_FIRSTHDR(&m); cm; cm = CMSG_NXTHDR(&m, cm))
if (cm->cmsg_level == SOL_SOCKET && cm->cmsg_type == SCM_RIGHTS)
{
@@ -498,6 +486,26 @@ _dbus_read_socket_with_unix_fds (DBusSocket fd,
if (!found)
*n_fds = 0;
+ if (m.msg_flags & MSG_CTRUNC)
+ {
+ int i;
+
+ /* 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. */
+
+ /* We still need to close whatever fds we *did* receive,
+ * otherwise they'll never get closed. (CVE-2020-12049) */
+ for (i = 0; i < *n_fds; i++)
+ close (fds[i]);
+
+ *n_fds = 0;
+ errno = ENOSPC;
+ _dbus_string_set_length (buffer, start);
+ return -1;
+ }
+
/* put length back (doesn't actually realloc) */
_dbus_string_set_length (buffer, start + bytes_read);