summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2016-04-18 13:07:35 +0300
committerTimothy Pearson <tpearson@raptorengineering.com>2019-11-29 20:03:49 -0600
commitdc0adf219b1372f7a3be6f1dc770614a3927a57d (patch)
tree4bcf901c0a211456369c002964316bff401e6410
parent465e84d59bddad8766c965e7334492dcd1f714d9 (diff)
downloadhqemu-dc0adf219b1372f7a3be6f1dc770614a3927a57d.zip
hqemu-dc0adf219b1372f7a3be6f1dc770614a3927a57d.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>
-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 486591b..7977878 100644
--- a/hw/char/cadence_uart.c
+++ b/hw/char/cadence_uart.c
@@ -375,6 +375,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;
OpenPOWER on IntegriCloud