[PATCH 3/4] remoteproc: qcom: Fix bounds check in q6v5_wcss_da_to_va()

From: Atul Akella

Date: Fri Nov 06 2026 - 13:49:29 EST


offset is calculated as da - wcss->mem_reloc and stored in a
32 bit signed int, while da and wcss->mem_reloc are both u64.
For a sufficiently small da, the 64bit difference is truncated
into the 32 bit int, bypassing the offset < 0 underflow check
with a small positive value. Additionally, offset + len >
wcss->mem_size can itself overflow when offset and len are both
large, providing a second bypass.

da and len come from firmware's ELF program headers via
rproc_da_to_va(), and the result is used by the ELF loader
to write firmware segments, so a malformed firmware image can
cause writes outside the carveout.

Rewrite the bounds check entirely in u64 arithmetic. Reject
underflow before computing offset (da < wcss->mem_reloc).
Replace the addition based overflow check with a
subtraction based one (len > wcss->mem_size - offset) so no
intermediate sum can wrap.

Fixes: 3a3d4163e0bf ("remoteproc: qcom: Introduce Hexagon V5 based WCSS driver")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Atul Akella <atul.akella@xxxxxxxxx>
---
drivers/remoteproc/qcom_q6v5_wcss.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/qcom_q6v5_wcss.c b/drivers/remoteproc/qcom_q6v5_wcss.c
index b391724cfd08..e67dc3ff8a07 100644
--- a/drivers/remoteproc/qcom_q6v5_wcss.c
+++ b/drivers/remoteproc/qcom_q6v5_wcss.c
@@ -740,10 +740,12 @@ static int q6v5_wcss_stop(struct rproc *rproc)
static void *q6v5_wcss_da_to_va(struct rproc *rproc, u64 da, size_t len, bool *is_iomem)
{
struct q6v5_wcss *wcss = rproc->priv;
- int offset;
+ u64 offset;

+ if (da < wcss->mem_reloc)
+ return NULL;
offset = da - wcss->mem_reloc;
- if (offset < 0 || offset + len > wcss->mem_size)
+ if (offset > wcss->mem_size || len > wcss->mem_size - offset)
return NULL;

return wcss->mem_region + offset;
--
2.43.0