Skip to content

Commit

Permalink
cadence_uart: bounds check write offset
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
mstsirkin authored and pm215 committed Apr 19, 2016
1 parent a087cc5 commit 5eb0b19
Showing 1 changed file with 3 additions and 0 deletions.
3 changes: 3 additions & 0 deletions hw/char/cadence_uart.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down

0 comments on commit 5eb0b19

Please sign in to comment.