diff options
author | Aleksander Morgado <aleksander@aleksander.es> | 2019-12-21 16:38:40 +0100 |
---|---|---|
committer | Aleksander Morgado <aleksander@aleksander.es> | 2019-12-21 16:40:14 +0100 |
commit | 4d5a77fe68feeef3c0aed27c865ac7645760789b (patch) | |
tree | 58b6e4c69e60e31e012496db53c415c06618fa47 | |
parent | 0d3017abc39d14d4c8356f54af81aa4dbb0f4e79 (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.c | 16 |
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 ()); |