thebeanogamer / rpms / qemu-kvm

Forked from rpms/qemu-kvm 5 months ago
Clone

Blame SOURCES/kvm-hw-block-fdc-Prevent-end-of-track-overrun-CVE-2021-3.patch

586cba
From 6ee4a8718dcce2d6da43ee200534b75baf1d7bbe Mon Sep 17 00:00:00 2001
586cba
From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com>
586cba
Date: Thu, 18 Nov 2021 12:57:32 +0100
586cba
Subject: [PATCH 16/17] hw/block/fdc: Prevent end-of-track overrun
586cba
 (CVE-2021-3507)
586cba
MIME-Version: 1.0
586cba
Content-Type: text/plain; charset=UTF-8
586cba
Content-Transfer-Encoding: 8bit
586cba
586cba
RH-Author: Jon Maloy <jmaloy@redhat.com>
586cba
RH-MergeRequest: 107: hw/block/fdc: Prevent end-of-track overrun (CVE-2021-3507)
586cba
RH-Commit: [1/2] 9ffc5290348884d20b894fa79f4d0c8089247f8b (mrezanin/centos-src-qemu-kvm)
586cba
RH-Bugzilla: 1951522
586cba
RH-Acked-by: Hanna Reitz <hreitz@redhat.com>
586cba
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
586cba
586cba
Per the 82078 datasheet, if the end-of-track (EOT byte in
586cba
the FIFO) is more than the number of sectors per side, the
586cba
command is terminated unsuccessfully:
586cba
586cba
* 5.2.5 DATA TRANSFER TERMINATION
586cba
586cba
  The 82078 supports terminal count explicitly through
586cba
  the TC pin and implicitly through the underrun/over-
586cba
  run and end-of-track (EOT) functions. For full sector
586cba
  transfers, the EOT parameter can define the last
586cba
  sector to be transferred in a single or multisector
586cba
  transfer. If the last sector to be transferred is a par-
586cba
  tial sector, the host can stop transferring the data in
586cba
  mid-sector, and the 82078 will continue to complete
586cba
  the sector as if a hardware TC was received. The
586cba
  only difference between these implicit functions and
586cba
  TC is that they return "abnormal termination" result
586cba
  status. Such status indications can be ignored if they
586cba
  were expected.
586cba
586cba
* 6.1.3 READ TRACK
586cba
586cba
  This command terminates when the EOT specified
586cba
  number of sectors have been read. If the 82078
586cba
  does not find an I D Address Mark on the diskette
586cba
  after the second· occurrence of a pulse on the
586cba
  INDX# pin, then it sets the IC code in Status Regis-
586cba
  ter 0 to "01" (Abnormal termination), sets the MA bit
586cba
  in Status Register 1 to "1", and terminates the com-
586cba
  mand.
586cba
586cba
* 6.1.6 VERIFY
586cba
586cba
  Refer to Table 6-6 and Table 6-7 for information
586cba
  concerning the values of MT and EC versus SC and
586cba
  EOT value.
586cba
586cba
* Table 6·6. Result Phase Table
586cba
586cba
* Table 6-7. Verify Command Result Phase Table
586cba
586cba
Fix by aborting the transfer when EOT > # Sectors Per Side.
586cba
586cba
Cc: qemu-stable@nongnu.org
586cba
Cc: Hervé Poussineau <hpoussin@reactos.org>
586cba
Fixes: baca51faff0 ("floppy driver: disk geometry auto detect")
586cba
Reported-by: Alexander Bulekov <alxndr@bu.edu>
586cba
Resolves: https://gitlab.com/qemu-project/qemu/-/issues/339
586cba
Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
586cba
Message-Id: <20211118115733.4038610-2-philmd@redhat.com>
586cba
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
586cba
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
586cba
(cherry picked from commit defac5e2fbddf8423a354ff0454283a2115e1367)
586cba
Signed-off-by: Jon Maloy <jmaloy@redhat.com>
586cba
---
586cba
 hw/block/fdc.c | 8 ++++++++
586cba
 1 file changed, 8 insertions(+)
586cba
586cba
diff --git a/hw/block/fdc.c b/hw/block/fdc.c
586cba
index ca1776121f..6481ec0cfb 100644
586cba
--- a/hw/block/fdc.c
586cba
+++ b/hw/block/fdc.c
586cba
@@ -1532,6 +1532,14 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction)
586cba
         int tmp;
586cba
         fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]);
586cba
         tmp = (fdctrl->fifo[6] - ks + 1);
586cba
+        if (tmp < 0) {
586cba
+            FLOPPY_DPRINTF("invalid EOT: %d\n", tmp);
586cba
+            fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00);
586cba
+            fdctrl->fifo[3] = kt;
586cba
+            fdctrl->fifo[4] = kh;
586cba
+            fdctrl->fifo[5] = ks;
586cba
+            return;
586cba
+        }
586cba
         if (fdctrl->fifo[0] & 0x80)
586cba
             tmp += fdctrl->fifo[6];
586cba
         fdctrl->data_len *= tmp;
586cba
-- 
586cba
2.31.1
586cba