blob: 624c1f64960d2084e778c46ac069e5522546bd52 [file] [log] [blame]
Andrew Geisslerc926e172021-05-07 16:11:35 -05001From db916870a839346767b6d5ca7d0eed3128ba5fea Mon Sep 17 00:00:00 2001
2From: Bin Meng <bmeng.cn@gmail.com>
3Date: Wed, 3 Mar 2021 20:26:39 +0800
4Subject: [PATCH 6/6] hw/sd: sdhci: Reset the data pointer of s->fifo_buffer[]
5 when a different block size is programmed
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10If the block size is programmed to a different value from the
11previous one, reset the data pointer of s->fifo_buffer[] so that
12s->fifo_buffer[] can be filled in using the new block size in
13the next transfer.
14
15With this fix, the following reproducer:
16
17outl 0xcf8 0x80001010
18outl 0xcfc 0xe0000000
19outl 0xcf8 0x80001001
20outl 0xcfc 0x06000000
21write 0xe000002c 0x1 0x05
22write 0xe0000005 0x1 0x02
23write 0xe0000007 0x1 0x01
24write 0xe0000028 0x1 0x10
25write 0x0 0x1 0x23
26write 0x2 0x1 0x08
27write 0xe000000c 0x1 0x01
28write 0xe000000e 0x1 0x20
29write 0xe000000f 0x1 0x00
30write 0xe000000c 0x1 0x32
31write 0xe0000004 0x2 0x0200
32write 0xe0000028 0x1 0x00
33write 0xe0000003 0x1 0x40
34
35cannot be reproduced with the following QEMU command line:
36
37$ qemu-system-x86_64 -nographic -machine accel=qtest -m 512M \
38 -nodefaults -device sdhci-pci,sd-spec-version=3 \
39 -drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \
40 -device sd-card,drive=mydrive -qtest stdio
41
42Cc: qemu-stable@nongnu.org
43Fixes: CVE-2020-17380
44Fixes: CVE-2020-25085
45Fixes: CVE-2021-3409
46Fixes: d7dfca0807a0 ("hw/sdhci: introduce standard SD host controller")
47Reported-by: Alexander Bulekov <alxndr@bu.edu>
48Reported-by: Cornelius Aschermann (Ruhr-Universität Bochum)
49Reported-by: Sergej Schumilo (Ruhr-Universität Bochum)
50Reported-by: Simon Wörner (Ruhr-Universität Bochum)
51Buglink: https://bugs.launchpad.net/qemu/+bug/1892960
52Buglink: https://bugs.launchpad.net/qemu/+bug/1909418
53Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1928146
54Tested-by: Alexander Bulekov <alxndr@bu.edu>
55Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
56Message-Id: <20210303122639.20004-6-bmeng.cn@gmail.com>
57Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
58
59Upstream-Status: Backport [cffb446e8fd19a14e1634c7a3a8b07be3f01d5c9]
60CVE: CVE-2021-3409
61
62Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com>
63---
64 hw/sd/sdhci.c | 12 ++++++++++++
65 1 file changed, 12 insertions(+)
66
67diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
68index 6c780126e..216842420 100644
69--- a/hw/sd/sdhci.c
70+++ b/hw/sd/sdhci.c
71@@ -1140,6 +1140,8 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
72 break;
73 case SDHC_BLKSIZE:
74 if (!TRANSFERRING_DATA(s->prnsts)) {
75+ uint16_t blksize = s->blksize;
76+
77 MASKED_WRITE(s->blksize, mask, extract32(value, 0, 12));
78 MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16);
79
80@@ -1151,6 +1153,16 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
81
82 s->blksize = deposit32(s->blksize, 0, 12, s->buf_maxsz);
83 }
84+
85+ /*
86+ * If the block size is programmed to a different value from
87+ * the previous one, reset the data pointer of s->fifo_buffer[]
88+ * so that s->fifo_buffer[] can be filled in using the new block
89+ * size in the next transfer.
90+ */
91+ if (blksize != s->blksize) {
92+ s->data_count = 0;
93+ }
94 }
95
96 break;
97--
982.29.2
99