quectel: fix crash when parsing +CTZU=? response

The logic should consider that mm_parse_uint_list() may return NULL
without setting the output GError, in the case where an empty string
is given.

This should ideally be changed in the mm_parse_uint_list() itself, but
that approach is not trivial as the method is being used in multiple
different places.

This change exclusively tries to solve this crash.

  0x000057435d315eca (ModemManager - mm-shared-quectel.c: 1060)	ctzu_test_ready
  0x00007eea3d019e86 (libgio-2.0.so.0 - gtask.c: 1309)	g_task_return_now
  0x00007eea3d018e50 (libgio-2.0.so.0 - gtask.c: 1378)	g_task_return
  0x000057435d268eab (ModemManager - mm-base-modem-at.c: 544)	at_command_ready
  0x00007eea3d019e86 (libgio-2.0.so.0 - gtask.c: 1309)	g_task_return_now
  0x00007eea3d018e50 (libgio-2.0.so.0 - gtask.c: 1378)	g_task_return
  0x000057435d318a18 (ModemManager - mm-port-serial-at.c: 350)	serial_command_ready
  0x00007eea3d019e86 (libgio-2.0.so.0 - gtask.c: 1309)	g_task_return_now
  0x00007eea3d018e50 (libgio-2.0.so.0 - gtask.c: 1378)	g_task_return
  0x000057435d31c7bd (ModemManager - mm-port-serial.c: 734)	port_serial_got_response
  0x000057435d31cc3e (ModemManager - mm-port-serial.c: 911)	parse_response_buffer
  0x000057435d31cc3e (ModemManager - mm-port-serial.c: 1028)	common_input_available
  0x00007eea3d16591b (libglib-2.0.so.0 - gmain.c: 3460)	g_main_dispatch
  0x00007eea3d16591b (libglib-2.0.so.0 - gmain.c: 4200)	g_main_context_dispatch
  0x00007eea3d165c37 (libglib-2.0.so.0 - gmain.c: 4276)	g_main_context_iterate
  0x00007eea3d165eb5 (libglib-2.0.so.0 - gmain.c: 4479)	g_main_loop_run
  0x000057435d25f5bf (ModemManager - main.c: 236)	main
  0x00007eea3c980705 (libc.so.6 - libc_start_call_main.h: 58)	__libc_start_call_main
  0x00007eea3c9807c1 (libc.so.6 - libc-start.c: 360)	__libc_start_main_impl
  0x000057435d25ef10 (ModemManager + 0x000b3f10)	_start
  0x00007ffcc0b5d517
This commit is contained in:
Aleksander Morgado
2024-10-29 08:39:05 +00:00
parent 5056ee0d7b
commit cb6a56fa0c
2 changed files with 31 additions and 14 deletions
+11 -5
View File
@@ -31,9 +31,10 @@ mm_quectel_parse_ctzu_test_response (const gchar *response,
gboolean *supports_enable_update_rtc,
GError **error)
{
g_auto(GStrv) split = NULL;
g_autoptr(GArray) modes = NULL;
guint i;
g_auto(GStrv) split = NULL;
g_autoptr(GArray) modes = NULL;
GError *inner_error = NULL;
guint i;
/*
* Response may be:
@@ -57,9 +58,14 @@ mm_quectel_parse_ctzu_test_response (const gchar *response,
return FALSE;
}
modes = mm_parse_uint_list (split[0], error);
modes = mm_parse_uint_list (split[0], &inner_error);
if (inner_error) {
g_propagate_prefixed_error (error, inner_error, "Failed to parse integer list in +CTZU test response: ");
return FALSE;
}
if (!modes) {
g_prefix_error (error, "Failed to parse integer list in +CTZU test response: ");
g_set_error (error, MM_CORE_ERROR, MM_CORE_ERROR_FAILED,
"Unexpected empty integer list in +CTZU test response: ");
return FALSE;
}
@@ -34,18 +34,23 @@ typedef struct {
gboolean expect_supports_disable;
gboolean expect_supports_enable;
gboolean expect_supports_enable_update_rtc;
gboolean expect_error;
} TestCtzuResponse;
static const TestCtzuResponse test_ctzu_response[] = {
{ "+CTZU: (0,1)", TRUE, TRUE, FALSE },
{ "+CTZU: (0,1,3)", TRUE, TRUE, TRUE },
{ "+CTZU: ", FALSE, FALSE, FALSE, TRUE },
{ "+CTZU: ()", FALSE, FALSE, FALSE, TRUE },
{ "+CTZU: (,)", FALSE, FALSE, FALSE, TRUE },
{ "+CTZU: (0,1)", TRUE, TRUE, FALSE, FALSE },
{ "+CTZU: (0,1,3)", TRUE, TRUE, TRUE, FALSE },
};
static void
common_test_ctzu (const gchar *response,
gboolean expect_supports_disable,
gboolean expect_supports_enable,
gboolean expect_supports_enable_update_rtc)
gboolean expect_supports_enable_update_rtc,
gboolean expect_error)
{
g_autoptr(GError) error = NULL;
gboolean res;
@@ -59,12 +64,17 @@ common_test_ctzu (const gchar *response,
&supports_enable,
&supports_enable_update_rtc,
&error);
g_assert_no_error (error);
g_assert (res);
if (expect_error) {
g_assert (error);
g_assert (!res);
} else {
g_assert_no_error (error);
g_assert (res);
g_assert_cmpuint (expect_supports_disable, ==, supports_disable);
g_assert_cmpuint (expect_supports_enable, ==, supports_enable);
g_assert_cmpuint (expect_supports_enable_update_rtc, ==, supports_enable_update_rtc);
g_assert_cmpuint (expect_supports_disable, ==, supports_disable);
g_assert_cmpuint (expect_supports_enable, ==, supports_enable);
g_assert_cmpuint (expect_supports_enable_update_rtc, ==, supports_enable_update_rtc);
}
}
static void
@@ -76,7 +86,8 @@ test_ctzu (void)
common_test_ctzu (test_ctzu_response[i].response,
test_ctzu_response[i].expect_supports_disable,
test_ctzu_response[i].expect_supports_enable,
test_ctzu_response[i].expect_supports_enable_update_rtc);
test_ctzu_response[i].expect_supports_enable_update_rtc,
test_ctzu_response[i].expect_error);
}
/*****************************************************************************/