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

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