4a88b0
From 51a5bbf9074855b0f4a353ed309938b196c13525 Mon Sep 17 00:00:00 2001
4a88b0
From: Simon McVittie <smcv@collabora.com>
4a88b0
Date: Fri, 30 Sep 2022 13:46:31 +0100
4a88b0
Subject: [PATCH] dbus-marshal-byteswap: Byte-swap Unix fd indexes if needed
4a88b0
4a88b0
When a D-Bus message includes attached file descriptors, the body of the
4a88b0
message contains unsigned 32-bit indexes pointing into an out-of-band
4a88b0
array of file descriptors. Some D-Bus APIs like GLib's GDBus refer to
4a88b0
these indexes as "handles" for the associated fds (not to be confused
4a88b0
with a Windows HANDLE, which is a kernel object).
4a88b0
4a88b0
The assertion message removed by this commit is arguably correct up to
4a88b0
a point: fd-passing is only reasonable on a local machine, and no known
4a88b0
operating system allows processes of differing endianness even on a
4a88b0
multi-endian ARM or PowerPC CPU, so it makes little sense for the sender
4a88b0
to specify a byte-order that differs from the byte-order of the recipient.
4a88b0
4a88b0
However, this doesn't account for the fact that a malicious sender
4a88b0
doesn't have to restrict itself to only doing things that make sense.
4a88b0
On a system with untrusted local users, a message sender could crash
4a88b0
the system dbus-daemon (a denial of service) by sending a message in
4a88b0
the opposite endianness that contains handles to file descriptors.
4a88b0
4a88b0
Before this commit, if assertions are enabled, attempting to byteswap
4a88b0
a fd index would cleanly crash the message recipient with an assertion
4a88b0
failure. If assertions are disabled, attempting to byteswap a fd index
4a88b0
would silently do nothing without advancing the pointer p, causing the
4a88b0
message's type and the pointer into its contents to go out of sync, which
4a88b0
can result in a subsequent crash (the crash demonstrated by fuzzing was
4a88b0
a use-after-free, but other failure modes might be possible).
4a88b0
4a88b0
In principle we could resolve this by rejecting wrong-endianness messages
4a88b0
from a local sender, but it's actually simpler and less code to treat
4a88b0
wrong-endianness messages as valid and byteswap them.
4a88b0
4a88b0
Thanks: Evgeny Vereshchagin
4a88b0
Fixes: ba7daa60 "unix-fd: add basic marshalling code for unix fds"
4a88b0
Resolves: https://gitlab.freedesktop.org/dbus/dbus/-/issues/417
4a88b0
Resolves: CVE-2022-42012
4a88b0
Signed-off-by: Simon McVittie <smcv@collabora.com>
4a88b0
(cherry picked from commit 236f16e444e88a984cf12b09225e0f8efa6c5b44)
4a88b0
(cherry picked from commit 3fb065b0752db1e298e4ada52cf4adc414f5e946)
4a88b0
---
4a88b0
 dbus/dbus-marshal-byteswap.c | 6 +-----
4a88b0
 1 file changed, 1 insertion(+), 5 deletions(-)
4a88b0
4a88b0
diff --git a/dbus/dbus-marshal-byteswap.c b/dbus/dbus-marshal-byteswap.c
4a88b0
index 27695aafb..7104e9c63 100644
4a88b0
--- a/dbus/dbus-marshal-byteswap.c
4a88b0
+++ b/dbus/dbus-marshal-byteswap.c
4a88b0
@@ -61,6 +61,7 @@ byteswap_body_helper (DBusTypeReader       *reader,
4a88b0
         case DBUS_TYPE_BOOLEAN:
4a88b0
         case DBUS_TYPE_INT32:
4a88b0
         case DBUS_TYPE_UINT32:
4a88b0
+        case DBUS_TYPE_UNIX_FD:
4a88b0
           {
4a88b0
             p = _DBUS_ALIGN_ADDRESS (p, 4);
4a88b0
             *((dbus_uint32_t*)p) = DBUS_UINT32_SWAP_LE_BE (*((dbus_uint32_t*)p));
4a88b0
@@ -188,11 +189,6 @@ byteswap_body_helper (DBusTypeReader       *reader,
4a88b0
           }
4a88b0
           break;
4a88b0
 
4a88b0
-        case DBUS_TYPE_UNIX_FD:
4a88b0
-          /* fds can only be passed on a local machine, so byte order must always match */
4a88b0
-          _dbus_assert_not_reached("attempted to byteswap unix fds which makes no sense");
4a88b0
-          break;
4a88b0
-
4a88b0
         default:
4a88b0
           _dbus_assert_not_reached ("invalid typecode in supposedly-validated signature");
4a88b0
           break;
4a88b0
-- 
4a88b0
GitLab
4a88b0