Re: [PATCH] remoteproc: imx_rproc: Fix off-by-one in address translation
[email protected] Thu, 30 Jul 2026 03:21:06 +0000
| Newsgroups | dev.linux.lists.imx |
|---|---|
| Message-ID | <[email protected]> |
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider: Pre-existing issues: - [High] The patch fixes an off-by-one boundary check in `imx_rproc_da_to_sys()` using `<=` but misses the identical boundary check in its caller `imx_rproc_da_to_va()`, leaving the bug unresolved. - [High] An integer overflow in the memory segment bounds checks allows untrusted firmware to perform arbitrary out-of-bounds kernel writes on 64-bit platforms. -- --- Patch [1]: [PATCH] remoteproc: imx_rproc: Fix off-by-one in address translation --- commit 26c9a9508d8034f3f59181045a1d03a59fa5b603 Author: Peng Fan <[email protected]> remoteproc: imx_rproc: Fix off-by-one in address translation This commit fixes an off-by-one error in imx_rproc_da_to_sys() by changing a strict less-than comparison to a less-than-or-equal comparison for firmware segments that exactly fill a memory region. Link: https://lore.kernel.org/all/[email protected]/ > diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c > index 745ce52cd8226..9af0aa26ce9b7 100644 > --- a/drivers/remoteproc/imx_rproc.c > +++ b/drivers/remoteproc/imx_rproc.c > @@ -552,7 +552,7 @@ static int imx_rproc_da_to_sys(struct imx_rproc *priv, u64 da, > continue; > } > > - if (da >= att->da && da + len < att->da + att->size) { > + if (da >= att->da && da + len <= att->da + att->size) { [Severity: High] This is a pre-existing issue, but does this fix actually solve the problem since the caller still uses a strict less-than check? When imx_rproc_da_to_sys() successfully translates a valid boundary case where da + len == att->da + att->size, its caller imx_rproc_da_to_va() performs a secondary boundary check: drivers/remoteproc/imx_rproc.c:imx_rproc_da_to_va() { ... if (imx_rproc_da_to_sys(priv, da, len, &sys, is_iomem)) return NULL; for (i = 0; i < IMX_RPROC_MEM_MAX; i++) { if (sys >= priv->mem[i].sys_addr && sys + len < priv->mem[i].sys_addr + priv->mem[i].size) { ... } } ... } Because imx_rproc_da_to_va() still uses a strict less-than comparison (<) instead of (<=), won't it still reject the exactly matching segment and return NULL, preventing the system from booting valid firmware? [Severity: High] This is also a pre-existing issue, but can the da + len calculation overflow 64-bit integers on 64-bit platforms? In rproc_elf_load_segments() from drivers/remoteproc/remoteproc_elf_loader.c, da and memsz (len) are extracted from the ELF headers. By providing a maliciously crafted da (e.g., 0x10000000) and a massive memsz (e.g., 0xFFFFFFFFF0000000), da + len can overflow and wrap around to a small value (e.g., 0). Could this bypass the primary bounds check here: if (da >= att->da && da + len <= att->da + att->size) { and the secondary check in imx_rproc_da_to_va(): if (sys >= priv->mem[i].sys_addr && sys + len < ... allowing untrusted firmware to perform arbitrary out-of-bounds kernel memory writes during memcpy() in rproc_elf_load_segments()? > unsigned int offset = da - att->da; > > *sys = att->sa + offset; -- Sashiko AI review ยท https://sashiko.dev/#/patchset/[email protected]?part=1