Fix VENOM vulnerability for Intel-based systems.

This is a back-port of the upstream fix to the VENOM security
vulnerability, that affects the floppy disk virtual device
implementation.

Upstream origin:
    http://git.qemu.org/?p=qemu.git;a=commitdiff;h=e907746266721f305d67bc0718795fedee2e824c

Upstream commit message:
	fdc: force the fifo access to be in bounds of the allocated buffer

	During processing of certain commands such as FD_CMD_READ_ID and
	FD_CMD_DRIVE_SPECIFICATION_COMMAND the fifo memory access could
	get out of bounds leading to memory corruption with values coming
	from the guest.

	Fix this by making sure that the index is always bounded by the
	allocated memory.

	This is CVE-2015-3456.

	Signed-off-by: Petr Matousek <pmatouse@redhat.com>
	Reviewed-by: John Snow <jsnow@redhat.com>
	Signed-off-by: John Snow <jsnow@redhat.com>

BUG=21251683

Change-Id: I46c0908fa6ece61f84879a7cf8e60fa45548f7d0
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
index 739a03e..1168e8c 100644
--- a/hw/block/fdc.c
+++ b/hw/block/fdc.c
@@ -1512,7 +1512,7 @@
 {
     FDrive *cur_drv;
     uint32_t retval = 0;
-    int pos;
+    uint32_t pos;
 
     cur_drv = get_cur_drv(fdctrl);
     fdctrl->dsr &= ~FD_DSR_PWRDOWN;
@@ -1521,8 +1521,8 @@
         return 0;
     }
     pos = fdctrl->data_pos;
+    pos %= FD_SECTOR_LEN;
     if (fdctrl->msr & FD_MSR_NONDMA) {
-        pos %= FD_SECTOR_LEN;
         if (pos == 0) {
             if (fdctrl->data_pos != 0)
                 if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) {
@@ -1867,10 +1867,13 @@
 static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction)
 {
     FDrive *cur_drv = get_cur_drv(fdctrl);
+    uint32_t pos;
 
-    if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) {
+    pos = fdctrl->data_pos - 1;
+    pos %= FD_SECTOR_LEN;
+    if (fdctrl->fifo[pos] & 0x80) {
         /* Command parameters done */
-        if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) {
+        if (fdctrl->fifo[pos] & 0x40) {
             fdctrl->fifo[0] = fdctrl->fifo[1];
             fdctrl->fifo[2] = 0;
             fdctrl->fifo[3] = 0;
@@ -1970,7 +1973,7 @@
 static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value)
 {
     FDrive *cur_drv;
-    int pos;
+    uint32_t pos;
 
     /* Reset mode */
     if (!(fdctrl->dor & FD_DOR_nRESET)) {
@@ -2019,7 +2022,9 @@
     }
 
     FLOPPY_DPRINTF("%s: %02x\n", __func__, value);
-    fdctrl->fifo[fdctrl->data_pos++] = value;
+    pos = fdctrl->data_pos++;
+    pos %= FD_SECTOR_LEN;
+    fdctrl->fifo[pos] = value;
     if (fdctrl->data_pos == fdctrl->data_len) {
         /* We now have all parameters
          * and will be able to treat the command