The i.MX address translation code checks the requested range
using addition based comparisons, da + len < att->da + att->size.

Both additions can overflow, letting an out of range device
address or length pass the bounds check. The strict less than
comparison also rejects a valid range that ends exactly at the
end of the translation region.

offset is also stored in an unsigned int, while da and att->da
are both u64. The 64 bit subtraction can get truncated on
assignment, giving a wrong offset instead of failing.

Reject underflow before calculating the offset, then do the
remaining bounds check using subtraction instead of addition.
Store offset as u64 so it cannot truncate. This keeps the
arithmetic overflow safe and allows ranges that end exactly at
the region boundary.

Signed-off-by: Atul Akella <[email protected]>
---
 drivers/remoteproc/imx_rproc.c | 7 +++++--
 1 file changed, 5 insertions(+), 2 deletions(-)

diff --git a/drivers/remoteproc/imx_rproc.c b/drivers/remoteproc/imx_rproc.c
index 3f8cea127ec..570d22b6e51 100644
--- a/drivers/remoteproc/imx_rproc.c
+++ b/drivers/remoteproc/imx_rproc.c
@@ -248,10 +248,13 @@ static int imx_rproc_da_to_sys(struct udevice *dev, u64 
da, size_t len, u64 *sys
        /* parse address translation table */
        for (i = 0; i < dcfg->att_size; i++) {
                const struct imx_rproc_att *att = &dcfg->att[i];
+               u64 offset;
 
-               if (da >= att->da && da + len < att->da + att->size) {
-                       unsigned int offset = da - att->da;
+               if (da < att->da)
+                       continue;
 
+               offset = da - att->da;
+               if (offset <= att->size && len <= att->size - offset) {
                        *sys = att->sa + offset;
 
                        if (is_iomem)
-- 
2.43.0

Reply via email to