summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksander Morgado <aleksander@aleksander.es>2019-12-21 16:38:40 +0100
committerAleksander Morgado <aleksander@aleksander.es>2019-12-21 16:40:14 +0100
commit4d5a77fe68feeef3c0aed27c865ac7645760789b (patch)
tree58b6e4c69e60e31e012496db53c415c06618fa47
parent0d3017abc39d14d4c8356f54af81aa4dbb0f4e79 (diff)
libmbim,device: plug memleak when processing responses with multiple fragments
==8725== 48 bytes in 3 blocks are definitely lost in loss record 840 of 1,273 ==8725== at 0x483877F: malloc (vg_replace_malloc.c:309) ==8725== by 0x4B7C8D9: g_malloc (in /usr/lib/libglib-2.0.so.0.6200.3) ==8725== by 0x4B5D893: g_slice_alloc (in /usr/lib/libglib-2.0.so.0.6200.3) ==8725== by 0x48AA78D: device_store_transaction (mbim-device.c:371) ==8725== by 0x48AE34C: mbim_device_command (mbim-device.c:2218) ==8725== by 0x48B0E83: process_command (mbim-proxy.c:1020) ==8725== by 0x48B0F8C: process_message (mbim-proxy.c:1052) ==8725== by 0x48B1052: parse_request (mbim-proxy.c:1091) ==8725== by 0x48B1279: connection_readable_cb (mbim-proxy.c:1140) ==8725== by 0x49D32E9: ??? (in /usr/lib/libgio-2.0.so.0.6200.3) ==8725== by 0x4B8226E: g_main_context_dispatch (in /usr/lib/libglib-2.0.so.0.6200.3) ==8725== by 0x4B841B0: ??? (in /usr/lib/libglib-2.0.so.0.6200.3) ==8725==
-rw-r--r--src/libmbim-glib/mbim-device.c16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/libmbim-glib/mbim-device.c b/src/libmbim-glib/mbim-device.c
index b1add4c..ec998b4 100644
--- a/src/libmbim-glib/mbim-device.c
+++ b/src/libmbim-glib/mbim-device.c
@@ -368,14 +368,18 @@ device_store_transaction (MbimDevice *self,
ctx = g_task_get_task_data (task);
- ctx->wait_ctx = g_slice_new (TransactionWaitContext);
- ctx->wait_ctx->self = self;
- /* valid as long as the transaction is in the HT */
- ctx->wait_ctx->transaction_id = ctx->transaction_id;
- ctx->wait_ctx->type = type;
+ /* When storing the transaction in the device, we have two options: either this
+ * is a completely new transaction, or this is a transaction that had already been
+ * previously stored (e.g. when waiting for more fragments). In the latter case,
+ * make sure we don't reset the wait context or the timeout. */
- /* don't add timeout if one already exists */
+ /* don't add timeout and setup wait context if one already exists */
if (!ctx->timeout_source) {
+ g_assert (!ctx->wait_ctx);
+ ctx->wait_ctx = g_slice_new (TransactionWaitContext);
+ ctx->wait_ctx->self = self;
+ ctx->wait_ctx->transaction_id = ctx->transaction_id;
+ ctx->wait_ctx->type = type;
ctx->timeout_source = g_timeout_source_new (timeout_ms);
g_source_set_callback (ctx->timeout_source, (GSourceFunc)transaction_timed_out, ctx->wait_ctx, NULL);
g_source_attach (ctx->timeout_source, g_main_context_get_thread_default ());