blob: c3b37ed616ddd0081a061281eeabd69c528c0f62 [file] [log] [blame]
Andrew Geisslerc926e172021-05-07 16:11:35 -05001From 405ca416ccc8135544a4fe5732974497244128c9 Mon Sep 17 00:00:00 2001
2From: Bin Meng <bmeng.cn@gmail.com>
3Date: Wed, 3 Mar 2021 20:26:36 +0800
4Subject: [PATCH 3/6] hw/sd: sdhci: Don't write to SDHC_SYSAD register when
5 transfer is in progress
6MIME-Version: 1.0
7Content-Type: text/plain; charset=UTF-8
8Content-Transfer-Encoding: 8bit
9
10Per "SD Host Controller Standard Specification Version 7.00"
11chapter 2.2.1 SDMA System Address Register:
12
13This register can be accessed only if no transaction is executing
14(i.e., after a transaction has stopped).
15
16With this fix, the following reproducer:
17
18outl 0xcf8 0x80001010
19outl 0xcfc 0xfbefff00
20outl 0xcf8 0x80001001
21outl 0xcfc 0x06000000
22write 0xfbefff2c 0x1 0x05
23write 0xfbefff0f 0x1 0x37
24write 0xfbefff0a 0x1 0x01
25write 0xfbefff0f 0x1 0x29
26write 0xfbefff0f 0x1 0x02
27write 0xfbefff0f 0x1 0x03
28write 0xfbefff04 0x1 0x01
29write 0xfbefff05 0x1 0x01
30write 0xfbefff07 0x1 0x02
31write 0xfbefff0c 0x1 0x33
32write 0xfbefff0e 0x1 0x20
33write 0xfbefff0f 0x1 0x00
34write 0xfbefff2a 0x1 0x01
35write 0xfbefff0c 0x1 0x00
36write 0xfbefff03 0x1 0x00
37write 0xfbefff05 0x1 0x00
38write 0xfbefff2a 0x1 0x02
39write 0xfbefff0c 0x1 0x32
40write 0xfbefff01 0x1 0x01
41write 0xfbefff02 0x1 0x01
42write 0xfbefff03 0x1 0x01
43
44cannot be reproduced with the following QEMU command line:
45
46$ qemu-system-x86_64 -nographic -machine accel=qtest -m 512M \
47 -nodefaults -device sdhci-pci,sd-spec-version=3 \
48 -drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \
49 -device sd-card,drive=mydrive -qtest stdio
50
51Cc: qemu-stable@nongnu.org
52Fixes: CVE-2020-17380
53Fixes: CVE-2020-25085
54Fixes: CVE-2021-3409
55Fixes: d7dfca0807a0 ("hw/sdhci: introduce standard SD host controller")
56Reported-by: Alexander Bulekov <alxndr@bu.edu>
57Reported-by: Cornelius Aschermann (Ruhr-Universität Bochum)
58Reported-by: Sergej Schumilo (Ruhr-Universität Bochum)
59Reported-by: Simon Wörner (Ruhr-Universität Bochum)
60Buglink: https://bugs.launchpad.net/qemu/+bug/1892960
61Buglink: https://bugs.launchpad.net/qemu/+bug/1909418
62Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1928146
63Tested-by: Alexander Bulekov <alxndr@bu.edu>
64Signed-off-by: Bin Meng <bmeng.cn@gmail.com>
65Message-Id: <20210303122639.20004-3-bmeng.cn@gmail.com>
66Signed-off-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
67
68Upstream-Status: Backport [8be45cc947832b3c02144c9d52921f499f2d77fe]
69CVE: CVE-2021-3409
70
71Signed-off-by: Sakib Sajal <sakib.sajal@windriver.com>
72---
73 hw/sd/sdhci.c | 20 +++++++++++---------
74 1 file changed, 11 insertions(+), 9 deletions(-)
75
76diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c
77index 44f8a82ea..d8a46f307 100644
78--- a/hw/sd/sdhci.c
79+++ b/hw/sd/sdhci.c
80@@ -1121,15 +1121,17 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size)
81
82 switch (offset & ~0x3) {
83 case SDHC_SYSAD:
84- s->sdmasysad = (s->sdmasysad & mask) | value;
85- MASKED_WRITE(s->sdmasysad, mask, value);
86- /* Writing to last byte of sdmasysad might trigger transfer */
87- if (!(mask & 0xFF000000) && TRANSFERRING_DATA(s->prnsts) && s->blkcnt &&
88- s->blksize && SDHC_DMA_TYPE(s->hostctl1) == SDHC_CTRL_SDMA) {
89- if (s->trnmod & SDHC_TRNS_MULTI) {
90- sdhci_sdma_transfer_multi_blocks(s);
91- } else {
92- sdhci_sdma_transfer_single_block(s);
93+ if (!TRANSFERRING_DATA(s->prnsts)) {
94+ s->sdmasysad = (s->sdmasysad & mask) | value;
95+ MASKED_WRITE(s->sdmasysad, mask, value);
96+ /* Writing to last byte of sdmasysad might trigger transfer */
97+ if (!(mask & 0xFF000000) && s->blkcnt && s->blksize &&
98+ SDHC_DMA_TYPE(s->hostctl1) == SDHC_CTRL_SDMA) {
99+ if (s->trnmod & SDHC_TRNS_MULTI) {
100+ sdhci_sdma_transfer_multi_blocks(s);
101+ } else {
102+ sdhci_sdma_transfer_single_block(s);
103+ }
104 }
105 }
106 break;
107--
1082.29.2
109