From 39c4e0d32c99766e4ac8ff197a1fb793ffa2675c Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 8 May 2021 10:39:15 +0800 Subject: [PATCH 1/7] hw/sd: sdhci: Don't transfer any data when command time out MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: CVE-2020-17380 Fixes: CVE-2020-25085 Fixes: CVE-2021-3409 At the end of sdhci_send_command(), it starts a data transfer if the command register indicates data is associated. But the data transfer should only be initiated when the command execution has succeeded. With this fix, the following reproducer: outl 0xcf8 0x80001810 outl 0xcfc 0xe1068000 outl 0xcf8 0x80001804 outw 0xcfc 0x7 write 0xe106802c 0x1 0x0f write 0xe1068004 0xc 0x2801d10101fffffbff28a384 write 0xe106800c 0x1f 0x9dacbbcad9e8f7061524334251606f7e8d9cabbac9d8e7f60514233241505f write 0xe1068003 0x28 0x80d000251480d000252280d000253080d000253e80d000254c80d000255a80d000256880d0002576 write 0xe1068003 0x1 0xfe cannot be reproduced with the following QEMU command line: $ qemu-system-x86_64 -nographic -M pc-q35-5.0 \ -device sdhci-pci,sd-spec-version=3 \ -drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \ -device sd-card,drive=mydrive \ -monitor none -serial none -qtest stdio Cc: qemu-stable@nongnu.org Fixes: CVE-2020-17380 Fixes: CVE-2020-25085 Fixes: CVE-2021-3409 Fixes: d7dfca0807a0 ("hw/sdhci: introduce standard SD host controller") Reported-by: Alexander Bulekov Reported-by: Cornelius Aschermann (Ruhr-University Bochum) Reported-by: Muhammad Ramdhan Reported-by: Sergej Schumilo (Ruhr-University Bochum) Reported-by: Simon Wrner (Ruhr-University Bochum) Buglink: https://bugs.launchpad.net/qemu/+bug/1892960 Buglink: https://bugs.launchpad.net/qemu/+bug/1909418 Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1928146 Signed-off-by: Bin Meng Acked-by: Alistair Francis Tested-by: Alexander Bulekov Tested-by: Philippe Mathieu-Daudé Signed-off-by: Jiajie Li --- ...t-transfer-any-data-when-command-tim.patch | 93 +++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 hw-sd-sdhci-Don-t-transfer-any-data-when-command-tim.patch diff --git a/hw-sd-sdhci-Don-t-transfer-any-data-when-command-tim.patch b/hw-sd-sdhci-Don-t-transfer-any-data-when-command-tim.patch new file mode 100644 index 00000000..0eef581f --- /dev/null +++ b/hw-sd-sdhci-Don-t-transfer-any-data-when-command-tim.patch @@ -0,0 +1,93 @@ +From e53e808dc58401e9bb42f83d9dd9fc7b633ff848 Mon Sep 17 00:00:00 2001 +From: Bin Meng +Date: Sat, 8 May 2021 10:39:15 +0800 +Subject: [PATCH] hw/sd: sdhci: Don't transfer any data when command time out +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes: CVE-2020-17380 +Fixes: CVE-2020-25085 +Fixes: CVE-2021-3409 + +At the end of sdhci_send_command(), it starts a data transfer if the +command register indicates data is associated. But the data transfer +should only be initiated when the command execution has succeeded. + +With this fix, the following reproducer: + +outl 0xcf8 0x80001810 +outl 0xcfc 0xe1068000 +outl 0xcf8 0x80001804 +outw 0xcfc 0x7 +write 0xe106802c 0x1 0x0f +write 0xe1068004 0xc 0x2801d10101fffffbff28a384 +write 0xe106800c 0x1f +0x9dacbbcad9e8f7061524334251606f7e8d9cabbac9d8e7f60514233241505f +write 0xe1068003 0x28 +0x80d000251480d000252280d000253080d000253e80d000254c80d000255a80d000256880d0002576 +write 0xe1068003 0x1 0xfe + +cannot be reproduced with the following QEMU command line: + +$ qemu-system-x86_64 -nographic -M pc-q35-5.0 \ + -device sdhci-pci,sd-spec-version=3 \ + -drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \ + -device sd-card,drive=mydrive \ + -monitor none -serial none -qtest stdio + +Cc: qemu-stable@nongnu.org +Fixes: CVE-2020-17380 +Fixes: CVE-2020-25085 +Fixes: CVE-2021-3409 +Fixes: d7dfca0807a0 ("hw/sdhci: introduce standard SD host controller") +Reported-by: Alexander Bulekov +Reported-by: Cornelius Aschermann (Ruhr-University Bochum) +Reported-by: Muhammad Ramdhan +Reported-by: Sergej Schumilo (Ruhr-University Bochum) +Reported-by: Simon Wrner (Ruhr-University Bochum) +Buglink: https://bugs.launchpad.net/qemu/+bug/1892960 +Buglink: https://bugs.launchpad.net/qemu/+bug/1909418 +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1928146 +Signed-off-by: Bin Meng +Acked-by: Alistair Francis +Tested-by: Alexander Bulekov +Tested-by: Philippe Mathieu-Daudé + +Signed-off-by: Jiajie Li +--- + hw/sd/sdhci.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index e51573fe3c..a24f164e3f 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -314,6 +314,7 @@ static void sdhci_send_command(SDHCIState *s) + SDRequest request; + uint8_t response[16]; + int rlen; ++ bool timeout = false; + + s->errintsts = 0; + s->acmd12errsts = 0; +@@ -337,6 +338,7 @@ static void sdhci_send_command(SDHCIState *s) + trace_sdhci_response16(s->rspreg[3], s->rspreg[2], + s->rspreg[1], s->rspreg[0]); + } else { ++ timeout = true; + trace_sdhci_error("timeout waiting for command response"); + if (s->errintstsen & SDHC_EISEN_CMDTIMEOUT) { + s->errintsts |= SDHC_EIS_CMDTIMEOUT; +@@ -357,7 +359,7 @@ static void sdhci_send_command(SDHCIState *s) + + sdhci_update_irq(s); + +- if (s->blksize && (s->cmdreg & SDHC_CMD_DATA_PRESENT)) { ++ if (!timeout && s->blksize && (s->cmdreg & SDHC_CMD_DATA_PRESENT)) { + s->data_count = 0; + sdhci_data_transfer(s); + } +-- +2.27.0 + -- Gitee From f9606955cb1908ab4892ad8fc490568cdbc3030b Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 8 May 2021 10:47:12 +0800 Subject: [PATCH 2/7] hw/sd: sdhci: Don't write to SDHC_SYSAD register when transfer is in progress Fixes: CVE-2020-17380 Fixes: CVE-2020-25085 Fixes: CVE-2021-3409 Per "SD Host Controller Standard Specification Version 7.00" chapter 2.2.1 SDMA System Address Register: This register can be accessed only if no transaction is executing (i.e., after a transaction has stopped). With this fix, the following reproducer: outl 0xcf8 0x80001010 outl 0xcfc 0xfbefff00 outl 0xcf8 0x80001001 outl 0xcfc 0x06000000 write 0xfbefff2c 0x1 0x05 write 0xfbefff0f 0x1 0x37 write 0xfbefff0a 0x1 0x01 write 0xfbefff0f 0x1 0x29 write 0xfbefff0f 0x1 0x02 write 0xfbefff0f 0x1 0x03 write 0xfbefff04 0x1 0x01 write 0xfbefff05 0x1 0x01 write 0xfbefff07 0x1 0x02 write 0xfbefff0c 0x1 0x33 write 0xfbefff0e 0x1 0x20 write 0xfbefff0f 0x1 0x00 write 0xfbefff2a 0x1 0x01 write 0xfbefff0c 0x1 0x00 write 0xfbefff03 0x1 0x00 write 0xfbefff05 0x1 0x00 write 0xfbefff2a 0x1 0x02 write 0xfbefff0c 0x1 0x32 write 0xfbefff01 0x1 0x01 write 0xfbefff02 0x1 0x01 write 0xfbefff03 0x1 0x01 cannot be reproduced with the following QEMU command line: $ qemu-system-x86_64 -nographic -machine accel=qtest -m 512M \ -nodefaults -device sdhci-pci,sd-spec-version=3 \ -drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \ -device sd-card,drive=mydrive -qtest stdio Cc: qemu-stable@nongnu.org Fixes: CVE-2020-17380 Fixes: CVE-2020-25085 Fixes: CVE-2021-3409 Fixes: d7dfca0807a0 ("hw/sdhci: introduce standard SD host controller") Reported-by: Alexander Bulekov Reported-by: Cornelius Aschermann (Ruhr-University Bochum) Reported-by: Muhammad Ramdhan Reported-by: Sergej Schumilo (Ruhr-University Bochum) Reported-by: Simon Wrner (Ruhr-University Bochum) Buglink: https://bugs.launchpad.net/qemu/+bug/1892960 Buglink: https://bugs.launchpad.net/qemu/+bug/1909418 Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1928146 Signed-off-by: Bin Meng Tested-by: Alexander Bulekov Signed-off-by: Jiajie Li --- ...t-write-to-SDHC_SYSAD-register-when-.patch | 106 ++++++++++++++++++ 1 file changed, 106 insertions(+) create mode 100644 hw-sd-sdhci-Don-t-write-to-SDHC_SYSAD-register-when-.patch diff --git a/hw-sd-sdhci-Don-t-write-to-SDHC_SYSAD-register-when-.patch b/hw-sd-sdhci-Don-t-write-to-SDHC_SYSAD-register-when-.patch new file mode 100644 index 00000000..090e2f36 --- /dev/null +++ b/hw-sd-sdhci-Don-t-write-to-SDHC_SYSAD-register-when-.patch @@ -0,0 +1,106 @@ +From a6f48732a586d05cf3aa40db1290436810dcd023 Mon Sep 17 00:00:00 2001 +From: Bin Meng +Date: Sat, 8 May 2021 10:47:12 +0800 +Subject: [PATCH] hw/sd: sdhci: Don't write to SDHC_SYSAD register when + transfer is in progress + +Fixes: CVE-2020-17380 +Fixes: CVE-2020-25085 +Fixes: CVE-2021-3409 + +Per "SD Host Controller Standard Specification Version 7.00" +chapter 2.2.1 SDMA System Address Register: + +This register can be accessed only if no transaction is executing +(i.e., after a transaction has stopped). + +With this fix, the following reproducer: + +outl 0xcf8 0x80001010 +outl 0xcfc 0xfbefff00 +outl 0xcf8 0x80001001 +outl 0xcfc 0x06000000 +write 0xfbefff2c 0x1 0x05 +write 0xfbefff0f 0x1 0x37 +write 0xfbefff0a 0x1 0x01 +write 0xfbefff0f 0x1 0x29 +write 0xfbefff0f 0x1 0x02 +write 0xfbefff0f 0x1 0x03 +write 0xfbefff04 0x1 0x01 +write 0xfbefff05 0x1 0x01 +write 0xfbefff07 0x1 0x02 +write 0xfbefff0c 0x1 0x33 +write 0xfbefff0e 0x1 0x20 +write 0xfbefff0f 0x1 0x00 +write 0xfbefff2a 0x1 0x01 +write 0xfbefff0c 0x1 0x00 +write 0xfbefff03 0x1 0x00 +write 0xfbefff05 0x1 0x00 +write 0xfbefff2a 0x1 0x02 +write 0xfbefff0c 0x1 0x32 +write 0xfbefff01 0x1 0x01 +write 0xfbefff02 0x1 0x01 +write 0xfbefff03 0x1 0x01 + +cannot be reproduced with the following QEMU command line: + +$ qemu-system-x86_64 -nographic -machine accel=qtest -m 512M \ + -nodefaults -device sdhci-pci,sd-spec-version=3 \ + -drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \ + -device sd-card,drive=mydrive -qtest stdio + +Cc: qemu-stable@nongnu.org +Fixes: CVE-2020-17380 +Fixes: CVE-2020-25085 +Fixes: CVE-2021-3409 +Fixes: d7dfca0807a0 ("hw/sdhci: introduce standard SD host controller") +Reported-by: Alexander Bulekov +Reported-by: Cornelius Aschermann (Ruhr-University Bochum) +Reported-by: Muhammad Ramdhan +Reported-by: Sergej Schumilo (Ruhr-University Bochum) +Reported-by: Simon Wrner (Ruhr-University Bochum) +Buglink: https://bugs.launchpad.net/qemu/+bug/1892960 +Buglink: https://bugs.launchpad.net/qemu/+bug/1909418 +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1928146 +Signed-off-by: Bin Meng +Tested-by: Alexander Bulekov + +Signed-off-by: Jiajie Li +--- + hw/sd/sdhci.c | 20 +++++++++++--------- + 1 file changed, 11 insertions(+), 9 deletions(-) + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index a24f164e3f..6eca91d07c 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -1117,15 +1117,17 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) + + switch (offset & ~0x3) { + case SDHC_SYSAD: +- s->sdmasysad = (s->sdmasysad & mask) | value; +- MASKED_WRITE(s->sdmasysad, mask, value); +- /* Writing to last byte of sdmasysad might trigger transfer */ +- if (!(mask & 0xFF000000) && TRANSFERRING_DATA(s->prnsts) && s->blkcnt && +- s->blksize && SDHC_DMA_TYPE(s->hostctl1) == SDHC_CTRL_SDMA) { +- if (s->trnmod & SDHC_TRNS_MULTI) { +- sdhci_sdma_transfer_multi_blocks(s); +- } else { +- sdhci_sdma_transfer_single_block(s); ++ if (!TRANSFERRING_DATA(s->prnsts)) { ++ s->sdmasysad = (s->sdmasysad & mask) | value; ++ MASKED_WRITE(s->sdmasysad, mask, value); ++ /* Writing to last byte of sdmasysad might trigger transfer */ ++ if (!(mask & 0xFF000000) && s->blkcnt && s->blksize && ++ SDHC_DMA_TYPE(s->hostctl1) == SDHC_CTRL_SDMA) { ++ if (s->trnmod & SDHC_TRNS_MULTI) { ++ sdhci_sdma_transfer_multi_blocks(s); ++ } else { ++ sdhci_sdma_transfer_single_block(s); ++ } + } + } + break; +-- +2.27.0 + -- Gitee From fcfbc0d4e61edd775eb1b7347a63f6b8d1bf8427 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 8 May 2021 10:51:37 +0800 Subject: [PATCH 3/7] hw/sd: sdhci: Correctly set the controller status for ADMA MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: CVE-2020-17380 Fixes: CVE-2020-25085 Fixes: CVE-2021-3409 When an ADMA transfer is started, the codes forget to set the controller status to indicate a transfer is in progress. With this fix, the following 2 reproducers: https://paste.debian.net/plain/1185136 https://paste.debian.net/plain/1185141 cannot be reproduced with the following QEMU command line: $ qemu-system-x86_64 -nographic -machine accel=qtest -m 512M \ -nodefaults -device sdhci-pci,sd-spec-version=3 \ -drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \ -device sd-card,drive=mydrive -qtest stdio Cc: qemu-stable@nongnu.org Fixes: CVE-2020-17380 Fixes: CVE-2020-25085 Fixes: CVE-2021-3409 Fixes: d7dfca0807a0 ("hw/sdhci: introduce standard SD host controller") Reported-by: Alexander Bulekov Reported-by: Cornelius Aschermann (Ruhr-University Bochum) Reported-by: Muhammad Ramdhan Reported-by: Sergej Schumilo (Ruhr-University Bochum) Reported-by: Simon Wrner (Ruhr-University Bochum) Buglink: https://bugs.launchpad.net/qemu/+bug/1892960 Buglink: https://bugs.launchpad.net/qemu/+bug/1909418 Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1928146 Signed-off-by: Bin Meng Tested-by: Alexander Bulekov Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Jiajie Li --- ...ectly-set-the-controller-status-for-.patch | 75 +++++++++++++++++++ 1 file changed, 75 insertions(+) create mode 100644 hw-sd-sdhci-Correctly-set-the-controller-status-for-.patch diff --git a/hw-sd-sdhci-Correctly-set-the-controller-status-for-.patch b/hw-sd-sdhci-Correctly-set-the-controller-status-for-.patch new file mode 100644 index 00000000..500dfeed --- /dev/null +++ b/hw-sd-sdhci-Correctly-set-the-controller-status-for-.patch @@ -0,0 +1,75 @@ +From ada7d59499e98301f591f5a02940f22ddc4f6dbb Mon Sep 17 00:00:00 2001 +From: Bin Meng +Date: Sat, 8 May 2021 10:51:37 +0800 +Subject: [PATCH] hw/sd: sdhci: Correctly set the controller status for ADMA +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes: CVE-2020-17380 +Fixes: CVE-2020-25085 +Fixes: CVE-2021-3409 + +When an ADMA transfer is started, the codes forget to set the +controller status to indicate a transfer is in progress. + +With this fix, the following 2 reproducers: + +https://paste.debian.net/plain/1185136 +https://paste.debian.net/plain/1185141 + +cannot be reproduced with the following QEMU command line: + +$ qemu-system-x86_64 -nographic -machine accel=qtest -m 512M \ + -nodefaults -device sdhci-pci,sd-spec-version=3 \ + -drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \ + -device sd-card,drive=mydrive -qtest stdio + +Cc: qemu-stable@nongnu.org +Fixes: CVE-2020-17380 +Fixes: CVE-2020-25085 +Fixes: CVE-2021-3409 +Fixes: d7dfca0807a0 ("hw/sdhci: introduce standard SD host controller") +Reported-by: Alexander Bulekov +Reported-by: Cornelius Aschermann (Ruhr-University Bochum) +Reported-by: Muhammad Ramdhan +Reported-by: Sergej Schumilo (Ruhr-University Bochum) +Reported-by: Simon Wrner (Ruhr-University Bochum) +Buglink: https://bugs.launchpad.net/qemu/+bug/1892960 +Buglink: https://bugs.launchpad.net/qemu/+bug/1909418 +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1928146 +Signed-off-by: Bin Meng +Tested-by: Alexander Bulekov +Reviewed-by: Philippe Mathieu-Daudé + +Signed-off-by: Jiajie Li +--- + hw/sd/sdhci.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index 6eca91d07c..48e5333433 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -776,8 +776,9 @@ static void sdhci_do_adma(SDHCIState *s) + + switch (dscr.attr & SDHC_ADMA_ATTR_ACT_MASK) { + case SDHC_ADMA_ATTR_ACT_TRAN: /* data transfer */ +- ++ s->prnsts |= SDHC_DATA_INHIBIT | SDHC_DAT_LINE_ACTIVE; + if (s->trnmod & SDHC_TRNS_READ) { ++ s->prnsts |= SDHC_DOING_READ; + while (length) { + if (s->data_count == 0) { + for (n = 0; n < block_size; n++) { +@@ -807,6 +808,7 @@ static void sdhci_do_adma(SDHCIState *s) + } + } + } else { ++ s->prnsts |= SDHC_DOING_WRITE; + while (length) { + begin = s->data_count; + if ((length + begin) < block_size) { +-- +2.27.0 + -- Gitee From 42780901322eea43bd2327aa2c20e9203d14db0a Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 8 May 2021 11:02:27 +0800 Subject: [PATCH 4/7] hw/sd: sdhci: Limit block size only when SDHC_BLKSIZE register is writable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes: CVE-2020-17380 Fixes: CVE-2020-25085 Fixes: CVE-2021-3409 The codes to limit the maximum block size is only necessary when SDHC_BLKSIZE register is writable. Signed-off-by: Bin Meng Tested-by: Alexander Bulekov Reviewed-by: Philippe Mathieu-Daudé Signed-off-by: Jiajie Li --- ...t-block-size-only-when-SDHC_BLKSIZE-.patch | 55 +++++++++++++++++++ 1 file changed, 55 insertions(+) create mode 100644 hw-sd-sdhci-Limit-block-size-only-when-SDHC_BLKSIZE-.patch diff --git a/hw-sd-sdhci-Limit-block-size-only-when-SDHC_BLKSIZE-.patch b/hw-sd-sdhci-Limit-block-size-only-when-SDHC_BLKSIZE-.patch new file mode 100644 index 00000000..6fccd5c6 --- /dev/null +++ b/hw-sd-sdhci-Limit-block-size-only-when-SDHC_BLKSIZE-.patch @@ -0,0 +1,55 @@ +From cb61003c695d01c65262f7dcd7d0b78a53f787ec Mon Sep 17 00:00:00 2001 +From: Bin Meng +Date: Sat, 8 May 2021 11:02:27 +0800 +Subject: [PATCH] hw/sd: sdhci: Limit block size only when SDHC_BLKSIZE + register is writable +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fixes: CVE-2020-17380 +Fixes: CVE-2020-25085 +Fixes: CVE-2021-3409 + +The codes to limit the maximum block size is only necessary when +SDHC_BLKSIZE register is writable. + +Signed-off-by: Bin Meng +Tested-by: Alexander Bulekov +Reviewed-by: Philippe Mathieu-Daudé + +Signed-off-by: Jiajie Li +--- + hw/sd/sdhci.c | 14 +++++++------- + 1 file changed, 7 insertions(+), 7 deletions(-) + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index 48e5333433..f870907ea9 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -1137,15 +1137,15 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) + if (!TRANSFERRING_DATA(s->prnsts)) { + MASKED_WRITE(s->blksize, mask, value); + MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16); +- } + +- /* Limit block size to the maximum buffer size */ +- if (extract32(s->blksize, 0, 12) > s->buf_maxsz) { +- qemu_log_mask(LOG_GUEST_ERROR, "%s: Size 0x%x is larger than " \ +- "the maximum buffer 0x%x", __func__, s->blksize, +- s->buf_maxsz); ++ /* Limit block size to the maximum buffer size */ ++ if (extract32(s->blksize, 0, 12) > s->buf_maxsz) { ++ qemu_log_mask(LOG_GUEST_ERROR, "%s: Size 0x%x is larger than " \ ++ "the maximum buffer 0x%x\n", __func__, s->blksize, ++ s->buf_maxsz); + +- s->blksize = deposit32(s->blksize, 0, 12, s->buf_maxsz); ++ s->blksize = deposit32(s->blksize, 0, 12, s->buf_maxsz); ++ } + } + + break; +-- +2.27.0 + -- Gitee From c2e89e0fd91814479a74561bb91d7183f22d1c20 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Sat, 8 May 2021 11:05:47 +0800 Subject: [PATCH 5/7] hw/sd: sdhci: Reset the data pointer of s->fifo_buffer[] when a different block size is programmed Fixes: CVE-2020-17380 Fixes: CVE-2020-25085 Fixes: CVE-2021-3409 If the block size is programmed to a different value from the previous one, reset the data pointer of s->fifo_buffer[] so that s->fifo_buffer[] can be filled in using the new block size in the next transfer. With this fix, the following reproducer: outl 0xcf8 0x80001010 outl 0xcfc 0xe0000000 outl 0xcf8 0x80001001 outl 0xcfc 0x06000000 write 0xe000002c 0x1 0x05 write 0xe0000005 0x1 0x02 write 0xe0000007 0x1 0x01 write 0xe0000028 0x1 0x10 write 0x0 0x1 0x23 write 0x2 0x1 0x08 write 0xe000000c 0x1 0x01 write 0xe000000e 0x1 0x20 write 0xe000000f 0x1 0x00 write 0xe000000c 0x1 0x32 write 0xe0000004 0x2 0x0200 write 0xe0000028 0x1 0x00 write 0xe0000003 0x1 0x40 cannot be reproduced with the following QEMU command line: $ qemu-system-x86_64 -nographic -machine accel=qtest -m 512M \ -nodefaults -device sdhci-pci,sd-spec-version=3 \ -drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \ -device sd-card,drive=mydrive -qtest stdio Cc: qemu-stable@nongnu.org Fixes: CVE-2020-17380 Fixes: CVE-2020-25085 Fixes: CVE-2021-3409 Fixes: d7dfca0807a0 ("hw/sdhci: introduce standard SD host controller") Reported-by: Alexander Bulekov Reported-by: Cornelius Aschermann (Ruhr-University Bochum) Reported-by: Muhammad Ramdhan Reported-by: Sergej Schumilo (Ruhr-University Bochum) Reported-by: Simon Wrner (Ruhr-University Bochum) Buglink: https://bugs.launchpad.net/qemu/+bug/1892960 Buglink: https://bugs.launchpad.net/qemu/+bug/1909418 Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1928146 Signed-off-by: Bin Meng Tested-by: Alexander Bulekov Signed-off-by: Jiajie Li --- ...t-the-data-pointer-of-s-fifo_buffer-.patch | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 hw-sd-sdhci-Reset-the-data-pointer-of-s-fifo_buffer-.patch diff --git a/hw-sd-sdhci-Reset-the-data-pointer-of-s-fifo_buffer-.patch b/hw-sd-sdhci-Reset-the-data-pointer-of-s-fifo_buffer-.patch new file mode 100644 index 00000000..17d11a77 --- /dev/null +++ b/hw-sd-sdhci-Reset-the-data-pointer-of-s-fifo_buffer-.patch @@ -0,0 +1,98 @@ +From 3df07ae6621c8e4ac5e50361e7068dc92b3127ed Mon Sep 17 00:00:00 2001 +From: Bin Meng +Date: Sat, 8 May 2021 11:05:47 +0800 +Subject: [PATCH] hw/sd: sdhci: Reset the data pointer of s->fifo_buffer[] when + a different block size is programmed + +Fixes: CVE-2020-17380 +Fixes: CVE-2020-25085 +Fixes: CVE-2021-3409 + +If the block size is programmed to a different value from the +previous one, reset the data pointer of s->fifo_buffer[] so that +s->fifo_buffer[] can be filled in using the new block size in +the next transfer. + +With this fix, the following reproducer: + +outl 0xcf8 0x80001010 +outl 0xcfc 0xe0000000 +outl 0xcf8 0x80001001 +outl 0xcfc 0x06000000 +write 0xe000002c 0x1 0x05 +write 0xe0000005 0x1 0x02 +write 0xe0000007 0x1 0x01 +write 0xe0000028 0x1 0x10 +write 0x0 0x1 0x23 +write 0x2 0x1 0x08 +write 0xe000000c 0x1 0x01 +write 0xe000000e 0x1 0x20 +write 0xe000000f 0x1 0x00 +write 0xe000000c 0x1 0x32 +write 0xe0000004 0x2 0x0200 +write 0xe0000028 0x1 0x00 +write 0xe0000003 0x1 0x40 + +cannot be reproduced with the following QEMU command line: + +$ qemu-system-x86_64 -nographic -machine accel=qtest -m 512M \ + -nodefaults -device sdhci-pci,sd-spec-version=3 \ + -drive if=sd,index=0,file=null-co://,format=raw,id=mydrive \ + -device sd-card,drive=mydrive -qtest stdio + +Cc: qemu-stable@nongnu.org +Fixes: CVE-2020-17380 +Fixes: CVE-2020-25085 +Fixes: CVE-2021-3409 +Fixes: d7dfca0807a0 ("hw/sdhci: introduce standard SD host controller") +Reported-by: Alexander Bulekov +Reported-by: Cornelius Aschermann (Ruhr-University Bochum) +Reported-by: Muhammad Ramdhan +Reported-by: Sergej Schumilo (Ruhr-University Bochum) +Reported-by: Simon Wrner (Ruhr-University Bochum) +Buglink: https://bugs.launchpad.net/qemu/+bug/1892960 +Buglink: https://bugs.launchpad.net/qemu/+bug/1909418 +Buglink: https://bugzilla.redhat.com/show_bug.cgi?id=1928146 +Signed-off-by: Bin Meng +Tested-by: Alexander Bulekov + +Signed-off-by: Jiajie Li +--- + hw/sd/sdhci.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index f870907ea9..bcfba25691 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -1135,7 +1135,9 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) + break; + case SDHC_BLKSIZE: + if (!TRANSFERRING_DATA(s->prnsts)) { +- MASKED_WRITE(s->blksize, mask, value); ++ uint16_t blksize = s->blksize; ++ ++ MASKED_WRITE(s->blksize, mask, extract32(value, 0, 12)); + MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16); + + /* Limit block size to the maximum buffer size */ +@@ -1146,6 +1148,16 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) + + s->blksize = deposit32(s->blksize, 0, 12, s->buf_maxsz); + } ++ ++ /* ++ * If the block size is programmed to a different value from ++ * the previous one, reset the data pointer of s->fifo_buffer[] ++ * so that s->fifo_buffer[] can be filled in using the new block ++ * size in the next transfer. ++ */ ++ if (blksize != s->blksize) { ++ s->data_count = 0; ++ } + } + + break; +-- +2.27.0 + -- Gitee From 07547acf2d06b569ef3fcf57c7ed7ab5c6690baa Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Tue, 11 May 2021 11:26:59 +0800 Subject: [PATCH 6/7] spec: Update patch and changelog with !96 fix CVE-2021-3409 #I3E5M7 && fix CVE-2020-25085 #I3J7F2 !96 hw/sd: sdhci: Don't transfer any data when command time out hw/sd: sdhci: Don't write to SDHC_SYSAD register when transfer is in progress hw/sd: sdhci: Correctly set the controller status for ADMA hw/sd: sdhci: Limit block size only when SDHC_BLKSIZE register is writable hw/sd: sdhci: Reset the data pointer of s->fifo_buffer[] when a different block size is programmed Signed-off-by: Chen Qun --- qemu.spec | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/qemu.spec b/qemu.spec index 1b40ea1f..104f0935 100644 --- a/qemu.spec +++ b/qemu.spec @@ -320,6 +320,11 @@ Patch0307: sd-sdhci-assert-data_count-is-within-fifo_buffer.patch Patch0308: msix-add-valid.accepts-methods-to-check-address.patch Patch0309: ide-atapi-check-io_buffer_index-in-ide_atapi_cmd_rep.patch Patch0310: net-vmxnet3-validate-configuration-values-during-act.patch +Patch0311: hw-sd-sdhci-Don-t-transfer-any-data-when-command-tim.patch +Patch0312: hw-sd-sdhci-Don-t-write-to-SDHC_SYSAD-register-when-.patch +Patch0313: hw-sd-sdhci-Correctly-set-the-controller-status-for-.patch +Patch0314: hw-sd-sdhci-Limit-block-size-only-when-SDHC_BLKSIZE-.patch +Patch0315: hw-sd-sdhci-Reset-the-data-pointer-of-s-fifo_buffer-.patch BuildRequires: flex BuildRequires: bison @@ -666,6 +671,13 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Tue May 11 2021 Chen Qun +- hw/sd: sdhci: Don't transfer any data when command time out +- hw/sd: sdhci: Don't write to SDHC_SYSAD register when transfer is in progress +- hw/sd: sdhci: Correctly set the controller status for ADMA +- hw/sd: sdhci: Limit block size only when SDHC_BLKSIZE register is writable +- hw/sd: sdhci: Reset the data pointer of s->fifo_buffer[] when a different block size is programmed + * Thu Mar 18 2021 Chen Qun - net: vmxnet3: validate configuration values during activate (CVE-2021-20203) -- Gitee From e14029a90827b9a6a0c69968c3d62dc9647803b6 Mon Sep 17 00:00:00 2001 From: Chen Qun Date: Tue, 11 May 2021 11:27:02 +0800 Subject: [PATCH 7/7] spec: Update release version with !96 increase release verison by one Signed-off-by: Chen Qun --- qemu.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu.spec b/qemu.spec index 104f0935..c32a7aee 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 43 +Release: 44 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY -- Gitee