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 <j@w1.fi>
This commit is contained in:
Jouni Malinen 2015-01-06 17:04:24 +02:00
parent c61bc23aa2
commit f2d57282ad

View file

@ -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);