diff --git a/cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch b/cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch new file mode 100644 index 0000000000000000000000000000000000000000..afbe5ba945682039bbf7f8f795519bbbfd755d76 --- /dev/null +++ b/cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch @@ -0,0 +1,44 @@ +From 22aa1e5315508da1ce8ec4565bbf2e525e79c6c2 Mon Sep 17 00:00:00 2001 +From: Alexander Bulekov +Date: Fri, 14 May 2021 10:39:58 +0800 +Subject: [PATCH] cadence_gem: switch to use qemu_receive_packet() for loopback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix CVE-2021-3416 + +This patch switches to use qemu_receive_packet() which can detect +reentrancy and return early. + +This is intended to address CVE-2021-3416. + +Cc: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Alexander Bulekov +Signed-off-by: Jason Wang + +Signed-off-by: Jiajie Li +--- + hw/net/cadence_gem.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c +index d412085884..52205f36be 100644 +--- a/hw/net/cadence_gem.c ++++ b/hw/net/cadence_gem.c +@@ -1221,8 +1221,8 @@ static void gem_transmit(CadenceGEMState *s) + /* Send the packet somewhere */ + if (s->phy_loop || (s->regs[GEM_NWCTRL] & + GEM_NWCTRL_LOCALLOOP)) { +- gem_receive(qemu_get_queue(s->nic), tx_packet, +- total_bytes); ++ qemu_receive_packet(qemu_get_queue(s->nic), tx_packet, ++ total_bytes); + } else { + qemu_send_packet(qemu_get_queue(s->nic), tx_packet, + total_bytes); +-- +2.27.0 + diff --git a/dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch b/dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch new file mode 100644 index 0000000000000000000000000000000000000000..e103e063db59cd43009529dbb1ebbaf5a971d84c --- /dev/null +++ b/dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch @@ -0,0 +1,42 @@ +From 3c28d0dd733d8a7cf8417105fcd65d3cae226dce Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Fri, 14 May 2021 10:24:53 +0800 +Subject: [PATCH] dp8393x: switch to use qemu_receive_packet() for loopback + packet +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix CVE-2021-3416 + +This patch switches to use qemu_receive_packet() which can detect +reentrancy and return early. + +This is intended to address CVE-2021-3416. + +Cc: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Reviewed-by: Philippe Mathieu-Daudé + +Signed-off-by: Jiajie Li +--- + hw/net/dp8393x.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/dp8393x.c b/hw/net/dp8393x.c +index bdb0b3b2c2..a64da76bf3 100644 +--- a/hw/net/dp8393x.c ++++ b/hw/net/dp8393x.c +@@ -459,7 +459,7 @@ static void dp8393x_do_transmit_packets(dp8393xState *s) + s->regs[SONIC_TCR] |= SONIC_TCR_CRSL; + if (nc->info->can_receive(nc)) { + s->loopback_packet = 1; +- nc->info->receive(nc, s->tx_buffer, tx_len); ++ qemu_receive_packet(nc, s->tx_buffer, tx_len); + } + } else { + /* Transmit packet */ +-- +2.27.0 + diff --git a/e1000-switch-to-use-qemu_receive_packet-for-loopback.patch b/e1000-switch-to-use-qemu_receive_packet-for-loopback.patch new file mode 100644 index 0000000000000000000000000000000000000000..4890e184eb8e4095e9f83709450ea7884fbabaae --- /dev/null +++ b/e1000-switch-to-use-qemu_receive_packet-for-loopback.patch @@ -0,0 +1,41 @@ +From 0eb0e31d48fa80dd1e57fc4b3c6ba288850ce380 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Fri, 14 May 2021 10:21:33 +0800 +Subject: [PATCH] e1000: switch to use qemu_receive_packet() for loopback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix CVE-2021-3416 + +This patch switches to use qemu_receive_packet() which can detect +reentrancy and return early. + +This is intended to address CVE-2021-3416. + +Cc: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Jason Wang + +Signed-off-by: Jiajie Li +--- + hw/net/e1000.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/e1000.c b/hw/net/e1000.c +index a023ceb27c..a99aa3ccc3 100644 +--- a/hw/net/e1000.c ++++ b/hw/net/e1000.c +@@ -546,7 +546,7 @@ e1000_send_packet(E1000State *s, const uint8_t *buf, int size) + + NetClientState *nc = qemu_get_queue(s->nic); + if (s->phy_reg[PHY_CTRL] & MII_CR_LOOPBACK) { +- nc->info->receive(nc, buf, size); ++ qemu_receive_packet(nc, buf, size); + } else { + qemu_send_packet(nc, buf, size); + } +-- +2.27.0 + 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 0000000000000000000000000000000000000000..bcc2725e1ae86cd8c8cb4e04872e42a79a960b07 --- /dev/null +++ b/hw-sd-sdhci-Correctly-set-the-controller-status-for-.patch @@ -0,0 +1,75 @@ +From 8d286a071877216c5b282bb14f34ff3b09d3f3f8 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 fdb59f44e6..8c857d1e40 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 + 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 0000000000000000000000000000000000000000..ea461c09036af3fe2d0f5f506e8883d205fd8970 --- /dev/null +++ b/hw-sd-sdhci-Don-t-transfer-any-data-when-command-tim.patch @@ -0,0 +1,93 @@ +From e71b13a123d197f97bab5050377cb537516d1e0f 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 d4ee6bd01f..419782c25d 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 + 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 0000000000000000000000000000000000000000..7460614b6e876746f7306c124f8c54ec64fd0094 --- /dev/null +++ b/hw-sd-sdhci-Don-t-write-to-SDHC_SYSAD-register-when-.patch @@ -0,0 +1,106 @@ +From f95d0c3bb20d33cfef35378fbfbd61b02544b2d4 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 419782c25d..fdb59f44e6 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 + 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 0000000000000000000000000000000000000000..9176a4d9e8ea2286826e9f5b75a40a37b5e6781d --- /dev/null +++ b/hw-sd-sdhci-Limit-block-size-only-when-SDHC_BLKSIZE-.patch @@ -0,0 +1,55 @@ +From f52bb54b58a81e92956510adb077c8ab416749d0 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 8c857d1e40..4b8d9de50b 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, extract32(value, 0, 12)); + 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 + 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 0000000000000000000000000000000000000000..c5bc9569c58f29df1c4b928734bd8cf69dcba793 --- /dev/null +++ b/hw-sd-sdhci-Reset-the-data-pointer-of-s-fifo_buffer-.patch @@ -0,0 +1,96 @@ +From 6fd51eacd097284a68be623a455900ac26bb4604 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 | 12 ++++++++++++ + 1 file changed, 12 insertions(+) + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index 4b8d9de50b..bcfba25691 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -1135,6 +1135,8 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) + break; + case SDHC_BLKSIZE: + if (!TRANSFERRING_DATA(s->prnsts)) { ++ uint16_t blksize = s->blksize; ++ + MASKED_WRITE(s->blksize, mask, extract32(value, 0, 12)); + MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16); + +@@ -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 + diff --git a/lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch b/lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch new file mode 100644 index 0000000000000000000000000000000000000000..38de5a26b56ee7b260bf1b17cd1e514963aa0379 --- /dev/null +++ b/lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch @@ -0,0 +1,42 @@ +From 827610834ff2a32522c73bee48984fff5521c389 Mon Sep 17 00:00:00 2001 +From: Alexander Bulekov +Date: Fri, 14 May 2021 10:41:41 +0800 +Subject: [PATCH] lan9118: switch to use qemu_receive_packet() for loopback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix CVE-2021-3416 + +This patch switches to use qemu_receive_packet() which can detect +reentrancy and return early. + +This is intended to address CVE-2021-3416. + +Cc: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Jason Wang + +Signed-off-by: Jiajie Li +--- + hw/net/lan9118.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/lan9118.c b/hw/net/lan9118.c +index f6120be219..f1a1d2351e 100644 +--- a/hw/net/lan9118.c ++++ b/hw/net/lan9118.c +@@ -662,7 +662,7 @@ static void do_tx_packet(lan9118_state *s) + /* FIXME: Honor TX disable, and allow queueing of packets. */ + if (s->phy_control & 0x4000) { + /* This assumes the receive routine doesn't touch the VLANClient. */ +- lan9118_receive(qemu_get_queue(s->nic), s->txp->data, s->txp->len); ++ qemu_receive_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len); + } else { + qemu_send_packet(qemu_get_queue(s->nic), s->txp->data, s->txp->len); + } +-- +2.27.0 + diff --git a/net-introduce-qemu_receive_packet.patch b/net-introduce-qemu_receive_packet.patch new file mode 100644 index 0000000000000000000000000000000000000000..8bf6242b5bf68cdd059f5aa558a012b72a4d1c5c --- /dev/null +++ b/net-introduce-qemu_receive_packet.patch @@ -0,0 +1,167 @@ +From f34f6b6e78b8b3f401cc31a0d7c06a1c9ea9ad08 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Fri, 14 May 2021 10:14:02 +0800 +Subject: [PATCH] net: introduce qemu_receive_packet() + +Fix CVE-2021-3416 + +Some NIC supports loopback mode and this is done by calling +nc->info->receive() directly which in fact suppresses the effort of +reentrancy check that is done in qemu_net_queue_send(). + +Unfortunately we can use qemu_net_queue_send() here since for loop +back there's no sender as peer, so this patch introduce a +qemu_receive_packet() which is used for implementing loopback mode +for a NIC with this check. + +NIC that supports loopback mode will be converted to this helper. + +Signed-off-by: Jason Wang +Signed-off-by: Jiajie Li +--- + include/net/net.h | 5 +++++ + include/net/queue.h | 8 ++++++++ + net/net.c | 38 +++++++++++++++++++++++++++++++------- + net/queue.c | 22 ++++++++++++++++++++++ + 4 files changed, 66 insertions(+), 7 deletions(-) + +diff --git a/include/net/net.h b/include/net/net.h +index acf0451fc4..5609b2ecba 100644 +--- a/include/net/net.h ++++ b/include/net/net.h +@@ -143,12 +143,17 @@ void *qemu_get_nic_opaque(NetClientState *nc); + void qemu_del_net_client(NetClientState *nc); + typedef void (*qemu_nic_foreach)(NICState *nic, void *opaque); + void qemu_foreach_nic(qemu_nic_foreach func, void *opaque); ++int qemu_can_receive_packet(NetClientState *nc); + int qemu_can_send_packet(NetClientState *nc); + ssize_t qemu_sendv_packet(NetClientState *nc, const struct iovec *iov, + int iovcnt); + ssize_t qemu_sendv_packet_async(NetClientState *nc, const struct iovec *iov, + int iovcnt, NetPacketSent *sent_cb); + ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size); ++ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf,int size); ++ssize_t qemu_receive_packet_iov(NetClientState *nc, ++ const struct iovec *iov, ++ int iovcnt); + ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size); + ssize_t qemu_send_packet_async(NetClientState *nc, const uint8_t *buf, + int size, NetPacketSent *sent_cb); +diff --git a/include/net/queue.h b/include/net/queue.h +index c0269bb1dc..9f2f289d77 100644 +--- a/include/net/queue.h ++++ b/include/net/queue.h +@@ -55,6 +55,14 @@ void qemu_net_queue_append_iov(NetQueue *queue, + + void qemu_del_net_queue(NetQueue *queue); + ++ssize_t qemu_net_queue_receive(NetQueue *queue, ++ const uint8_t *data, ++ size_t size); ++ ++ssize_t qemu_net_queue_receive_iov(NetQueue *queue, ++ const struct iovec *iov, ++ int iovcnt); ++ + ssize_t qemu_net_queue_send(NetQueue *queue, + NetClientState *sender, + unsigned flags, +diff --git a/net/net.c b/net/net.c +index 7d4098254f..3b5631879c 100644 +--- a/net/net.c ++++ b/net/net.c +@@ -514,6 +514,17 @@ int qemu_set_vnet_be(NetClientState *nc, bool is_be) + #endif + } + ++int qemu_can_receive_packet(NetClientState *nc) ++{ ++ if (nc->receive_disabled) { ++ return 0; ++ } else if (nc->info->can_receive && ++ !nc->info->can_receive(nc)) { ++ return 0; ++ } ++ return 1; ++} ++ + int qemu_can_send_packet(NetClientState *sender) + { + int vm_running = runstate_is_running(); +@@ -526,13 +537,7 @@ int qemu_can_send_packet(NetClientState *sender) + return 1; + } + +- if (sender->peer->receive_disabled) { +- return 0; +- } else if (sender->peer->info->can_receive && +- !sender->peer->info->can_receive(sender->peer)) { +- return 0; +- } +- return 1; ++ return qemu_can_receive_packet(sender->peer); + } + + static ssize_t filter_receive_iov(NetClientState *nc, +@@ -665,6 +670,25 @@ ssize_t qemu_send_packet(NetClientState *nc, const uint8_t *buf, int size) + return qemu_send_packet_async(nc, buf, size, NULL); + } + ++ssize_t qemu_receive_packet(NetClientState *nc, const uint8_t *buf, int size) ++{ ++ if (!qemu_can_receive_packet(nc)) { ++ return 0; ++ } ++ ++ return qemu_net_queue_receive(nc->incoming_queue, buf, size); ++} ++ ++ssize_t qemu_receive_packet_iov(NetClientState *nc, const struct iovec *iov, ++ int iovcnt) ++{ ++ if (!qemu_can_receive_packet(nc)) { ++ return 0; ++ } ++ ++ return qemu_net_queue_receive_iov(nc->incoming_queue, iov, iovcnt); ++} ++ + ssize_t qemu_send_packet_raw(NetClientState *nc, const uint8_t *buf, int size) + { + return qemu_send_packet_async_with_flags(nc, QEMU_NET_PACKET_FLAG_RAW, +diff --git a/net/queue.c b/net/queue.c +index 61276ca4be..7c0b72c8ef 100644 +--- a/net/queue.c ++++ b/net/queue.c +@@ -182,6 +182,28 @@ static ssize_t qemu_net_queue_deliver_iov(NetQueue *queue, + return ret; + } + ++ssize_t qemu_net_queue_receive(NetQueue *queue, ++ const uint8_t *data, ++ size_t size) ++{ ++ if (queue->delivering) { ++ return 0; ++ } ++ ++ return qemu_net_queue_deliver(queue, NULL, 0, data, size); ++} ++ ++ssize_t qemu_net_queue_receive_iov(NetQueue *queue, ++ const struct iovec *iov, ++ int iovcnt) ++{ ++ if (queue->delivering) { ++ return 0; ++ } ++ ++ return qemu_net_queue_deliver_iov(queue, NULL, 0, iov, iovcnt); ++} ++ + ssize_t qemu_net_queue_send(NetQueue *queue, + NetClientState *sender, + unsigned flags, +-- +2.27.0 + diff --git a/pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch b/pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch new file mode 100644 index 0000000000000000000000000000000000000000..4ae51204790e42f2b75aa33bc29f79234dab300b --- /dev/null +++ b/pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch @@ -0,0 +1,43 @@ +From 90e95b8873d1aa42ffc15f8d0e054d2b52453c5e Mon Sep 17 00:00:00 2001 +From: Alexander Bulekov +Date: Fri, 14 May 2021 10:37:29 +0800 +Subject: [PATCH] pcnet: switch to use qemu_receive_packet() for loopback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix CVE-2021-3416 + +This patch switches to use qemu_receive_packet() which can detect +reentrancy and return early. + +This is intended to address CVE-2021-3416. + +Cc: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Buglink: https://bugs.launchpad.net/qemu/+bug/1917085 +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Jason Wang + +Signed-off-by: Jiajie Li +--- + hw/net/pcnet.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c +index 16683091c9..9e8d267536 100644 +--- a/hw/net/pcnet.c ++++ b/hw/net/pcnet.c +@@ -1249,7 +1249,7 @@ txagain: + if (BCR_SWSTYLE(s) == 1) + add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS); + s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; +- pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos); ++ qemu_receive_packet(qemu_get_queue(s->nic), s->buffer, s->xmit_pos); + s->looptest = 0; + } else { + if (s->nic) { +-- +2.27.0 + diff --git a/qemu.spec b/qemu.spec index 87b6a03b92a1368a14a339e559a0d102742a56e5..e7cc9efdea3115bf5e23210deb401045f09ec578 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 45 +Release: 46 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY-SA-4.0 @@ -287,6 +287,20 @@ Patch0274: migration-tls-fix-inverted-semantics-in-multifd_chan.patch Patch0275: migration-tls-add-error-handling-in-multifd_tls_hand.patch Patch0276: arm-cpu-Fixed-function-undefined-error-at-compile-ti.patch Patch0277: scsi-mptsas-dequeue-request-object-in-case-of-an-err.patch +Patch0278: hw-sd-sdhci-Don-t-transfer-any-data-when-command-tim.patch +Patch0279: hw-sd-sdhci-Don-t-write-to-SDHC_SYSAD-register-when-.patch +Patch0280: hw-sd-sdhci-Correctly-set-the-controller-status-for-.patch +Patch0281: hw-sd-sdhci-Limit-block-size-only-when-SDHC_BLKSIZE-.patch +Patch0282: hw-sd-sdhci-Reset-the-data-pointer-of-s-fifo_buffer-.patch +Patch0283: net-introduce-qemu_receive_packet.patch +Patch0284: e1000-switch-to-use-qemu_receive_packet-for-loopback.patch +Patch0285: dp8393x-switch-to-use-qemu_receive_packet-for-loopba.patch +Patch0286: sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch +Patch0287: tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch +Patch0288: rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch +Patch0289: pcnet-switch-to-use-qemu_receive_packet-for-loopback.patch +Patch0290: cadence_gem-switch-to-use-qemu_receive_packet-for-lo.patch +Patch0291: lan9118-switch-to-use-qemu_receive_packet-for-loopba.patch BuildRequires: flex BuildRequires: bison @@ -675,6 +689,22 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Thu May 20 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 +- net: introduce qemu_receive_packet() +- e1000: switch to use qemu_receive_packet() for loopback +- dp8393x: switch to use qemu_receive_packet() for loopback packet +- sungem: switch to use qemu_receive_packet() for loopback +- tx_pkt: switch to use qemu_receive_packet_iov() for loopback +- rtl8139: switch to use qemu_receive_packet() for loopback +- pcnet: switch to use qemu_receive_packet() for loopback +- cadence_gem: switch to use qemu_receive_packet() for loopback +- lan9118: switch to use qemu_receive_packet() for loopback + * Wed May 19 2021 Chen Qun - scsi: mptsas: dequeue request object in case of an error diff --git a/rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch b/rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch new file mode 100644 index 0000000000000000000000000000000000000000..070b88af9128e894bb63bace7f66d2b5f1944728 --- /dev/null +++ b/rtl8139-switch-to-use-qemu_receive_packet-for-loopba.patch @@ -0,0 +1,43 @@ +From beaa8c1788fa201ca4e4c8dc58b96c8d67ae8389 Mon Sep 17 00:00:00 2001 +From: Alexander Bulekov +Date: Fri, 14 May 2021 10:35:11 +0800 +Subject: [PATCH] rtl8139: switch to use qemu_receive_packet() for loopback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix CVE-2021-3416 + +This patch switches to use qemu_receive_packet() which can detect +reentrancy and return early. + +This is intended to address CVE-2021-3416. + +Cc: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Buglink: https://bugs.launchpad.net/qemu/+bug/1910826 +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Jason Wang + +Signed-off-by: Jiajie Li +--- + hw/net/rtl8139.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/rtl8139.c b/hw/net/rtl8139.c +index 09273171e5..79584fbb17 100644 +--- a/hw/net/rtl8139.c ++++ b/hw/net/rtl8139.c +@@ -1792,7 +1792,7 @@ static void rtl8139_transfer_frame(RTL8139State *s, uint8_t *buf, int size, + } + + DPRINTF("+++ transmit loopback mode\n"); +- rtl8139_do_receive(qemu_get_queue(s->nic), buf, size, do_interrupt); ++ qemu_receive_packet(qemu_get_queue(s->nic), buf, size); + + if (iov) { + g_free(buf2); +-- +2.27.0 + diff --git a/sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch b/sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch new file mode 100644 index 0000000000000000000000000000000000000000..eff54c5795a8b065cfb5eb5e8a05467d9053f93f --- /dev/null +++ b/sungem-switch-to-use-qemu_receive_packet-for-loopbac.patch @@ -0,0 +1,43 @@ +From e36764a070b9caccf2ac7502f4656a81e2283823 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Fri, 14 May 2021 10:30:23 +0800 +Subject: [PATCH] sungem: switch to use qemu_receive_packet() for loopback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix CVE-2021-3416 + +This patch switches to use qemu_receive_packet() which can detect +reentrancy and return early. + +This is intended to address CVE-2021-3416. + +Cc: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Reviewed-by: Mark Cave-Ayland +Reviewed-by: Philippe Mathieu-Daudé +Reviewed-by: Alistair Francis +Signed-off-by: Jason Wang + +Signed-off-by: Jiajie Li +--- + hw/net/sungem.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/sungem.c b/hw/net/sungem.c +index 89bcf749d1..37b62f62b8 100644 +--- a/hw/net/sungem.c ++++ b/hw/net/sungem.c +@@ -303,7 +303,7 @@ static void sungem_send_packet(SunGEMState *s, const uint8_t *buf, + NetClientState *nc = qemu_get_queue(s->nic); + + if (s->macregs[MAC_XIFCFG >> 2] & MAC_XIFCFG_LBCK) { +- nc->info->receive(nc, buf, size); ++ qemu_receive_packet(nc, buf, size); + } else { + qemu_send_packet(nc, buf, size); + } +-- +2.27.0 + diff --git a/tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch b/tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch new file mode 100644 index 0000000000000000000000000000000000000000..cac19234efcefbebd2653b009a182f28f65fa857 --- /dev/null +++ b/tx_pkt-switch-to-use-qemu_receive_packet_iov-for-loo.patch @@ -0,0 +1,41 @@ +From c75b8239c9505269c2ea9704a7af890f084edd7b Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Fri, 14 May 2021 10:32:24 +0800 +Subject: [PATCH] tx_pkt: switch to use qemu_receive_packet_iov() for loopback +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Fix CVE-2021-3416 + +This patch switches to use qemu_receive_receive_iov() which can detect +reentrancy and return early. + +This is intended to address CVE-2021-3416. + +Cc: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Reviewed-by: Philippe Mathieu-Daudé +Signed-off-by: Jason Wang + +Signed-off-by: Jiajie Li +--- + hw/net/net_tx_pkt.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c +index 54d4c3bbd0..646cdfaf4d 100644 +--- a/hw/net/net_tx_pkt.c ++++ b/hw/net/net_tx_pkt.c +@@ -544,7 +544,7 @@ static inline void net_tx_pkt_sendv(struct NetTxPkt *pkt, + NetClientState *nc, const struct iovec *iov, int iov_cnt) + { + if (pkt->is_loopback) { +- nc->info->receive_iov(nc, iov, iov_cnt); ++ qemu_receive_packet_iov(nc, iov, iov_cnt); + } else { + qemu_sendv_packet(nc, iov, iov_cnt); + } +-- +2.27.0 +