Patrick Williams | 92b42cb | 2022-09-03 06:53:57 -0500 | [diff] [blame] | 1 | From 57a89cc36ead7234e540d0ecbe1a792ab6b04cb7 Mon Sep 17 00:00:00 2001 |
| 2 | From: =?UTF-8?q?Philippe=20Mathieu-Daud=C3=A9?= <philmd@redhat.com> |
| 3 | Date: Thu, 18 Nov 2021 12:57:32 +0100 |
| 4 | Subject: [PATCH 1/2] hw/block/fdc: Prevent end-of-track overrun |
| 5 | (CVE-2021-3507) |
| 6 | MIME-Version: 1.0 |
| 7 | Content-Type: text/plain; charset=UTF-8 |
| 8 | Content-Transfer-Encoding: 8bit |
| 9 | |
| 10 | Per the 82078 datasheet, if the end-of-track (EOT byte in |
| 11 | the FIFO) is more than the number of sectors per side, the |
| 12 | command is terminated unsuccessfully: |
| 13 | |
| 14 | * 5.2.5 DATA TRANSFER TERMINATION |
| 15 | |
| 16 | The 82078 supports terminal count explicitly through |
| 17 | the TC pin and implicitly through the underrun/over- |
| 18 | run and end-of-track (EOT) functions. For full sector |
| 19 | transfers, the EOT parameter can define the last |
| 20 | sector to be transferred in a single or multisector |
| 21 | transfer. If the last sector to be transferred is a par- |
| 22 | tial sector, the host can stop transferring the data in |
| 23 | mid-sector, and the 82078 will continue to complete |
| 24 | the sector as if a hardware TC was received. The |
| 25 | only difference between these implicit functions and |
| 26 | TC is that they return "abnormal termination" result |
| 27 | status. Such status indications can be ignored if they |
| 28 | were expected. |
| 29 | |
| 30 | * 6.1.3 READ TRACK |
| 31 | |
| 32 | This command terminates when the EOT specified |
| 33 | number of sectors have been read. If the 82078 |
| 34 | does not find an I D Address Mark on the diskette |
| 35 | after the second· occurrence of a pulse on the |
| 36 | INDX# pin, then it sets the IC code in Status Regis- |
| 37 | ter 0 to "01" (Abnormal termination), sets the MA bit |
| 38 | in Status Register 1 to "1", and terminates the com- |
| 39 | mand. |
| 40 | |
| 41 | * 6.1.6 VERIFY |
| 42 | |
| 43 | Refer to Table 6-6 and Table 6-7 for information |
| 44 | concerning the values of MT and EC versus SC and |
| 45 | EOT value. |
| 46 | |
| 47 | * Table 6·6. Result Phase Table |
| 48 | |
| 49 | * Table 6-7. Verify Command Result Phase Table |
| 50 | |
| 51 | Fix by aborting the transfer when EOT > # Sectors Per Side. |
| 52 | |
| 53 | Cc: qemu-stable@nongnu.org |
| 54 | Cc: Hervé Poussineau <hpoussin@reactos.org> |
| 55 | Fixes: baca51faff0 ("floppy driver: disk geometry auto detect") |
| 56 | Reported-by: Alexander Bulekov <alxndr@bu.edu> |
| 57 | Resolves: https://gitlab.com/qemu-project/qemu/-/issues/339 |
| 58 | Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com> |
| 59 | Message-Id: <20211118115733.4038610-2-philmd@redhat.com> |
| 60 | Reviewed-by: Hanna Reitz <hreitz@redhat.com> |
| 61 | Signed-off-by: Kevin Wolf <kwolf@redhat.com> |
| 62 | |
| 63 | Upstream-Status: Backport [defac5e2fbddf8423a354ff0454283a2115e1367] |
| 64 | CVE: CVE-2021-3507 |
| 65 | |
| 66 | Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com> |
| 67 | --- |
| 68 | hw/block/fdc.c | 8 ++++++++ |
| 69 | 1 file changed, 8 insertions(+) |
| 70 | |
| 71 | diff --git a/hw/block/fdc.c b/hw/block/fdc.c |
| 72 | index 347875a0c..57bb35579 100644 |
| 73 | --- a/hw/block/fdc.c |
| 74 | +++ b/hw/block/fdc.c |
| 75 | @@ -1530,6 +1530,14 @@ static void fdctrl_start_transfer(FDCtrl *fdctrl, int direction) |
| 76 | int tmp; |
| 77 | fdctrl->data_len = 128 << (fdctrl->fifo[5] > 7 ? 7 : fdctrl->fifo[5]); |
| 78 | tmp = (fdctrl->fifo[6] - ks + 1); |
| 79 | + if (tmp < 0) { |
| 80 | + FLOPPY_DPRINTF("invalid EOT: %d\n", tmp); |
| 81 | + fdctrl_stop_transfer(fdctrl, FD_SR0_ABNTERM, FD_SR1_MA, 0x00); |
| 82 | + fdctrl->fifo[3] = kt; |
| 83 | + fdctrl->fifo[4] = kh; |
| 84 | + fdctrl->fifo[5] = ks; |
| 85 | + return; |
| 86 | + } |
| 87 | if (fdctrl->fifo[0] & 0x80) |
| 88 | tmp += fdctrl->fifo[6]; |
| 89 | fdctrl->data_len *= tmp; |
| 90 | -- |
| 91 | 2.33.0 |
| 92 | |