[PATCH] Fix sporadic out-of-bounds error

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

suraev at alumni.ntnu.no suraev at alumni.ntnu.no
Thu Jan 21 15:52:40 UTC 2016


From: Max <msuraev at sysmocom.de>

This code dealing with bit shifting sometimes gets 1 byte beyond array
boundary while calculating index. This is now explicitly checked and prevented.

Ticket: OW#1198
Sponsored-by: On-Waves ehf
---
 src/gsm/gsm_utils.c | 34 +++++++++++++++++++++-------------
 1 file changed, 21 insertions(+), 13 deletions(-)

diff --git a/src/gsm/gsm_utils.c b/src/gsm/gsm_utils.c
index fad59bc..e8e452f 100644
--- a/src/gsm/gsm_utils.c
+++ b/src/gsm/gsm_utils.c
@@ -129,13 +129,11 @@ uint8_t gsm_get_octet_len(const uint8_t sept_len){
 /* GSM 03.38 6.2.1 Character unpacking */
 int gsm_7bit_decode_n_hdr(char *text, size_t n, const uint8_t *user_data, uint8_t septet_l, uint8_t ud_hdr_ind)
 {
-	int i = 0;
-	int shift = 0;
-	uint8_t c7, c8;
-	uint8_t next_is_ext = 0;
+	unsigned shift = 0;
+	uint8_t c7, c8, next_is_ext = 0, lu, ru;
+	const uint8_t maxlen = gsm_get_octet_len(septet_l);
 	const char *text_buf_begin = text;
 	const char *text_buf_end = text + n;
-	int nchars;
 
 	OSMO_ASSERT (n > 0);
 
@@ -148,12 +146,24 @@ int gsm_7bit_decode_n_hdr(char *text, size_t n, const uint8_t *user_data, uint8_
 		septet_l = septet_l - shift;
 	}
 
+	unsigned i, l, r;
 	for (i = 0; i < septet_l && text != text_buf_end - 1; i++) {
-		c7 =
-			((user_data[((i + shift) * 7 + 7) >> 3] <<
-			  (7 - (((i + shift) * 7 + 7) & 7))) |
-			 (user_data[((i + shift) * 7) >> 3] >>
-			  (((i + shift) * 7) & 7))) & 0x7f;
+
+		l = ((i + shift) * 7 + 7) >> 3;
+		r = ((i + shift) * 7) >> 3;
+
+		/* the left side index is always >= right side index
+		sometimes it even gets beyond array boundary
+		check for that explicitly and force 0 instead
+		 */
+		if (l >= maxlen)
+			lu = 0;
+		else
+			lu = user_data[l] << (7 - (((i + shift) * 7 + 7) & 7));
+
+		ru = user_data[r] >> (((i + shift) * 7) & 7);
+
+		c7 = (lu | ru) & 0x7f;
 
 		if (next_is_ext) {
 			/* this is an extension character */
@@ -169,11 +179,9 @@ int gsm_7bit_decode_n_hdr(char *text, size_t n, const uint8_t *user_data, uint8_
 		*(text++) = c8;
 	}
 
-	nchars = text - text_buf_begin;
-
 	*text = '\0';
 
-	return nchars;
+	return text - text_buf_begin;
 }
 
 int gsm_7bit_decode_n(char *text, size_t n, const uint8_t *user_data, uint8_t septet_l)
-- 
2.5.0




More information about the OpenBSC mailing list