greybus: audio: bound the topology section sizes against the fetched size

gb_audio_gb_get_topology() fetches a topology blob of a module-supplied
size, and gbaudio_tplg_parse_data() then walks it by adding the
module-supplied size_dais, size_controls and size_widgets fields to
form the control, widget and route section offsets. Those le32 sizes
are never checked against the fetched blob, so a module reporting a
small topology size but large section sizes makes the offsets point
past the allocation, and parsing reads out of bounds.

Reject a topology whose section sizes do not fit within the fetched
size before it is parsed.

Fixes: 184992e305 ("greybus: audio: Add Greybus Audio Device Class Protocol helper routines")
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Link: https://patch.msgid.link/20260616-b4-disp-4352e8b0-v1-1-3e09f62e0ad5@proton.me
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
Bryam Vargas 2026-06-16 01:06:12 -05:00 committed by Greg Kroah-Hartman
parent cbc8262f68
commit 33d8c7b794

View File

@ -37,6 +37,19 @@ int gb_audio_gb_get_topology(struct gb_connection *connection,
return ret;
}
/*
* The size_* fields are supplied by the module and are used by
* gbaudio_tplg_parse_data() to compute offsets into the blob; make
* sure the sections fit within the fetched topology, so walking it
* cannot read out of bounds.
*/
if ((u64)le32_to_cpu(topo->size_dais) + le32_to_cpu(topo->size_controls) +
le32_to_cpu(topo->size_widgets) + le32_to_cpu(topo->size_routes) >
size - sizeof(*topo)) {
kfree(topo);
return -EINVAL;
}
*topology = topo;
return 0;