Validate the address before subtracting the channel base and use hwaddr 
for channel calculations to prevent unsigned underflow and truncation.

Resolves: Coverity CID 1685516

Reported-by: Alistair Francis <[email protected]>
Signed-off-by: Tao Ding <[email protected]>
---
 hw/dma/k230_gsdma.c | 6 +++++-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/hw/dma/k230_gsdma.c b/hw/dma/k230_gsdma.c
index 7635cd19e8..e9a7877e54 100644
--- a/hw/dma/k230_gsdma.c
+++ b/hw/dma/k230_gsdma.c
@@ -300,7 +300,7 @@ static const VMStateDescription vmstate_k230_gsdma = {
 static uint64_t k230_gsdma_read(void *opaque, hwaddr addr, unsigned int size)
 {
     K230GSDMAState *s = K230_GSDMA(opaque);
-    unsigned int ch;
+    hwaddr ch;
     hwaddr ch_off;
     uint64_t ret = 0;
 
@@ -329,6 +329,9 @@ static uint64_t k230_gsdma_read(void *opaque, hwaddr addr, 
unsigned int size)
         break;
     }
 
+    if (addr < K230_GSDMA_CH_BASE) {
+        goto out;
+    }
     ch = (addr - K230_GSDMA_CH_BASE) / K230_GSDMA_CH_STRIDE;
     ch_off = (addr - K230_GSDMA_CH_BASE) % K230_GSDMA_CH_STRIDE;
     if (ch < K230_GSDMA_NUM_SDMA_CHANNELS) {
@@ -355,6 +358,7 @@ static uint64_t k230_gsdma_read(void *opaque, hwaddr addr, 
unsigned int size)
         }
     }
 
+out:
     trace_k230_gsdma_read(addr, size, ret);
     return ret;
 }
-- 
2.43.0


Reply via email to