From ef133a7a59874cfed3e9afff896ad05505f58769 Mon Sep 17 00:00:00 2001
From: Aleksander Morgado <aleksander@aleksander.es>
Date: Fri, 13 Nov 2020 10:11:13 +0100
Subject: [PATCH] libmbim-glib,device: avoid using an already unref-ed source

We were creating the source, attaching it to the main context, and
removing our reference right away. That meant that the ownership of
the source was fully given to the main context, and so we shouldn't
have attempted to remove it from the main context later on, as it
could have already been fired and removed behind our back.

Solve this, by making sure we keep a valid source reference of our
own, and in this way we can safely destroy the source (it's fine to
destroy an already destroyed source, as long as the reference is
valid) and then fully unref it.

  ModemManager[55085]: transaction 0x6 aborted, but message is not abortable
  ModemManager[55085]: [/dev/mhi_MBIM] MBIM error: Cannot write message: Broken pipe

  (ModemManager:55085): GLib-CRITICAL **: 10:04:58.605: g_source_destroy: assertion 'g_atomic_int_get (&source->ref_count) > 0' failed

  Thread 1 "ModemManager" received signal SIGTRAP, Trace/breakpoint trap.
  0x00007ffff775ef23 in g_logv () from /usr/lib/libglib-2.0.so.0
  (gdb) bt
  #0  0x00007ffff775ef23 in g_logv () at /usr/lib/libglib-2.0.so.0
  #1  0x00007ffff775f1a0 in g_log () at /usr/lib/libglib-2.0.so.0
  #2  0x00007ffff7a8f564 in transaction_context_free (ctx=0x5555558254a0) at mbim-device.c:162
  #3  0x00007ffff79240ba in  () at /usr/lib/libgio-2.0.so.0
  #4  0x00007ffff78537b1 in g_object_unref () at /usr/lib/libgobject-2.0.so.0
  #5  0x00007ffff77512b3 in  () at /usr/lib/libglib-2.0.so.0
  #6  0x00007ffff775384a in  () at /usr/lib/libglib-2.0.so.0
  #7  0x00007ffff7756b90 in g_main_context_dispatch () at /usr/lib/libglib-2.0.so.0
  #8  0x00007ffff77a81f9 in  () at /usr/lib/libglib-2.0.so.0
  #9  0x00007ffff7756163 in g_main_loop_run () at /usr/lib/libglib-2.0.so.0
  #10 0x00005555555a0b15 in main (argc=2, argv=0x7fffffffeac8) at main.c:206
---
 src/libmbim-glib/mbim-device.c | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

diff --git a/src/libmbim-glib/mbim-device.c b/src/libmbim-glib/mbim-device.c
index 221956a7..745947bd 100644
--- a/src/libmbim-glib/mbim-device.c
+++ b/src/libmbim-glib/mbim-device.c
@@ -158,8 +158,11 @@ transaction_context_free (TransactionContext *ctx)
     if (ctx->fragments)
         mbim_message_unref (ctx->fragments);
 
-    if (ctx->timeout_source)
-        g_source_destroy (ctx->timeout_source);
+    if (ctx->timeout_source) {
+        if (!g_source_is_destroyed (ctx->timeout_source))
+            g_source_destroy (ctx->timeout_source);
+        g_source_unref (ctx->timeout_source);
+    }
 
     if (ctx->cancellable) {
         if (ctx->cancellable_id)
@@ -369,7 +372,6 @@ device_store_transaction (MbimDevice       *self,
         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 ());
-        g_source_unref (ctx->timeout_source);
     }
 
     /* Indication transactions don't have cancellable */
-- 
GitLab