From 4aaea370228fdc873ac34c3fa542088a2893f2db Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Sun, 24 Jul 2022 14:46:10 +0200 Subject: base-sms: fix segfault when storing already sent messages The internal list of parts in the base SMS object is created either when the message is sent or when the message is stored. The daemon should not expect the list of SMS parts to be empty upon a store() operation requested via DBus, as the list of parts may have already been created during send(). Fixes https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/issues/598 --- src/mm-base-sms.c | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) (limited to 'src') diff --git a/src/mm-base-sms.c b/src/mm-base-sms.c index 1c291daf..e84ece62 100644 --- a/src/mm-base-sms.c +++ b/src/mm-base-sms.c @@ -361,31 +361,37 @@ handle_store_ready (MMBaseSms *self, } static gboolean -prepare_sms_to_be_stored (MMBaseSms *self, - GError **error) +prepare_sms_to_be_stored (MMBaseSms *self, + GError **error) { - GList *l; - guint8 reference; - - g_assert (self->priv->parts == NULL); - - /* Look for a valid multipart reference to use. When storing, we need to - * check whether we have already stored multipart SMS with the same - * reference and destination number */ - reference = (mm_iface_modem_messaging_get_local_multipart_reference ( - MM_IFACE_MODEM_MESSAGING (self->priv->modem), - mm_gdbus_sms_get_number (MM_GDBUS_SMS (self)), - error)); - if (!reference || - !generate_submit_pdus (self, error)) { - g_prefix_error (error, "Cannot prepare SMS to be stored: "); + /* Create parts if we did not create them already before (e.g. when + * sending) */ + if (!self->priv->parts && !generate_submit_pdus (self, error)) { + g_prefix_error (error, "Cannot create submit PDUs: "); return FALSE; } /* If the message is a multipart message, we need to set a proper * multipart reference. When sending a message which wasn't stored - * yet, we can just get a random multipart reference. */ + * yet, we chose a random multipart reference, but that doesn't work + * when storing locally, as we could collide with the references used + * in other existing messages. */ if (self->priv->is_multipart) { + GList *l; + guint8 reference; + + /* Look for a valid multipart reference to use. When storing, we need to + * check whether we have already stored multipart SMS with the same + * reference and destination number */ + reference = mm_iface_modem_messaging_get_local_multipart_reference ( + MM_IFACE_MODEM_MESSAGING (self->priv->modem), + mm_gdbus_sms_get_number (MM_GDBUS_SMS (self)), + error); + if (!reference) { + g_prefix_error (error, "Cannot get local multipart reference: "); + return FALSE; + } + self->priv->multipart_reference = reference; for (l = self->priv->parts; l; l = g_list_next (l)) { mm_sms_part_set_concat_reference ((MMSmsPart *)l->data, @@ -438,6 +444,7 @@ handle_store_auth_ready (MMBaseModem *modem, /* Prepare the SMS to be stored, creating the PDU list if required */ if (!prepare_sms_to_be_stored (ctx->self, &error)) { + g_prefix_error (&error, "Cannot prepare SMS to be stored: "); g_dbus_method_invocation_take_error (ctx->invocation, error); handle_store_context_free (ctx); return; @@ -546,11 +553,12 @@ prepare_sms_to_be_sent (MMBaseSms *self, { GList *l; + /* If we created the parts when storing, we're fine already */ if (self->priv->parts) return TRUE; if (!generate_submit_pdus (self, error)) { - g_prefix_error (error, "Cannot prepare SMS to be sent: "); + g_prefix_error (error, "Cannot create submit PDUs: "); return FALSE; } @@ -606,6 +614,7 @@ handle_send_auth_ready (MMBaseModem *modem, /* Prepare the SMS to be sent, creating the PDU list if required */ if (!prepare_sms_to_be_sent (ctx->self, &error)) { + g_prefix_error (&error, "Cannot prepare SMS to be sent: "); g_dbus_method_invocation_take_error (ctx->invocation, error); handle_send_context_free (ctx); return; -- cgit v1.2.3-70-g09d2