]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
DBusMessage: Fix UB (misaligned access) in call to _dbus_header_set_field_basic()
authorMarc Mutz <marc@kdab.net>
Mon, 3 Oct 2016 20:19:45 +0000 (22:19 +0200)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Tue, 4 Oct 2016 10:22:25 +0000 (11:22 +0100)
The const void* 'value' pointer that is passed the address of a
uint32_t here eventually ends up in _dbus_marshal_write_basic(), which
casts it to a DBusBasicValue, a union type that has an alignment of
eight on 64-bit platforms and is therefore more-aligned than the
uint32.

The read of a value of a more-aligned type through a pointer to a less
-aligned type is undefined behaviour.

Fix by storing the uint32 in a DBusBasicValue and passing that instead.

Found by UBSan:

  dbus/dbus/dbus-marshal-basic.c:832:14: runtime error: member access within misaligned address 0x7fdb8dac3a04 for type 'const union DBusBasicValue', which requires 8 byte alignment
  0x7fdb8dac3a04: note: pointer points here
    4a 87 b5 71 01 00 00 00  40 7d 01 00 00 61 00 00  10 3b ac 8d db 7f 00 00  2c 2a 3e 94 db 7f 00 00
                ^
    #0 0x7fdb9444a2c3 in _dbus_marshal_write_basic dbus/dbus/dbus-marshal-basic.c:832
    #1 0x7fdb943d22fb in _dbus_type_writer_write_basic_no_typecode dbus/dbus/dbus-marshal-recursive.c:1605
    #2 0x7fdb943d64e9 in _dbus_type_writer_write_basic dbus/dbus/dbus-marshal-recursive.c:2327
    #3 0x7fdb943c52a6 in write_basic_field dbus/dbus/dbus-marshal-header.c:318
    #4 0x7fdb943c919e in _dbus_header_set_field_basic dbus/dbus/dbus-marshal-header.c:1321
    #5 0x7fdb943e1349 in dbus_message_set_reply_serial dbus/dbus/dbus-message.c:1173

Signed-off-by: Marc Mutz <marc@kdab.net>
Reviewed-by: Simon McVittie <simon.mcvittie@collabora.co.uk>
Bug: https://bugs.freedesktop.org/show_bug.cgi?id=98035

dbus/dbus-message.c

index e22fe51b3285de94b64215186b55e6b413b9d7c3..e0d9c8bd529880d9a1b413890e20afc62f087224 100644 (file)
@@ -1166,14 +1166,18 @@ dbus_bool_t
 dbus_message_set_reply_serial (DBusMessage   *message,
                                dbus_uint32_t  reply_serial)
 {
+  DBusBasicValue value;
+
   _dbus_return_val_if_fail (message != NULL, FALSE);
   _dbus_return_val_if_fail (!message->locked, FALSE);
   _dbus_return_val_if_fail (reply_serial != 0, FALSE); /* 0 is invalid */
 
+  value.u32 = reply_serial;
+
   return _dbus_header_set_field_basic (&message->header,
                                        DBUS_HEADER_FIELD_REPLY_SERIAL,
                                        DBUS_TYPE_UINT32,
-                                       &reply_serial);
+                                       &value);
 }
 
 /**