From: Bryam Vargas <hexlabsecurity(a)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.
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(a)vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity(a)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.
---
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)) {
+ kfree(topo);
+ return -EINVAL;
+ }
+
*topology = topo;
return 0;
---
base-commit: 8e65320d91cdc3b241d4b94855c88459b91abf66
change-id: 20260616-b4-disp-4352e8b0-45e86659956e
Best regards,
--
Bryam Vargas <hexlabsecurity(a)proton.me>
Smatch warns:
drivers/staging/greybus/audio_codec.c:335 gbaudio_module_update()
warn: sscanf doesn't return error codes
sscanf() returns the number of successfully matched input items, not a
negative error code. Compare the return value directly with the expected
number of conversions instead of storing it in ret as an error code.
Also remove the redundant else-if check for snd_soc_dapm_aif_out. The
widget id is validated earlier in the function, so the remaining branch
can only handle snd_soc_dapm_aif_out. This avoids a compiler warning
about a potentially uninitialized variable.
Reported-by: kernel test robot <lkp(a)intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202606140347.gGVWDnbi-lkp@intel.com/
Signed-off-by: abdelnasser hussein <abdelnasserhussein11(a)gmail.com>
---
drivers/staging/greybus/audio_codec.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/staging/greybus/audio_codec.c b/drivers/staging/greybus/audio_codec.c
index 720aa752e17e..6daa4e706792 100644
--- a/drivers/staging/greybus/audio_codec.c
+++ b/drivers/staging/greybus/audio_codec.c
@@ -311,8 +311,7 @@ int gbaudio_module_update(struct gbaudio_codec_info *codec,
}
/* parse dai_id from AIF widget's stream_name */
- ret = sscanf(w->sname, "%s %d %s", intf_name, &dai_id, dir);
- if (ret < 3) {
+ if (sscanf(w->sname, "%s %d %s", intf_name, &dai_id, dir) != 3) {
dev_err(codec->dev, "Error while parsing dai_id for %s\n", w->name);
return -EINVAL;
}
@@ -323,7 +322,7 @@ int gbaudio_module_update(struct gbaudio_codec_info *codec,
ret = gbaudio_module_enable_tx(codec, module, dai_id);
else
ret = gbaudio_module_disable_tx(module, dai_id);
- } else if (w->id == snd_soc_dapm_aif_out) {
+ } else {
if (enable)
ret = gbaudio_module_enable_rx(codec, module, dai_id);
else
--
2.54.0
This patch series addresses two separate issues in gbaudio_module_update()
that were previously combined in v2:
1. Fixes an improper check of the sscanf() return value (smatch warning).
2. Removes a redundant else-if check that could lead to an uninitialized
variable warning for 'ret' (reported by kernel test robot).
Changes in v3:
- Split the changes into a 2-patch series based on feedback from
Greg Kroah-Hartman.
- Assigned correct Reported-by and Closes tags to both patches.
abdelnasser hussein (2):
staging: greybus: audio_codec: fix sscanf return value check
staging: greybus: audio_codec: remove redundant else-if check
drivers/staging/greybus/audio_codec.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--
2.54.0
The macro CAP_TIMEOUT_MS is defined but never used anywhere
in the kernel tree. Remove it to clean up code.
Signed-off-by: Rhys Tumelty <rhys(a)tumelty.co.uk>
---
drivers/staging/greybus/authentication.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/staging/greybus/authentication.c b/drivers/staging/greybus/authentication.c
index 97b9937bbdc1..d8f2cd43201f 100644
--- a/drivers/staging/greybus/authentication.c
+++ b/drivers/staging/greybus/authentication.c
@@ -15,8 +15,6 @@
#include "greybus_authentication.h"
#include "firmware.h"
-#define CAP_TIMEOUT_MS 1000
-
/*
* Number of minor devices this driver supports.
* There will be exactly one required per Interface.
--
2.54.0