summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2016-04-18 13:07:35 +0300
committerMichael Roth <mdroth@linux.vnet.ibm.com>2016-05-09 11:55:58 -0500
commit5b7236f7256974d9c0286fa4837aa5e15ef5c629 (patch)
tree8658d0e4046c0a47ec84b903feccdeffd0edd807
parent0bcdb632f871fc5c80ded99e52445da35a8eaaa7 (diff)
downloadqemu-5b7236f7256974d9c0286fa4837aa5e15ef5c629.tar.gz
cadence_uart: bounds check write offset
cadence_uart_init() initializes an I/O memory region of size 0x1000 bytes. However in uart_write(), the 'offset' parameter (offset within region) is divided by 4 and then used to index the array 'r' of size CADENCE_UART_R_MAX which is much smaller: (0x48/4). If 'offset>>=2' exceeds CADENCE_UART_R_MAX, this will cause an out-of-bounds memory write where the offset and the value are controlled by guest. This will corrupt QEMU memory, in most situations this causes the vm to crash. Fix by checking the offset against the array size. Cc: qemu-stable@nongnu.org Reported-by: 李强 <liqiang6-s@360.cn> Signed-off-by: Michael S. Tsirkin <mst@redhat.com> Reviewed-by: Alistair Francis <alistair.francis@xilinx.com> Message-id: 20160418100735.GA517@redhat.com Signed-off-by: Peter Maydell <peter.maydell@linaro.org> (cherry picked from commit 5eb0b194e9b01ba0f3613e6ddc2cb9f63ce96ae5) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
-rw-r--r--hw/char/cadence_uart.c3
1 files changed, 3 insertions, 0 deletions
diff --git a/hw/char/cadence_uart.c b/hw/char/cadence_uart.c
index 9d379e5b15..a217271beb 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -374,6 +374,9 @@ static void uart_write(void *opaque, hwaddr offset,
DB_PRINT(" offset:%x data:%08x\n", (unsigned)offset, (unsigned)value);
offset >>= 2;
+ if (offset >= CADENCE_UART_R_MAX) {
+ return;
+ }
switch (offset) {
case R_IER: /* ier (wts imr) */
s->r[R_IMR] |= value;