aboutsummaryrefslogtreecommitdiffstats
path: root/openbsc/src/gprs/gprs_utils.c
diff options
context:
space:
mode:
authorHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-04 14:22:13 +0200
committerHolger Hans Peter Freyther <holger@moiji-mobile.com>2014-08-04 15:00:54 +0200
commitce1b22e817584d512f82a711c02b67d12346c202 (patch)
tree5318c4557958272364f66e954359b6bbb7a36edb /openbsc/src/gprs/gprs_utils.c
parent4d9fc422d2dd17118d70a2ed25ab383614a81ede (diff)
gprs: Add testcases for the APN string/octet conversion and fix it
Create a testcase for the gprs_str_to_apn and gprs_apn_to_str routines. While writing the testcase we noticed it is possible to write more bytes than should have been allowed. This is fixed by checking that the max_len is at least 1 (needed to write the first length octet) and to do the size check before writing to the output. Modify the signature of gprs_str_to_apn to put the length/size next to the parameter that requires a size. Done with Jacob
Diffstat (limited to 'openbsc/src/gprs/gprs_utils.c')
-rw-r--r--openbsc/src/gprs/gprs_utils.c22
1 files changed, 17 insertions, 5 deletions
diff --git a/openbsc/src/gprs/gprs_utils.c b/openbsc/src/gprs/gprs_utils.c
index 8b82f2506..1a8fa4316 100644
--- a/openbsc/src/gprs/gprs_utils.c
+++ b/openbsc/src/gprs/gprs_utils.c
@@ -103,6 +103,9 @@ int gprs_msgb_resize_area(struct msgb *msg, uint8_t *area,
}
/* TODO: Move these conversion functions to a utils file. */
+/**
+ * out_str needs to have rest_chars amount of bytes or 1 whatever is bigger.
+ */
char * gprs_apn_to_str(char *out_str, const uint8_t *apn_enc, size_t rest_chars)
{
char *str = out_str;
@@ -125,13 +128,24 @@ char * gprs_apn_to_str(char *out_str, const uint8_t *apn_enc, size_t rest_chars)
return out_str;
}
-int gprs_str_to_apn(uint8_t *apn_enc, const char *str, size_t max_chars)
+int gprs_str_to_apn(uint8_t *apn_enc, size_t max_len, const char *str)
{
- uint8_t *last_len_field = apn_enc;
- int len = 1;
+ uint8_t *last_len_field;
+ int len;
+
+ /* Can we even write the length field to the output? */
+ if (max_len == 0)
+ return -1;
+
+ /* Remember where we need to put the length once we know it */
+ last_len_field = apn_enc;
+ len = 1;
apn_enc += 1;
while (str[0]) {
+ if (len >= max_len)
+ return -1;
+
if (str[0] == '.') {
*last_len_field = (apn_enc - last_len_field) - 1;
last_len_field = apn_enc;
@@ -141,8 +155,6 @@ int gprs_str_to_apn(uint8_t *apn_enc, const char *str, size_t max_chars)
apn_enc += 1;
str += 1;
len += 1;
- if (len > max_chars)
- return -1;
}
*last_len_field = (apn_enc - last_len_field) - 1;