50 lines
2.2 KiB
Diff
50 lines
2.2 KiB
Diff
From b96ef23e406baa08648339a53b0161fc80de7ce4 Mon Sep 17 00:00:00 2001
|
|
From: Andy Fiddaman <omnios@citrus-it.co.uk>
|
|
Date: Fri, 12 Jun 2020 12:32:20 +0000
|
|
Subject: [PATCH] Solaris and derivatives do not adjust cmsg_len on MSG_CTRUNC
|
|
|
|
---
|
|
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 b176dae1..0288dbc9 100644
|
|
--- a/dbus/dbus-sysdeps-unix.c
|
|
+++ b/dbus/dbus-sysdeps-unix.c
|
|
@@ -441,13 +441,32 @@ _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 unsigned int fits in a size_t without truncation, so
|
|
* casting (size_t) *n_fds is OK */
|
|
_DBUS_STATIC_ASSERT (sizeof (size_t) >= sizeof (unsigned 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 */
|
|
--
|
|
|