3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-22 06:29:23 +01:00

p2putil: fix crash/remove side effect parsing adv service info

The input queue pointer was being initialized unconditionally so if
parsing fails the out pointer is still set after the queue is
destroyed. This causes a crash during cleanup.

Instead use a temporary pointer while parsing and only after parsing
has finished do we set the out pointer.

Reported-By: Alex Radocea <alex@supernetworks.org>
This commit is contained in:
James Prestwood 2024-02-29 09:07:32 -08:00 committed by Denis Kenzior
parent 816d258cab
commit 52a47c9fd4

View File

@ -541,7 +541,8 @@ static void p2p_clear_advertised_service_descriptor(void *data)
static bool extract_p2p_advertised_service_info(const uint8_t *attr, size_t len, static bool extract_p2p_advertised_service_info(const uint8_t *attr, size_t len,
void *data) void *data)
{ {
struct l_queue **out = data; struct l_queue **q = data;
struct l_queue *out = NULL;
while (len) { while (len) {
struct p2p_advertised_service_descriptor *desc; struct p2p_advertised_service_descriptor *desc;
@ -557,11 +558,11 @@ static bool extract_p2p_advertised_service_info(const uint8_t *attr, size_t len,
if (!l_utf8_validate((const char *) attr + 7, name_len, NULL)) if (!l_utf8_validate((const char *) attr + 7, name_len, NULL))
goto error; goto error;
if (!*out) if (!out)
*out = l_queue_new(); out = l_queue_new();
desc = l_new(struct p2p_advertised_service_descriptor, 1); desc = l_new(struct p2p_advertised_service_descriptor, 1);
l_queue_push_tail(*out, desc); l_queue_push_tail(out, desc);
desc->advertisement_id = l_get_le32(attr + 0); desc->advertisement_id = l_get_le32(attr + 0);
desc->wsc_config_methods = l_get_be16(attr + 4); desc->wsc_config_methods = l_get_be16(attr + 4);
@ -572,10 +573,12 @@ static bool extract_p2p_advertised_service_info(const uint8_t *attr, size_t len,
len -= 7 + name_len; len -= 7 + name_len;
} }
*q = out;
return true; return true;
error: error:
l_queue_destroy(*out, p2p_clear_advertised_service_descriptor); l_queue_destroy(out, p2p_clear_advertised_service_descriptor);
return false; return false;
} }