From f2d57282ad45ce78d21d5e3718affb3b12f28776 Mon Sep 17 00:00:00 2001 From: Jouni Malinen Date: Tue, 6 Jan 2015 17:04:24 +0200 Subject: [PATCH] D-Bus: Fix string array dict entry parser in out-of-memory case entry->strarray_value was left to point to freed memory in case os_realloc_array() failed. This resulted in the following wpa_dbus_dict_entry_clear() trying to free an already freed memory area. In addition, the separately allocated strings in the array would have been leaked in such a case. Furthermore, wpa_dbus_dict_entry_clear() was not prepared for the possibility of the initial os_calloc() call failing and entry->strarray_value being NULL without array_len being cleared to zero. That would have resulted in reading uninitialized memory and NULL pointer dereference. Signed-off-by: Jouni Malinen --- wpa_supplicant/dbus/dbus_dict_helpers.c | 28 ++++++++++++++----------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/wpa_supplicant/dbus/dbus_dict_helpers.c b/wpa_supplicant/dbus/dbus_dict_helpers.c index c9615ad8b..a0c44ebfa 100644 --- a/wpa_supplicant/dbus/dbus_dict_helpers.c +++ b/wpa_supplicant/dbus/dbus_dict_helpers.c @@ -748,18 +748,16 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array( struct wpa_dbus_dict_entry *entry) { dbus_uint32_t count = 0; - dbus_bool_t success = FALSE; char **buffer, **nbuffer; entry->strarray_value = NULL; + entry->array_len = 0; entry->array_type = DBUS_TYPE_STRING; buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE); if (buffer == NULL) return FALSE; - entry->strarray_value = buffer; - entry->array_len = 0; while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) { const char *value; char *str; @@ -769,15 +767,13 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array( buffer, count + STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE); if (nbuffer == NULL) { - os_free(buffer); wpa_printf(MSG_ERROR, "dbus: %s out of memory trying to retrieve the string array", __func__); - goto done; + goto fail; } buffer = nbuffer; } - entry->strarray_value = buffer; dbus_message_iter_get_basic(iter, &value); wpa_printf(MSG_MSGDUMP, "%s: string_array value: %s", @@ -787,12 +783,13 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array( wpa_printf(MSG_ERROR, "dbus: %s out of memory trying to duplicate the string array", __func__); - goto done; + goto fail; } - entry->strarray_value[count] = str; - entry->array_len = ++count; + buffer[count++] = str; dbus_message_iter_next(iter); } + entry->strarray_value = buffer; + entry->array_len = count; wpa_printf(MSG_MSGDUMP, "%s: string_array length %u", __func__, entry->array_len); @@ -802,10 +799,15 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array( entry->strarray_value = NULL; } - success = TRUE; + return TRUE; -done: - return success; +fail: + while (count > 0) { + count--; + os_free(buffer[count]); + } + os_free(buffer); + return FALSE; } @@ -1114,6 +1116,8 @@ void wpa_dbus_dict_entry_clear(struct wpa_dbus_dict_entry *entry) os_free(entry->bytearray_value); break; case DBUS_TYPE_STRING: + if (!entry->strarray_value) + break; for (i = 0; i < entry->array_len; i++) os_free(entry->strarray_value[i]); os_free(entry->strarray_value);