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)
This commit is contained in:
Aleksander Morgado
2024-03-12 10:15:59 +00:00
parent aec461132c
commit 311d6f389e
+49 -36
View File
@@ -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;
MessagingEnableUnsolicitedEventsContext *ctx;
GError *error = NULL;
primary = mm_base_modem_peek_port_primary (MM_BASE_MODEM (self));
secondary = mm_base_modem_peek_port_secondary (MM_BASE_MODEM (self));
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 */