310 lines
13 KiB
Diff
310 lines
13 KiB
Diff
From ac243f94676695d88e861d225e98ec5bb3c2861e Mon Sep 17 00:00:00 2001
|
|
From: Carlo Lobrano <c.lobrano@gmail.com>
|
|
Date: Fri, 8 Apr 2022 11:46:11 +0200
|
|
Subject: [PATCH] sms: prevent crash if date is out of range
|
|
|
|
g_date_time_new, and g_date_time_new_utc return NULL if inputs are out
|
|
of range, and currently mm_new_iso8601_time passes the GDateTime created
|
|
by those two functions to date_time_format_iso8601 without checking for
|
|
NULL values, causing a g_date_time_format_iso8601 crash if PDU data is
|
|
corrupted with wrong date.
|
|
|
|
To prevent this, mm_new_iso8601_time now can return NULL and set a new
|
|
GError if GDateTime created by g_date_time_new is NULL.
|
|
|
|
Fixes #546
|
|
---
|
|
.../cinterion/mm-modem-helpers-cinterion.c | 7 +++--
|
|
plugins/huawei/mm-modem-helpers-huawei.c | 19 ++++++++----
|
|
plugins/icera/mm-broadband-modem-icera.c | 7 +++--
|
|
plugins/novatel/mm-broadband-modem-novatel.c | 4 +--
|
|
plugins/sierra/mm-broadband-modem-sierra.c | 2 +-
|
|
src/mm-modem-helpers.c | 8 +++--
|
|
src/mm-sms-part-3gpp.c | 30 ++++++++++++++-----
|
|
7 files changed, 91 insertions(+), 26 deletions(-)
|
|
|
|
diff --git a/src/mm-common-helpers.c b/src/mm-common-helpers.c
|
|
index b7883b265..085177b7b 100644
|
|
--- a/src/mm-modem-helpers.c
|
|
+++ b/src/mm-modem-helpers.c
|
|
@@ -1769,7 +1769,8 @@ mm_new_iso8601_time (guint year,
|
|
guint minute,
|
|
guint second,
|
|
gboolean have_offset,
|
|
- gint offset_minutes)
|
|
+ gint offset_minutes,
|
|
+ GError **error)
|
|
{
|
|
GString *str;
|
|
|
|
diff --git a/libmm-glib/mm-common-helpers.h b/libmm-glib/mm-common-helpers.h
|
|
index d444012c0..490f882da 100644
|
|
--- a/src/mm-modem-helpers.h
|
|
+++ b/src/mm-modem-helpers.h
|
|
@@ -216,7 +216,8 @@ gchar *mm_new_iso8601_time (guint year,
|
|
guint minute,
|
|
guint second,
|
|
gboolean have_offset,
|
|
- gint offset_minutes);
|
|
+ gint offset_minutes,
|
|
+ GError **error);
|
|
|
|
GArray *mm_filter_supported_modes (const GArray *all,
|
|
const GArray *supported_combinations,
|
|
diff --git a/plugins/cinterion/mm-modem-helpers-cinterion.c b/plugins/cinterion/mm-modem-helpers-cinterion.c
|
|
index f8cec8258..a75eb5304 100644
|
|
--- a/plugins/cinterion/mm-modem-helpers-cinterion.c
|
|
+++ b/plugins/cinterion/mm-modem-helpers-cinterion.c
|
|
@@ -1201,6 +1201,7 @@ mm_cinterion_parse_ctzu_urc (GMatchInfo *match_info,
|
|
MMNetworkTimezone **tzp,
|
|
GError **error)
|
|
{
|
|
+ gboolean ret = TRUE;
|
|
guint year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0, dst = 0;
|
|
gint tz = 0;
|
|
|
|
@@ -1229,7 +1230,9 @@ mm_cinterion_parse_ctzu_urc (GMatchInfo *match_info,
|
|
/* Return ISO-8601 format date/time string */
|
|
*iso8601p = mm_new_iso8601_time (year, month, day, hour,
|
|
minute, second,
|
|
- TRUE, tz * 15);
|
|
+ TRUE, tz * 15,
|
|
+ error);
|
|
+ ret = (*iso8601p != NULL);
|
|
}
|
|
|
|
if (tzp) {
|
|
@@ -1245,7 +1248,7 @@ mm_cinterion_parse_ctzu_urc (GMatchInfo *match_info,
|
|
if (tzp && mm_get_uint_from_match_info (match_info, 8, &dst))
|
|
mm_network_timezone_set_dst_offset (*tzp, dst * 60);
|
|
|
|
- return TRUE;
|
|
+ return ret;
|
|
}
|
|
|
|
/*****************************************************************************/
|
|
diff --git a/plugins/huawei/mm-modem-helpers-huawei.c b/plugins/huawei/mm-modem-helpers-huawei.c
|
|
index b85484183..3ded62379 100644
|
|
--- a/plugins/huawei/mm-modem-helpers-huawei.c
|
|
+++ b/plugins/huawei/mm-modem-helpers-huawei.c
|
|
@@ -1228,6 +1228,9 @@ gboolean mm_huawei_parse_nwtime_response (const gchar *response,
|
|
mm_get_uint_from_match_info (match_info, 6, &second) &&
|
|
mm_get_int_from_match_info (match_info, 7, &tz) &&
|
|
mm_get_uint_from_match_info (match_info, 8, &dt)) {
|
|
+
|
|
+ ret = TRUE;
|
|
+
|
|
/* adjust year */
|
|
if (year < 100)
|
|
year += 2000;
|
|
@@ -1240,7 +1243,9 @@ gboolean mm_huawei_parse_nwtime_response (const gchar *response,
|
|
/* Return ISO-8601 format date/time string */
|
|
*iso8601p = mm_new_iso8601_time (year, month, day, hour,
|
|
minute, second,
|
|
- TRUE, (tz * 15) + (dt * 60));
|
|
+ TRUE, (tz * 15) + (dt * 60),
|
|
+ error);
|
|
+ ret = (*iso8601p != NULL);
|
|
}
|
|
if (tzp) {
|
|
*tzp = mm_network_timezone_new ();
|
|
@@ -1248,7 +1253,6 @@ gboolean mm_huawei_parse_nwtime_response (const gchar *response,
|
|
mm_network_timezone_set_dst_offset (*tzp, dt * 60);
|
|
}
|
|
|
|
- ret = TRUE;
|
|
} else {
|
|
g_set_error_literal (error,
|
|
MM_CORE_ERROR,
|
|
@@ -1312,14 +1316,19 @@ gboolean mm_huawei_parse_time_response (const gchar *response,
|
|
mm_get_uint_from_match_info (match_info, 4, &hour) &&
|
|
mm_get_uint_from_match_info (match_info, 5, &minute) &&
|
|
mm_get_uint_from_match_info (match_info, 6, &second)) {
|
|
+ ret = TRUE;
|
|
+
|
|
/* adjust year */
|
|
if (year < 100)
|
|
year += 2000;
|
|
+
|
|
/* Return ISO-8601 format date/time string */
|
|
- if (iso8601p)
|
|
+ if (iso8601p) {
|
|
*iso8601p = mm_new_iso8601_time (year, month, day, hour,
|
|
- minute, second, FALSE, 0);
|
|
- ret = TRUE;
|
|
+ minute, second, FALSE, 0,
|
|
+ error);
|
|
+ ret = (*iso8601p != NULL);
|
|
+ }
|
|
} else {
|
|
g_set_error_literal (error,
|
|
MM_CORE_ERROR,
|
|
diff --git a/plugins/icera/mm-broadband-modem-icera.c b/plugins/icera/mm-broadband-modem-icera.c
|
|
index 26016c4c4..96cb45fa4 100644
|
|
--- a/plugins/icera/mm-broadband-modem-icera.c
|
|
+++ b/plugins/icera/mm-broadband-modem-icera.c
|
|
@@ -1569,6 +1569,7 @@ parse_tlts_query_reply (const gchar *response,
|
|
MMNetworkTimezone **tz,
|
|
GError **error)
|
|
{
|
|
+ gboolean ret = TRUE;
|
|
gint year;
|
|
gint month;
|
|
gint day;
|
|
@@ -1649,11 +1650,13 @@ parse_tlts_query_reply (const gchar *response,
|
|
g_date_time_get_minute (adjusted),
|
|
g_date_time_get_second (adjusted),
|
|
TRUE,
|
|
- offset);
|
|
+ offset,
|
|
+ error);
|
|
+ ret = (*iso8601 != NULL);
|
|
}
|
|
|
|
g_date_time_unref (adjusted);
|
|
- return TRUE;
|
|
+ return ret;
|
|
}
|
|
|
|
static MMNetworkTimezone *
|
|
diff --git a/plugins/novatel/mm-broadband-modem-novatel.c b/plugins/novatel/mm-broadband-modem-novatel.c
|
|
index 4eba0e168..1cc88e906 100644
|
|
--- a/plugins/novatel/mm-broadband-modem-novatel.c
|
|
+++ b/plugins/novatel/mm-broadband-modem-novatel.c
|
|
@@ -1431,13 +1431,13 @@ parse_nwltime_reply (const char *response,
|
|
mm_get_int_from_match_info (match_info, 8, &utc_offset)) {
|
|
|
|
result = mm_new_iso8601_time (year, month, day, hour, minute, second,
|
|
- TRUE, utc_offset * 60);
|
|
+ TRUE, utc_offset * 60, error);
|
|
if (out_tz) {
|
|
*out_tz = mm_network_timezone_new ();
|
|
mm_network_timezone_set_offset (*out_tz, utc_offset * 60);
|
|
}
|
|
|
|
- success = TRUE;
|
|
+ success = (result != NULL);
|
|
} else {
|
|
g_set_error_literal (error,
|
|
MM_CORE_ERROR,
|
|
diff --git a/plugins/sierra/mm-broadband-modem-sierra.c b/plugins/sierra/mm-broadband-modem-sierra.c
|
|
index 518f8adbc..3ac20808f 100644
|
|
--- a/plugins/sierra/mm-broadband-modem-sierra.c
|
|
+++ b/plugins/sierra/mm-broadband-modem-sierra.c
|
|
@@ -1656,7 +1656,7 @@ parse_time (const gchar *response,
|
|
mm_get_uint_from_match_info (match_info, 4, &hour) &&
|
|
mm_get_uint_from_match_info (match_info, 5, &minute) &&
|
|
mm_get_uint_from_match_info (match_info, 6, &second)) {
|
|
- result = mm_new_iso8601_time (year, month, day, hour, minute, second, FALSE, 0);
|
|
+ result = mm_new_iso8601_time (year, month, day, hour, minute, second, FALSE, 0, error);
|
|
} else {
|
|
g_set_error (error,
|
|
MM_CORE_ERROR,
|
|
diff --git a/src/mm-modem-helpers.c b/src/mm-modem-helpers.c
|
|
index 72714ab9a..5e58ba9dd 100644
|
|
--- a/src/mm-modem-helpers.c
|
|
+++ b/src/mm-modem-helpers.c
|
|
@@ -5112,15 +5112,17 @@ mm_parse_cclk_response (const char *response,
|
|
mm_network_timezone_set_offset (*tzp, tz * 15);
|
|
}
|
|
|
|
+ ret = TRUE;
|
|
+
|
|
if (iso8601p) {
|
|
/* Return ISO-8601 format date/time string */
|
|
*iso8601p = mm_new_iso8601_time (year, month, day, hour,
|
|
minute, second,
|
|
- TRUE, (tz * 15));
|
|
+ TRUE, (tz * 15),
|
|
+ error);
|
|
+ ret = (*iso8601p != NULL);
|
|
}
|
|
|
|
- ret = TRUE;
|
|
-
|
|
out:
|
|
g_match_info_free (match_info);
|
|
g_regex_unref (r);
|
|
diff --git a/src/mm-sms-part-3gpp.c b/src/mm-sms-part-3gpp.c
|
|
index bfae03a84..aeb9decb0 100644
|
|
--- a/src/mm-sms-part-3gpp.c
|
|
+++ b/src/mm-sms-part-3gpp.c
|
|
@@ -161,7 +161,8 @@ sms_decode_address (const guint8 *address,
|
|
}
|
|
|
|
static gchar *
|
|
-sms_decode_timestamp (const guint8 *timestamp)
|
|
+sms_decode_timestamp (const guint8 *timestamp,
|
|
+ GError **error)
|
|
{
|
|
/* ISO8601 format: YYYY-MM-DDTHH:MM:SS+HHMM */
|
|
guint year, month, day, hour, minute, second;
|
|
@@ -179,7 +180,7 @@ sms_decode_timestamp (const guint8 *timestamp)
|
|
offset_minutes = -1 * offset_minutes;
|
|
|
|
return mm_new_iso8601_time (year, month, day, hour,
|
|
- minute, second, TRUE, offset_minutes);
|
|
+ minute, second, TRUE, offset_minutes, error);
|
|
}
|
|
|
|
static MMSmsEncoding
|
|
@@ -509,6 +510,7 @@ mm_sms_part_3gpp_new_from_binary_pdu (guint index,
|
|
/* Get timestamps and indexes for TP-PID, TP-DCS and TP-UDL/TP-UD */
|
|
|
|
if (pdu_type == SMS_TP_MTI_SMS_DELIVER) {
|
|
+ gchar *str = NULL;
|
|
PDU_SIZE_CHECK (offset + 9,
|
|
"cannot read PID/DCS/Timestamp"); /* 1+1+7=9 */
|
|
|
|
@@ -519,8 +521,13 @@ mm_sms_part_3gpp_new_from_binary_pdu (guint index,
|
|
tp_dcs_offset = offset++;
|
|
|
|
/* ------ Timestamp (7 bytes) ------ */
|
|
+ str = sms_decode_timestamp (&pdu[offset], error);
|
|
+ if (!str) {
|
|
+ mm_sms_part_free (sms_part);
|
|
+ return NULL;
|
|
+ }
|
|
mm_sms_part_take_timestamp (sms_part,
|
|
- sms_decode_timestamp (&pdu[offset]));
|
|
+ str);
|
|
offset += 7;
|
|
|
|
tp_user_data_len_offset = offset;
|
|
@@ -564,6 +571,7 @@ mm_sms_part_3gpp_new_from_binary_pdu (guint index,
|
|
tp_user_data_len_offset = offset;
|
|
}
|
|
else if (pdu_type == SMS_TP_MTI_SMS_STATUS_REPORT) {
|
|
+ gchar *str = NULL;
|
|
/* We have 2 timestamps in status report PDUs:
|
|
* first, the timestamp for when the PDU was received in the SMSC
|
|
* second, the timestamp for when the PDU was forwarded by the SMSC
|
|
@@ -571,13 +579,21 @@ mm_sms_part_3gpp_new_from_binary_pdu (guint index,
|
|
PDU_SIZE_CHECK (offset + 15, "cannot read Timestamps/TP-STATUS"); /* 7+7+1=15 */
|
|
|
|
/* ------ Timestamp (7 bytes) ------ */
|
|
- mm_sms_part_take_timestamp (sms_part,
|
|
- sms_decode_timestamp (&pdu[offset]));
|
|
+ str = sms_decode_timestamp (&pdu[offset], error);
|
|
+ if (!str) {
|
|
+ mm_sms_part_free (sms_part);
|
|
+ return NULL;
|
|
+ }
|
|
+ mm_sms_part_take_timestamp (sms_part, str);
|
|
offset += 7;
|
|
|
|
/* ------ Discharge Timestamp (7 bytes) ------ */
|
|
- mm_sms_part_take_discharge_timestamp (sms_part,
|
|
- sms_decode_timestamp (&pdu[offset]));
|
|
+ str = sms_decode_timestamp (&pdu[offset], error);
|
|
+ if (!str) {
|
|
+ mm_sms_part_free (sms_part);
|
|
+ return NULL;
|
|
+ }
|
|
+ mm_sms_part_take_discharge_timestamp (sms_part, str);
|
|
offset += 7;
|
|
|
|
/* ----- TP-STATUS (1 byte) ------ */
|
|
--
|
|
GitLab
|