Blame SOURCES/kvm-fdc-force-the-fifo-access-to-be-in-bounds-of-the-all.patch

1200d7
From e3b51a8b94859d175b4733d3c17a960934f5edc6 Mon Sep 17 00:00:00 2001
1200d7
From: Miroslav Rezanina <mrezanin@redhat.com>
1200d7
Date: Fri, 8 May 2015 17:40:22 +0200
1200d7
Subject: [PATCH] fdc: force the fifo access to be in bounds of the allocated
1200d7
 buffer
1200d7
1200d7
Bugzilla: 1219269
1200d7
1200d7
During processing of certain commands such as FD_CMD_READ_ID and
1200d7
FD_CMD_DRIVE_SPECIFICATION_COMMAND the fifo memory access could
1200d7
get out of bounds leading to memory corruption with values coming
1200d7
from the guest.
1200d7
1200d7
Fix this by making sure that the index is always bounded by the
1200d7
allocated memory.
1200d7
1200d7
This is CVE-2015-3456.
1200d7
1200d7
Signed-off-by: Petr Matousek <pmatouse@redhat.com>
1200d7
---
1200d7
 hw/block/fdc.c | 17 +++++++++++------
1200d7
 1 file changed, 11 insertions(+), 6 deletions(-)
1200d7
1200d7
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
1200d7
index 322d863..56aedcc 100644
1200d7
--- a/hw/block/fdc.c
1200d7
+++ b/hw/block/fdc.c
1200d7
@@ -1434,7 +1434,7 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
1200d7
 {
1200d7
     FDrive *cur_drv;
1200d7
     uint32_t retval = 0;
1200d7
-    int pos;
1200d7
+    uint32_t pos;
1200d7
 
1200d7
     cur_drv = get_cur_drv(fdctrl);
1200d7
     fdctrl->dsr &= ~FD_DSR_PWRDOWN;
1200d7
@@ -1443,8 +1443,8 @@ static uint32_t fdctrl_read_data(FDCtrl *fdctrl)
1200d7
         return 0;
1200d7
     }
1200d7
     pos = fdctrl->data_pos;
1200d7
+    pos %= FD_SECTOR_LEN;
1200d7
     if (fdctrl->msr & FD_MSR_NONDMA) {
1200d7
-        pos %= FD_SECTOR_LEN;
1200d7
         if (pos == 0) {
1200d7
             if (fdctrl->data_pos != 0)
1200d7
                 if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
1200d7
@@ -1788,10 +1788,13 @@ static void fdctrl_handle_option(FDCtrl *fdctrl, int direction)
1200d7
 static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction)
1200d7
 {
1200d7
     FDrive *cur_drv = get_cur_drv(fdctrl);
1200d7
+    uint32_t pos;
1200d7
 
1200d7
-    if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {
1200d7
+    pos = fdctrl->data_pos - 1;
1200d7
+    pos %= FD_SECTOR_LEN;
1200d7
+    if (fdctrl->fifo[pos] & 0x80) {
1200d7
         /* Command parameters done */
1200d7
-        if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {
1200d7
+        if (fdctrl->fifo[pos] & 0x40) {
1200d7
             fdctrl->fifo[0] = fdctrl->fifo[1];
1200d7
             fdctrl->fifo[2] = 0;
1200d7
             fdctrl->fifo[3] = 0;
1200d7
@@ -1891,7 +1894,7 @@ static uint8_t command_to_handler[256];
1200d7
 static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
1200d7
 {
1200d7
     FDrive *cur_drv;
1200d7
-    int pos;
1200d7
+    uint32_t pos;
1200d7
 
1200d7
     /* Reset mode */
1200d7
     if (!(fdctrl->dor & FD_DOR_nRESET)) {
1200d7
@@ -1939,7 +1942,9 @@ static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
1200d7
     }
1200d7
 
1200d7
     FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
1200d7
-    fdctrl->fifo[fdctrl->data_pos++] = value;
1200d7
+    pos = fdctrl->data_pos++;
1200d7
+    pos %= FD_SECTOR_LEN;
1200d7
+    fdctrl->fifo[pos] = value;
1200d7
     if (fdctrl->data_pos == fdctrl->data_len) {
1200d7
         /* We now have all parameters
1200d7
          * and will be able to treat the command
1200d7
-- 
1200d7
1.8.3.1
1200d7