From 80f7e5b28c48c0bd98970ef972182f743bda448e Mon Sep 17 00:00:00 2001 From: Andy Fiddaman Date: Fri, 12 Jun 2020 12:32:20 +0000 Subject: Solaris and derivatives do not adjust cmsg_len on MSG_CTRUNC (cherry picked from commit b96ef23e406baa08648339a53b0161fc80de7ce4) --- dbus/dbus-sysdeps-unix.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 6303dbc4..4989e4a9 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -438,7 +438,7 @@ _dbus_read_socket_with_unix_fds (DBusSocket fd, size_t i; int *payload = (int *) CMSG_DATA (cm); size_t payload_len_bytes = (cm->cmsg_len - CMSG_LEN (0)); - size_t payload_len_fds = payload_len_bytes / sizeof (int); + size_t payload_len_fds; size_t fds_to_use; /* Every non-negative int fits in a size_t without truncation, @@ -446,6 +446,25 @@ _dbus_read_socket_with_unix_fds (DBusSocket fd, * casting (size_t) *n_fds is OK */ _DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (int)); + if ((m.msg_flags & MSG_CTRUNC) && CMSG_NXTHDR(&m, cm) == NULL && + (char *) payload + payload_len_bytes > + (char *) m.msg_control + m.msg_controllen) + { + /* This is the last cmsg in a truncated message and using + * cmsg_len would apparently overrun the allocated buffer. + * Some operating systems (illumos and Solaris are known) do + * not adjust cmsg_len in the last cmsg when truncation occurs. + * Adjust the payload length here. The calculation for + * payload_len_fds below will discard any trailing bytes that + * belong to an incomplete file descriptor - the kernel will + * have already closed that (at least for illumos and Solaris) + */ + payload_len_bytes = m.msg_controllen - + ((char *) payload - (char *) m.msg_control); + } + + payload_len_fds = payload_len_bytes / sizeof (int); + if (_DBUS_LIKELY (payload_len_fds <= (size_t) *n_fds)) { /* The fds in the payload will fit in our buffer */ -- cgit v1.2.3