Change in osmo-msc[master]: libmsc/db.c: fix incorrect SMS UD length truncation

Vadim Yanitskiy gerrit-no-reply at lists.osmocom.org
Sun Mar 31 11:37:54 UTC 2019


Vadim Yanitskiy has uploaded this change for review. ( https://gerrit.osmocom.org/13470


Change subject: libmsc/db.c: fix incorrect SMS UD length truncation
......................................................................

libmsc/db.c: fix incorrect SMS UD length truncation

During the compilation, clang-4.0 with -Wall writes the following:

  db.c:278:25: warning: comparison of constant 256 with expression of
               type 'uint8_t' (aka 'unsigned char') is always false
      [-Wtautological-constant-out-of-range-compare]
        if (sms->user_data_len > sizeof(sms->user_data))
            ~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~
  db.c:424:25: warning: comparison of constant 256 with expression of
               type 'uint8_t' (aka 'unsigned char') is always false
      [-Wtautological-constant-out-of-range-compare]
        if (sms->user_data_len > sizeof(sms->user_data))
            ~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~
  db.c:780:25: warning: comparison of constant 256 with expression of
               type 'uint8_t' (aka 'unsigned char') is always false
      [-Wtautological-constant-out-of-range-compare]
        if (sms->user_data_len > sizeof(sms->user_data))
            ~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~~~~~~~~~~~~~

Given that 'sizeof(sms->user_data)' is 256 (see SMS_TEXT_SIZE), and
'sms->user_data_len' is of type 'uint8_t', these warnings make sense.

The value of 'sms->user_data_len' is fetched from the database:

  sms->user_data_len = dbi_result_get_field_length(result, "user_data");

and this is where the problem is. As per the libdbi's documentation
(see 3.5.3), dbi_result_get_field_length() returns the length in
bytes of the value stored in the specified field:

  unsigned int dbi_result_get_field_length(dbi_result Result,
                                           const char *fieldname)

so 'unsigned int' is assigned to 'uint8_t', what would lead to
integer overflow if the value is grather than 0xff. As a result,
the truncation of 'user_data' would be done incorrectly, e.g.
if the length of 'user_data' is 282, only 26 bytes would be
fetched instead of 256.

Let's avoid such direct assignment, and use a separate variable.

Change-Id: Ibbd588545e1a4817504c806a3d02cf59d5938ee2
Related: OS#3684
---
M src/libmsc/db.c
1 file changed, 15 insertions(+), 9 deletions(-)



  git pull ssh://gerrit.osmocom.org:29418/osmo-msc refs/changes/70/13470/1

diff --git a/src/libmsc/db.c b/src/libmsc/db.c
index b5e7ad8..55a87bb 100644
--- a/src/libmsc/db.c
+++ b/src/libmsc/db.c
@@ -236,6 +236,7 @@
 	long long unsigned int sender_id;
 	const char *text, *daddr;
 	const unsigned char *user_data;
+	unsigned int user_data_len;
 	char buf[32];
 	char *quoted;
 	dbi_result result2;
@@ -273,10 +274,11 @@
 	if (daddr)
 		OSMO_STRLCPY_ARRAY(sms->dst.addr, daddr);
 
-	sms->user_data_len = dbi_result_get_field_length(result, "user_data");
+	user_data_len = dbi_result_get_field_length(result, "user_data");
 	user_data = dbi_result_get_binary(result, "user_data");
-	if (sms->user_data_len > sizeof(sms->user_data))
-		sms->user_data_len = (uint8_t) sizeof(sms->user_data);
+	if (user_data_len > sizeof(sms->user_data))
+		user_data_len = (uint8_t) sizeof(sms->user_data);
+	sms->user_data_len = user_data_len;
 	memcpy(sms->user_data, user_data, sms->user_data_len);
 
 	text = dbi_result_get_string(result, "text");
@@ -395,6 +397,7 @@
 {
 	struct gsm_sms *sms = sms_alloc();
 	const unsigned char *user_data;
+	unsigned int user_data_len;
 	const char *text, *addr;
 
 	if (!sms)
@@ -419,10 +422,11 @@
 	sms->dst.ton = dbi_result_get_ulonglong(result, "dest_ton");
 	sms->dst.npi = dbi_result_get_ulonglong(result, "dest_npi");
 
-	sms->user_data_len = dbi_result_get_field_length(result, "user_data");
+	user_data_len = dbi_result_get_field_length(result, "user_data");
 	user_data = dbi_result_get_binary(result, "user_data");
-	if (sms->user_data_len > sizeof(sms->user_data))
-		sms->user_data_len = (uint8_t) sizeof(sms->user_data);
+	if (user_data_len > sizeof(sms->user_data))
+		user_data_len = (uint8_t) sizeof(sms->user_data);
+	sms->user_data_len = user_data_len;
 	memcpy(sms->user_data, user_data, sms->user_data_len);
 
 	text = dbi_result_get_string(result, "text");
@@ -744,6 +748,7 @@
 	struct gsm_sms *sms = sms_alloc();
 	const char *text, *daddr, *saddr;
 	const unsigned char *user_data;
+	unsigned int user_data_len;
 	time_t validity_timestamp;
 
 	if (!sms)
@@ -777,10 +782,11 @@
 	if (saddr)
 		OSMO_STRLCPY_ARRAY(sms->src.addr, saddr);
 
-	sms->user_data_len = dbi_result_get_field_length(result, "user_data");
+	user_data_len = dbi_result_get_field_length(result, "user_data");
 	user_data = dbi_result_get_binary(result, "user_data");
-	if (sms->user_data_len > sizeof(sms->user_data))
-		sms->user_data_len = (uint8_t) sizeof(sms->user_data);
+	if (user_data_len > sizeof(sms->user_data))
+		user_data_len = (uint8_t) sizeof(sms->user_data);
+	sms->user_data_len = user_data_len;
 	memcpy(sms->user_data, user_data, sms->user_data_len);
 
 	text = dbi_result_get_string(result, "text");

-- 
To view, visit https://gerrit.osmocom.org/13470
To unsubscribe, or for help writing mail filters, visit https://gerrit.osmocom.org/settings

Gerrit-Project: osmo-msc
Gerrit-Branch: master
Gerrit-MessageType: newchange
Gerrit-Change-Id: Ibbd588545e1a4817504c806a3d02cf59d5938ee2
Gerrit-Change-Number: 13470
Gerrit-PatchSet: 1
Gerrit-Owner: Vadim Yanitskiy <axilirator at gmail.com>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.osmocom.org/pipermail/gerrit-log/attachments/20190331/758ea40a/attachment-0001.html>


More information about the gerrit-log mailing list