Crash with Fibocom L830-EB in mm-port-serial.c / common_input_available
Hello, I'm seeing some crashes with a Fibocom L830-EB, on desktop (core i9, debian testing) and arm (STM32MP157, openstlinux), using versions 1.18.6 or latest from git (8ab31cf0).
Modem firmware version is 18300.1008.00.01.01.16
How to reproduce:
- Obtain an Internet connection using NetworkManager + ModemManager
- Unplug the modem
- Plug the modem
Pretty often (nearly always), during the probing phase, ModemManager reads some data from ttyACM1 that make it crash. I'm not sure why, but using minicom or dd, I can see that indeed the modem is writing a lot of data on this port (might be a firmware bug, I'm not sure, and I still didn't find how to update the firmware).
I'm having the following log:
(ModemManager:9658): GLib-CRITICAL **: 07:58:57.502: g_byte_array_remove_range: assertion 'index_ + length <= array->len' failed
(ModemManager:9658): GLib-GObject-CRITICAL **: 07:58:57.503: g_object_ref: assertion 'G_IS_OBJECT (object)' failed
I checked a bit the code, and here's what I saw: In mm-port-serial.c, l.1021, we have the following sequence:
/* Make sure the response doesn't grow too long */
if ((self->priv->response->len > SERIAL_BUF_SIZE) && self->priv->spew_control) {
/* Notify listeners and then trim the buffer */
g_signal_emit (self, signals[BUFFER_FULL], 0, self->priv->response);
g_byte_array_remove_range (self->priv->response, 0, (SERIAL_BUF_SIZE / 2));
}
The first assertion is triggered by the last line of this block. Indeed, after the signal is emitted, self->priv->response->len
is 0 (while it is not 0 before emitting the signal).
I checked the receivers of the signal, and it appears that the function serial_buffer_full
in mm-port-probe.c is involved.
The function looks like:
static void
serial_buffer_full (MMPortSerial *serial,
GByteArray *buffer,
MMPortProbe *self)
{
PortProbeRunContext *ctx;
if (!is_non_at_response (buffer->data, buffer->len))
return;
g_assert (self->priv->task);
ctx = g_task_get_task_data (self->priv->task);
mm_obj_dbg (self, "serial buffer full");
/* Don't explicitly close the AT port, just end the AT probing
* (or custom init probing) */
mm_port_probe_set_result_at (self, FALSE);
g_cancellable_cancel (ctx->at_probing_cancellable);
}
The crash systematically occurs when is_non_at_response
returns false. If I force serial_buffer_full
to return, the crash disappears.
In case it helps, I'm attaching the gdb dump of a buffer that triggers the crash. buffer_dump.txt
Note: to make the cross compilation easier, I configured the build with options --without-mbim
and --without-qmi
. I'm not sure if this can have an impact on the issue.
Let me know if more information is needed.