summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorhongjinghao <q1204531485@163.com>2023-06-05 18:17:06 +0100
committerKarol Lewandowski <k.lewandowsk@samsung.com>2023-10-05 22:07:47 +0200
commit5c4fb289437d1d80991ae74f689e34fcebb27b31 (patch)
treee93ab6f8e44171653efe77f7e2acdcd613a7b82a
parent9aca6d45fb390318a8795e6c965f07143d051068 (diff)
downloaddbus-accepted/tizen/unified/20231011.153130.tar.gz
dbus-accepted/tizen/unified/20231011.153130.tar.bz2
dbus-accepted/tizen/unified/20231011.153130.zip
bus: Assign a serial number for messages from the driveraccepted/tizen/unified/dev/20240620.010635accepted/tizen/unified/20231011.153130
Normally, it's enough to rely on a message being given a serial number by the DBusConnection just before it is actually sent. However, in the rare case where the policy blocks the driver from sending a message (due to a deny rule or the outgoing message quota being full), we need to get a valid serial number sooner, so that we can copy it into the DBUS_HEADER_FIELD_REPLY_SERIAL field (which is mandatory) in the error message sent to monitors. Otherwise, the dbus-daemon will crash with an assertion failure if at least one Monitoring client is attached, because zero is not a valid serial number to copy. This fixes a denial-of-service vulnerability: if a privileged user is monitoring the well-known system bus using a Monitoring client like dbus-monitor or `busctl monitor`, then an unprivileged user can cause denial-of-service by triggering this crash. A mitigation for this vulnerability is to avoid attaching Monitoring clients to the system bus when they are not needed. If there are no Monitoring clients, then the vulnerable code is not reached. Co-authored-by: Simon McVittie <smcv@collabora.com> Resolves: dbus/dbus#457 (cherry picked from commit b159849e031000d1dbc1ab876b5fc78a3ce9b534) [ cherry picked to tizen branch, fixes CVE-2023-34969 ] Change-Id: Iee520329acc1d4a93d3a873a5fded056cb293d5b Signed-off-by: Karol Lewandowski <k.lewandowsk@samsung.com>
-rw-r--r--bus/connection.c15
-rw-r--r--dbus/dbus-connection-internal.h2
-rw-r--r--dbus/dbus-connection.c11
3 files changed, 27 insertions, 1 deletions
diff --git a/bus/connection.c b/bus/connection.c
index 15aea6ed..dc5c7ed2 100644
--- a/bus/connection.c
+++ b/bus/connection.c
@@ -2458,6 +2458,21 @@ bus_transaction_send_from_driver (BusTransaction *transaction,
if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
return FALSE;
+ /* Make sure the message has a non-zero serial number, otherwise
+ * bus_transaction_capture_error_reply() will not be able to mock up
+ * a corresponding reply for it. Normally this would be delayed until
+ * the first time we actually send the message out from a
+ * connection, when the transaction is committed, but that's too late
+ * in this case.
+ */
+ if (dbus_message_get_serial (message) == 0)
+ {
+ dbus_uint32_t next_serial;
+
+ next_serial = _dbus_connection_get_next_client_serial (connection);
+ dbus_message_set_serial (message, next_serial);
+ }
+
if (bus_connection_is_active (connection))
{
if (!dbus_message_set_destination (message,
diff --git a/dbus/dbus-connection-internal.h b/dbus/dbus-connection-internal.h
index aca66313..794f0baf 100644
--- a/dbus/dbus-connection-internal.h
+++ b/dbus/dbus-connection-internal.h
@@ -54,6 +54,8 @@ DBUS_PRIVATE_EXPORT
DBusConnection * _dbus_connection_ref_unlocked (DBusConnection *connection);
DBUS_PRIVATE_EXPORT
void _dbus_connection_unref_unlocked (DBusConnection *connection);
+DBUS_PRIVATE_EXPORT
+dbus_uint32_t _dbus_connection_get_next_client_serial (DBusConnection *connection);
void _dbus_connection_queue_received_message_link (DBusConnection *connection,
DBusList *link);
dbus_bool_t _dbus_connection_has_messages_to_send_unlocked (DBusConnection *connection);
diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c
index e0105790..7fa0ca03 100644
--- a/dbus/dbus-connection.c
+++ b/dbus/dbus-connection.c
@@ -1503,7 +1503,16 @@ _dbus_connection_unref_unlocked (DBusConnection *connection)
_dbus_connection_last_unref (connection);
}
-static dbus_uint32_t
+/**
+ * Allocate and return the next non-zero serial number for outgoing messages.
+ *
+ * This method is only valid to call from single-threaded code, such as
+ * the dbus-daemon, or with the connection lock held.
+ *
+ * @param connection the connection
+ * @returns A suitable serial number for the next message to be sent on the connection.
+ */
+dbus_uint32_t
_dbus_connection_get_next_client_serial (DBusConnection *connection)
{
dbus_uint32_t serial;