On Tue, Jun 16, 2026 at 01:06:12AM -0500, Bryam Vargas via B4 Relay wrote:
From: Bryam Vargas hexlabsecurity@proton.me
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.
But we trust the hardware to send us proper data, right? If we don't trust modules, then there are lots of other places stuff like this needs to be fixed, how many data paths did you audit?
Reject a topology whose section sizes do not fit within the fetched size before it is parsed.
Fixes: 184992e305f1 ("greybus: audio: Add Greybus Audio Device Class Protocol helper routines") Cc: stable@vger.kernel.org Signed-off-by: Bryam Vargas hexlabsecurity@proton.me
I reproduced the out-of-bounds read both in-kernel under KASAN and with a userspace AddressSanitizer model of the gbaudio_tplg_process_header() offset walk. The topology blob is kzalloc(size) where size is module-supplied (a u16), and process_header() forms control_offset = &data + size_dais, widget_offset = control_offset + size_controls, etc.; the consumers then read structs at those offsets.
In-kernel (7.1.0-rc5 + KASAN): a 64-byte blob (header 24, so 40 bytes available) with size_dais = 44 makes control_offset point 4 bytes past the allocation, and reading the first control byte there trips:
BUG: KASAN: slab-out-of-bounds in ...parse_topology... Read of size 1 at addr ... ... which belongs to the cache kmalloc-64 of size 64 The buggy address is located 4 bytes to the right of allocated 64-byte region
The patched arm (sections rejected, -EINVAL) and an in-bounds control arm (size_dais = 8) read cleanly with no KASAN report.
ASan model (-m32 and -m64): size_dais = 4096 makes control_offset point ~4 KB past the 64-byte blob - heap-buffer-overflow READ located 4056 bytes after the region, both ABIs; patched and in-bounds clean.
The source is a greybus audio module trust boundary (an attacker-supplied or compromised module reporting a malformed topology); the access is a read, and a large size_dais sends the offset far enough to fault. The reproducer (kernel module + ASan model) is available on request.
How did you find/fix this? You need to list what tools helped you...
drivers/staging/greybus/audio_gb.c | 13 +++++++++++++ 1 file changed, 13 insertions(+)
diff --git a/drivers/staging/greybus/audio_gb.c b/drivers/staging/greybus/audio_gb.c index 9d8994fdb41a..144591f1a512 100644 --- a/drivers/staging/greybus/audio_gb.c +++ b/drivers/staging/greybus/audio_gb.c @@ -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)) {
Are you sure these checks will not overflow?
thanks,
greg k-h