diff options
author | Aleksander Morgado <aleksandermj@chromium.org> | 2024-03-07 13:12:20 +0000 |
---|---|---|
committer | Aleksander Morgado <aleksandermj@chromium.org> | 2024-03-12 10:15:59 +0000 |
commit | 311d6f389e74899bc1790928bb44e8361e411a1b (patch) | |
tree | f7aaf7768a1e14db7f73424beb583ef5186a021a /src | |
parent | aec461132ce42bc430c8810e43016b858d5df890 (diff) |
broadband-modem: fix crash when ports gone while setting up messaging URCs
We cannot assume that the ports may be peeked after the AT sequence
has finished, because they may have been already removed. We can store
a full port reference instead, to ensure the validity of the objects
at that time.
==19351== Process terminating with default action of signal 5 (SIGTRAP)
==19351== at 0x4A1DB24: g_logv (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6800.1)
==19351== by 0x4A1DDB2: g_log (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6800.1)
==19351== by 0x28B54E: mm_port_get_device (mm-port.c:62)
==19351== by 0x1B1247: modem_messaging_enable_unsolicited_events_secondary_ready (mm-broadband-modem.c:7373)
==19351== by 0x4BA37D8: ??? (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.6800.1)
==19351== by 0x4BA381C: ??? (in /usr/lib/x86_64-linux-gnu/libgio-2.0.so.0.6800.1)
==19351== by 0x4A157EE: g_main_context_dispatch (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6800.1)
==19351== by 0x4A68D27: ??? (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6800.1)
==19351== by 0x4A14E52: g_main_loop_run (in /usr/lib/x86_64-linux-gnu/libglib-2.0.so.0.6800.1)
==19351== by 0x176B91: main (main.c:236)
Diffstat (limited to 'src')
-rw-r--r-- | src/mm-broadband-modem.c | 85 |
1 files changed, 49 insertions, 36 deletions
diff --git a/src/mm-broadband-modem.c b/src/mm-broadband-modem.c index e175d888..fb62012d 100644 --- a/src/mm-broadband-modem.c +++ b/src/mm-broadband-modem.c @@ -7308,6 +7308,19 @@ modem_messaging_cleanup_unsolicited_events (MMIfaceModemMessaging *self, /*****************************************************************************/ /* Enable unsolicited events (SMS indications) (Messaging interface) */ +typedef struct { + MMPortSerialAt *primary; + MMPortSerialAt *secondary; +} MessagingEnableUnsolicitedEventsContext; + +static void +messaging_enable_unsolicited_events_context_free (MessagingEnableUnsolicitedEventsContext *ctx) +{ + g_clear_object (&ctx->primary); + g_clear_object (&ctx->secondary); + g_slice_free (MessagingEnableUnsolicitedEventsContext, ctx); +} + static gboolean modem_messaging_enable_unsolicited_events_finish (MMIfaceModemMessaging *self, GAsyncResult *res, @@ -7358,60 +7371,56 @@ static const MMBaseModemAtCommand cnmi_sequence[] = { }; static void -modem_messaging_enable_unsolicited_events_secondary_ready (MMBaseModem *self, +modem_messaging_enable_unsolicited_events_secondary_ready (MMBaseModem *self, GAsyncResult *res, - GTask *task) + GTask *task) { - GError *inner_error = NULL; - MMPortSerialAt *secondary; + MessagingEnableUnsolicitedEventsContext *ctx; + g_autoptr(GError) error = NULL; - secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); + ctx = g_task_get_task_data (task); /* Since the secondary is not required, we don't propagate the error anywhere */ - mm_base_modem_at_sequence_full_finish (MM_BASE_MODEM (self), res, NULL, &inner_error); - if (inner_error) { + mm_base_modem_at_sequence_full_finish (MM_BASE_MODEM (self), res, NULL, &error); + if (error) { mm_obj_dbg (self, "failed to enable messaging unsolicited events on secondary port %s: %s", - mm_port_get_device (MM_PORT (secondary)), - inner_error->message); - g_error_free (inner_error); + mm_port_get_device (MM_PORT (ctx->secondary)), + error->message); + } else { + mm_obj_dbg (self, "messaging unsolicited events enabled on secondary port %s", + mm_port_get_device (MM_PORT (ctx->secondary))); } - mm_obj_dbg (self, "messaging unsolicited events enabled on secondary port %s", - mm_port_get_device (MM_PORT (secondary))); - g_task_return_boolean (task, TRUE); g_object_unref (task); } static void -modem_messaging_enable_unsolicited_events_primary_ready (MMBaseModem *self, +modem_messaging_enable_unsolicited_events_primary_ready (MMBaseModem *self, GAsyncResult *res, - GTask *task) + GTask *task) { - GError *inner_error = NULL; - MMPortSerialAt *primary; - MMPortSerialAt *secondary; - - primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); - secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self)); + MessagingEnableUnsolicitedEventsContext *ctx; + GError *error = NULL; - mm_base_modem_at_sequence_full_finish (MM_BASE_MODEM (self), res, NULL, &inner_error); - if (inner_error) { - g_task_return_error (task, inner_error); + mm_base_modem_at_sequence_full_finish (MM_BASE_MODEM (self), res, NULL, &error); + if (error) { + g_task_return_error (task, error); g_object_unref (task); return; } + ctx = g_task_get_task_data (task); mm_obj_dbg (self, "messaging unsolicited events enabled on primary port %s", - mm_port_get_device (MM_PORT (primary))); + mm_port_get_device (MM_PORT (ctx->primary))); /* Try to enable unsolicited events for secondary port */ - if (secondary) { + if (ctx->secondary) { mm_obj_dbg (self, "enabling messaging unsolicited events on secondary port %s", - mm_port_get_device (MM_PORT (secondary))); + mm_port_get_device (MM_PORT (ctx->secondary))); mm_base_modem_at_sequence_full ( MM_BASE_MODEM (self), - secondary, + ctx->secondary, cnmi_sequence, NULL, /* response_processor_context */ NULL, /* response_processor_context_free */ @@ -7427,18 +7436,22 @@ modem_messaging_enable_unsolicited_events_primary_ready (MMBaseModem *self, static void modem_messaging_enable_unsolicited_events (MMIfaceModemMessaging *self, - GAsyncReadyCallback callback, - gpointer user_data) + GAsyncReadyCallback callback, + gpointer user_data) { - GTask *task; - MMPortSerialAt *primary; + MessagingEnableUnsolicitedEventsContext *ctx; + GTask *task; task = g_task_new (self, NULL, callback, user_data); - primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self)); + + ctx = g_slice_new0 (MessagingEnableUnsolicitedEventsContext); + ctx->primary = mm_base_modem_get_port_primary (MM_BASE_MODEM (self)); + ctx->secondary = mm_base_modem_get_port_secondary (MM_BASE_MODEM (self)); + g_task_set_task_data (task, ctx, (GDestroyNotify) messaging_enable_unsolicited_events_context_free); /* Do nothing if the modem doesn't have any AT port (e.g. it could be * a QMI modem trying to enable the parent unsolicited messages) */ - if (!primary) { + if (!ctx->primary) { g_task_return_new_error (task, MM_CORE_ERROR, MM_CORE_ERROR_FAILED, "No AT port to enable messaging unsolicited events"); g_object_unref (task); @@ -7447,10 +7460,10 @@ modem_messaging_enable_unsolicited_events (MMIfaceModemMessaging *self, /* Enable unsolicited events for primary port */ mm_obj_dbg (self, "enabling messaging unsolicited events on primary port %s", - mm_port_get_device (MM_PORT (primary))); + mm_port_get_device (MM_PORT (ctx->primary))); mm_base_modem_at_sequence_full ( MM_BASE_MODEM (self), - primary, + ctx->primary, cnmi_sequence, NULL, /* response_processor_context */ NULL, /* response_processor_context_free */ |