summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksandermj@chromium.org>2022-10-17 21:27:01 +0000
committerAleksander Morgado <aleksandermj@chromium.org>2022-10-17 21:39:57 +0000
commitd2b9f082e8684be41e9cd0d3de6edf488803e236 (patch)
tree3fbeef5842d9cbb5afa4983f6ad13e9d78c37e09
parentff7c0c9b84c0b8e32760b5b6e9e978048666d505 (diff)
libqmi-glib: ensure client is valid during message processing
The Client object may be untracked while processing a message (e.g. if forwarding the response back to the remote client fails), and so the tracked reference may end up disposed. If that happens, any attempt to use the client object would end up reading already freed memory, and it would segfault, (e.g. in the `while (client->buffer->len > 0)` check just after having run `process_message()` in `parse_request()`. Avoid this by ensuring a valid Client reference is kept around during all this processing. Thread 0(id: 3232) CRASHED [ SIGSEGV /0x00000000@0x0000000000000004 ] 0x00000000e94d8cdc (libqmi-glib.so.5 - qmi-proxy.c: 942) connection_readable_cb 0x00000000e90aa593 (libgio-2.0.so.0 - gsocket.c: 4008) socket_source_dispatch 0x00000000e934de5b (libglib-2.0.so.0 - gmain.c: 3325) g_main_context_dispatch 0x00000000e934e083 (libglib-2.0.so.0 - gmain.c: 4119) g_main_context_iterate 0x00000000e934e2b3 (libglib-2.0.so.0 - gmain.c: 4317) g_main_loop_run 0x00000000071ebe93 (qmi-proxy - qmi-proxy.c: 230) main 0x00000000e91d1a9b (libc.so.6 - libc-start.c: 314) __libc_start_main 0x00000000071ebcbb (qmi-proxy) _start 0x00000000071ec10b (qmi-proxy - elf-init.c: 90) __libc_csu_init 0x00000000ff9eff8a Fixes https://gitlab.freedesktop.org/mobile-broadband/libqmi/-/issues/72
-rw-r--r--src/libqmi-glib/qmi-proxy.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/src/libqmi-glib/qmi-proxy.c b/src/libqmi-glib/qmi-proxy.c
index 094148e..eeff4bf 100644
--- a/src/libqmi-glib/qmi-proxy.c
+++ b/src/libqmi-glib/qmi-proxy.c
@@ -168,6 +168,8 @@ client_unref (Client *client)
}
}
+G_DEFINE_AUTOPTR_CLEANUP_FUNC (Client, client_unref)
+
static Client *
client_ref (Client *client)
{
@@ -941,15 +943,17 @@ parse_request (QmiProxy *self,
}
static gboolean
-connection_readable_cb (GSocket *socket,
- GIOCondition condition,
- Client *client)
+connection_readable_cb (GSocket *socket,
+ GIOCondition condition,
+ Client *_client)
{
- QmiProxy *self;
- guint8 buffer[BUFFER_SIZE];
- GError *error = NULL;
- gssize r;
+ g_autoptr(Client) client = NULL;
+ QmiProxy *self;
+ guint8 buffer[BUFFER_SIZE];
+ GError *error = NULL;
+ gssize r;
+ client = client_ref (_client);
self = client->proxy;
if (condition & G_IO_IN || condition & G_IO_PRI) {