diff mbox series

[PULL,22/22] dma: omap: check dma channel data_type

Message ID 1485531137-2362-23-git-send-email-peter.maydell@linaro.org
State Accepted
Commit 146871c33eb70ca7090a0a55e69e5a8f9b5eb102
Headers show
Series target-arm queue | expand

Commit Message

Peter Maydell Jan. 27, 2017, 3:32 p.m. UTC
From: Prasad J Pandit <pjp@fedoraproject.org>


When setting dma channel 'data_type', if (value & 3) == 3,
the set 'data_type' is said to be bad. This also leads to an
OOB access in 'omap_dma_transfer_generic', while doing
cpu_physical_memory_r/w operations. Add check to avoid it.

Reported-by: Jiang Xin <jiangxin1@huawei.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>

Message-id: 20170127120528.30959-1-ppandit@redhat.com
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>

---
 hw/dma/omap_dma.c | 10 +++++++---
 1 file changed, 7 insertions(+), 3 deletions(-)

-- 
2.7.4
diff mbox series

Patch

diff --git a/hw/dma/omap_dma.c b/hw/dma/omap_dma.c
index f6f86f9..45dfe7a 100644
--- a/hw/dma/omap_dma.c
+++ b/hw/dma/omap_dma.c
@@ -878,15 +878,17 @@  static int omap_dma_ch_reg_write(struct omap_dma_s *s,
         ch->burst[0] = (value & 0x0180) >> 7;
         ch->pack[0] = (value & 0x0040) >> 6;
         ch->port[0] = (enum omap_dma_port) ((value & 0x003c) >> 2);
-        ch->data_type = 1 << (value & 3);
         if (ch->port[0] >= __omap_dma_port_last)
             printf("%s: invalid DMA port %i\n", __FUNCTION__,
                             ch->port[0]);
         if (ch->port[1] >= __omap_dma_port_last)
             printf("%s: invalid DMA port %i\n", __FUNCTION__,
                             ch->port[1]);
-        if ((value & 3) == 3)
+        ch->data_type = 1 << (value & 3);
+        if ((value & 3) == 3) {
             printf("%s: bad data_type for DMA channel\n", __FUNCTION__);
+            ch->data_type >>= 1;
+        }
         break;
 
     case 0x02:	/* SYS_DMA_CCR_CH0 */
@@ -1988,8 +1990,10 @@  static void omap_dma4_write(void *opaque, hwaddr addr,
             fprintf(stderr, "%s: bad MReqAddressTranslate sideband signal\n",
                             __FUNCTION__);
         ch->data_type = 1 << (value & 3);
-        if ((value & 3) == 3)
+        if ((value & 3) == 3) {
             printf("%s: bad data_type for DMA channel\n", __FUNCTION__);
+            ch->data_type >>= 1;
+        }
         break;
 
     case 0x14:	/* DMA4_CEN */