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:
parent
c61bc23aa2
commit
f2d57282ad
1 changed files with 16 additions and 12 deletions
|
@ -748,18 +748,16 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
|
||||||
struct wpa_dbus_dict_entry *entry)
|
struct wpa_dbus_dict_entry *entry)
|
||||||
{
|
{
|
||||||
dbus_uint32_t count = 0;
|
dbus_uint32_t count = 0;
|
||||||
dbus_bool_t success = FALSE;
|
|
||||||
char **buffer, **nbuffer;
|
char **buffer, **nbuffer;
|
||||||
|
|
||||||
entry->strarray_value = NULL;
|
entry->strarray_value = NULL;
|
||||||
|
entry->array_len = 0;
|
||||||
entry->array_type = DBUS_TYPE_STRING;
|
entry->array_type = DBUS_TYPE_STRING;
|
||||||
|
|
||||||
buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE);
|
buffer = os_calloc(STR_ARRAY_CHUNK_SIZE, STR_ARRAY_ITEM_SIZE);
|
||||||
if (buffer == NULL)
|
if (buffer == NULL)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
entry->strarray_value = buffer;
|
|
||||||
entry->array_len = 0;
|
|
||||||
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
|
while (dbus_message_iter_get_arg_type(iter) == DBUS_TYPE_STRING) {
|
||||||
const char *value;
|
const char *value;
|
||||||
char *str;
|
char *str;
|
||||||
|
@ -769,15 +767,13 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
|
||||||
buffer, count + STR_ARRAY_CHUNK_SIZE,
|
buffer, count + STR_ARRAY_CHUNK_SIZE,
|
||||||
STR_ARRAY_ITEM_SIZE);
|
STR_ARRAY_ITEM_SIZE);
|
||||||
if (nbuffer == NULL) {
|
if (nbuffer == NULL) {
|
||||||
os_free(buffer);
|
|
||||||
wpa_printf(MSG_ERROR,
|
wpa_printf(MSG_ERROR,
|
||||||
"dbus: %s out of memory trying to retrieve the string array",
|
"dbus: %s out of memory trying to retrieve the string array",
|
||||||
__func__);
|
__func__);
|
||||||
goto done;
|
goto fail;
|
||||||
}
|
}
|
||||||
buffer = nbuffer;
|
buffer = nbuffer;
|
||||||
}
|
}
|
||||||
entry->strarray_value = buffer;
|
|
||||||
|
|
||||||
dbus_message_iter_get_basic(iter, &value);
|
dbus_message_iter_get_basic(iter, &value);
|
||||||
wpa_printf(MSG_MSGDUMP, "%s: string_array value: %s",
|
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,
|
wpa_printf(MSG_ERROR,
|
||||||
"dbus: %s out of memory trying to duplicate the string array",
|
"dbus: %s out of memory trying to duplicate the string array",
|
||||||
__func__);
|
__func__);
|
||||||
goto done;
|
goto fail;
|
||||||
}
|
}
|
||||||
entry->strarray_value[count] = str;
|
buffer[count++] = str;
|
||||||
entry->array_len = ++count;
|
|
||||||
dbus_message_iter_next(iter);
|
dbus_message_iter_next(iter);
|
||||||
}
|
}
|
||||||
|
entry->strarray_value = buffer;
|
||||||
|
entry->array_len = count;
|
||||||
wpa_printf(MSG_MSGDUMP, "%s: string_array length %u",
|
wpa_printf(MSG_MSGDUMP, "%s: string_array length %u",
|
||||||
__func__, entry->array_len);
|
__func__, entry->array_len);
|
||||||
|
|
||||||
|
@ -802,10 +799,15 @@ static dbus_bool_t _wpa_dbus_dict_entry_get_string_array(
|
||||||
entry->strarray_value = NULL;
|
entry->strarray_value = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
success = TRUE;
|
return TRUE;
|
||||||
|
|
||||||
done:
|
fail:
|
||||||
return success;
|
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);
|
os_free(entry->bytearray_value);
|
||||||
break;
|
break;
|
||||||
case DBUS_TYPE_STRING:
|
case DBUS_TYPE_STRING:
|
||||||
|
if (!entry->strarray_value)
|
||||||
|
break;
|
||||||
for (i = 0; i < entry->array_len; i++)
|
for (i = 0; i < entry->array_len; i++)
|
||||||
os_free(entry->strarray_value[i]);
|
os_free(entry->strarray_value[i]);
|
||||||
os_free(entry->strarray_value);
|
os_free(entry->strarray_value);
|
||||||
|
|
Loading…
Reference in a new issue