From 1ee3a443b12703fd69d7ff5e93d4f330231303b0 Mon Sep 17 00:00:00 2001 From: Aleksander Morgado Date: Mon, 29 Jun 2026 16:49:48 +0000 Subject: [PATCH] sms: sanitize decoded alphanumeric SMS addresses Alphanumeric SMS addresses decoded from GSM-7 could contain control characters (like CR/LF), which could lead to AT command injection if the address is later spliced into an AT+CMGS command during stored SMS send fallback. Sanitize the decoded address by removing all control characters. Introduce a common helper mm_utils_remove_control_characters() to remove control characters from a string in-place, and add unit tests for it. https://gitlab.freedesktop.org/mobile-broadband/ModemManager/-/work_items/1062 Signed-off-by: Aleksander Morgado --- src/mm-modem-helpers.c | 21 +++++++++++++++++++++ src/mm-modem-helpers.h | 2 ++ src/mm-sms-part-3gpp.c | 3 +++ src/tests/test-modem-helpers.c | 20 ++++++++++++++++++++ 4 files changed, 46 insertions(+) diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c index ed04a329..e243e6ea 100644 --- a/src/mm-modem-helpers.c +++ b/src/mm-modem-helpers.c @@ -5936,3 +5936,24 @@ mm_dtmf_split (const gchar *dtmf) return array; } + +/*****************************************************************************/ + +void +mm_utils_remove_control_characters (gchar *str) +{ + gchar *src = str; + gchar *dst = str; + + if (!str) + return; + + while (*src) { + if (((guint8)*src) >= 0x20) { + *dst = *src; + dst++; + } + src++; + } + *dst = '\0'; +} diff --git a/src/mm-modem-helpers.h b/src/mm-modem-helpers.h index 1e3dbb12..46d3f695 100644 --- a/src/mm-modem-helpers.h +++ b/src/mm-modem-helpers.h @@ -571,6 +571,8 @@ gboolean mm_parse_supl_address (const gchar *supl, guint16 *out_port, GError **error); +void mm_utils_remove_control_characters (gchar *str); + gboolean mm_validate_cbs_channels (GArray *channels, GError **error); diff --git a/src/mm-sms-part-3gpp.c b/src/mm-sms-part-3gpp.c index d91946c7..f746079e 100644 --- a/src/mm-sms-part-3gpp.c +++ b/src/mm-sms-part-3gpp.c @@ -28,6 +28,7 @@ #include "mm-sms-part-3gpp.h" #include "mm-charsets.h" #include "mm-log.h" +#include "mm-modem-helpers.h" #define PDU_SIZE 200 @@ -141,6 +142,8 @@ sms_decode_address (const guint8 *address, unpacked = mm_charset_gsm_unpack (address, (len_digits * 4) / 7, 0, &unpacked_len); unpacked_array = g_byte_array_new_take (unpacked, unpacked_len); utf8 = mm_modem_charset_bytearray_to_utf8 (unpacked_array, MM_MODEM_CHARSET_GSM, FALSE, error); + if (utf8) + mm_utils_remove_control_characters (utf8); } else if (addrtype == SMS_NUMBER_TYPE_INTL && addrplan == SMS_NUMBER_PLAN_TELEPHONE) { /* International telphone number, format as "+1234567890" */ diff --git a/src/tests/test-modem-helpers.c b/src/tests/test-modem-helpers.c index 7684fce7..ec820802 100644 --- a/src/tests/test-modem-helpers.c +++ b/src/tests/test-modem-helpers.c @@ -4872,6 +4872,25 @@ test_at_quote_string (void *f, gpointer d) } } +static void +test_remove_control_characters (void *f, gpointer d) +{ + gchar str1[] = "hello\r\nworld"; + gchar str2[] = "no_controls"; + gchar str3[] = "\r\n\t"; + + mm_utils_remove_control_characters (str1); + g_assert_cmpstr (str1, ==, "helloworld"); + + mm_utils_remove_control_characters (str2); + g_assert_cmpstr (str2, ==, "no_controls"); + + mm_utils_remove_control_characters (str3); + g_assert_cmpstr (str3, ==, ""); + + mm_utils_remove_control_characters (NULL); +} + /*****************************************************************************/ typedef struct { @@ -5418,6 +5437,7 @@ int main (int argc, char **argv) g_test_suite_add (suite, TESTCASE (test_bcd_to_string, NULL)); g_test_suite_add (suite, TESTCASE (test_at_quote_string, NULL)); + g_test_suite_add (suite, TESTCASE (test_remove_control_characters, NULL)); g_test_suite_add (suite, TESTCASE (test_cpol_response, NULL));