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