From 9122bd7ec7df653cbf7443282636693470b73f89 Mon Sep 17 00:00:00 2001 From: Johan Hedberg Date: Fri, 14 Oct 2011 11:15:14 +0300 Subject: [PATCH] Fix leaks and buffer overflows in EIR parsing By calling g_utf8_validate and allocating eir->name inside the parsing loop the code was exposing itself to buffer overflows and memory leaks. This is because the check for incorrect length fields is only done after exiting the loop (if (len > HCI_MAX_EIR_LENGTH)). By only setting a pointer to the name and doing the processing after checking the length validity both issues can be avoided. --- src/eir.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/src/eir.c b/src/eir.c index d632fa815..8772191aa 100644 --- a/src/eir.c +++ b/src/eir.c @@ -68,6 +68,8 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data) uint8_t *uuid128 = NULL; uuid_t service; char *uuid_str; + const char *name = NULL; + size_t name_len; unsigned int i; eir->flags = -1; @@ -104,12 +106,8 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data) break; case EIR_NAME_SHORT: case EIR_NAME_COMPLETE: - if (g_utf8_validate((char *) &eir_data[2], - field_len - 1, NULL)) - eir->name = g_strndup((char *) &eir_data[2], - field_len - 1); - else - eir->name = g_strdup(""); + name = (const char *) &eir_data[2]; + name_len = field_len - 1; eir->name_complete = eir_data[1] == EIR_NAME_COMPLETE; break; } @@ -122,6 +120,13 @@ int eir_parse(struct eir_data *eir, uint8_t *eir_data) if (len > HCI_MAX_EIR_LENGTH) return -EINVAL; + if (name != NULL) { + if (g_utf8_validate(name, name_len, NULL)) + eir->name = g_strndup(name, name_len); + else + eir->name = g_strdup(""); + } + total = uuid16_count + uuid32_count + uuid128_count; /* No UUIDs were parsed, so skip code below */ -- 2.47.3