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
