Possible SEGV (null pointer deref) in distribute_method_call()
There appears to be a rare SEGV (null pointer deref) possible in the distribute_method_call()
function from gdbusconnection.c
. The relevant code is here:
static void
distribute_method_call (GDBusConnection *connection,
GDBusMessage *message)
{
...
path = g_dbus_message_get_path (message); // This function can fail and return NULL
subtree_path = g_strdup (path);
needle = strrchr (subtree_path, '/'); // <--- Possible NULL pointer dereference
...
}
The problem is that the g_dbus_message_get_path()
can fail and return NULL
(see here, where the header field has an unexpected variant type). If this occurs, then path
and subtree_path
will be NULL
, causing a SEGV in the call to strrchr()
.
It is possible to induce the crash by reading a corrupt a DBUS message from the wire. It is a bit hard to reproduce, but changing the byte marked by ^
to the value 0x01
seems to do the trick:
..o...../org/gnome/Mines..........s.....org.freedesktop.DBus.Properties...s.....:1.156....g..s....s.....GetAll....s.....:1.34.......org.gtk.Application
^
Apologies if that is not very helpful.
Since it involves a corrupt message, this bug in unlikely to appear in everyday use. Nevertheless, glib should probably handle it more gracefully.
Example stack trace:
Thread 4 "gdbus" received signal SIGSEGV, Segmentation fault.
__strrchr_sse2 () at ../sysdeps/x86_64/multiarch/strrchr-sse2.S:58
...
#0 __strrchr_sse2 () at ../sysdeps/x86_64/multiarch/strrchr-sse2.S:58
#1 0x00007ffff742681b in distribute_method_call (message=0x7fffe8007650, connection=0x555555597fe0)
at ../gio/gdbusconnection.c:7203
#2 on_worker_message_received (worker=<optimized out>, user_data=0x555555597fe0, message=0x7fffe8007650)
at ../gio/gdbusconnection.c:2341
#3 on_worker_message_received (worker=<optimized out>, message=<optimized out>, user_data=0x555555597fe0)
at ../gio/gdbusconnection.c:2255
#4 0x00007ffff743c372 in _g_dbus_worker_emit_message_received (message=0x7fffe8007650, worker=0x55555559f200)
at ../gio/gdbusprivate.c:492
#5 _g_dbus_worker_emit_message_received (message=0x7fffe8007650, worker=0x55555559f200) at ../gio/gdbusprivate.c:488
#6 _g_dbus_worker_queue_or_deliver_received_message (message=0x7fffe8007650, worker=0x55555559f200)
at ../gio/gdbusprivate.c:520
#7 _g_dbus_worker_do_read_cb (input_stream=<optimized out>, res=<optimized out>, user_data=0x55555559f200)
at ../gio/gdbusprivate.c:815
#8 0x00007ffff73cd3b3 in g_task_return_now (task=0x7fffe8006240) at ../gio/gtask.c:1371
#9 0x00007ffff73cd3ed in complete_in_idle_cb (task=0x7fffe8006240) at ../gio/gtask.c:1385
#10 0x00007ffff7ec036f in g_main_dispatch (context=0x55555559f560) at ../../../glib/gmain.c:3460
#11 g_main_context_dispatch (context=0x55555559f560) at ../../../glib/gmain.c:4200
#12 0x00007ffff7f1b178 in g_main_context_iterate.constprop.0
(context=0x55555559f560, block=<optimized out>, dispatch=1, self=<optimized out>) at ../../../glib/gmain.c:4276
#13 0x00007ffff7ebfbdf in g_main_loop_run (loop=0x55555559f690) at ../../../glib/gmain.c:4479
#14 0x00007ffff743a12a in gdbus_shared_thread_func (user_data=0x55555559f530) at ../gio/gdbusprivate.c:284
#15 0x00007ffff7eec361 in g_thread_proxy (data=0x555555591910) at ../../../glib/gthread.c:831
#16 0x00007ffff6e8f18a in start_thread (arg=<optimized out>) at ./nptl/pthread_create.c:444
#17 0x00007ffff6f1dbd0 in clone3 () at ../sysdeps/unix/sysv/linux/x86_64/clone3.S:81
Tested on both the Ubuntu 23.04 system library and latest git head.