From e71b13a123d197f97bab5050377cb537516d1e0f Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sat, 8 May 2021 10:39:15 +0800 Subject: [PATCH 01/14] 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); } -- Gitee From f95d0c3bb20d33cfef35378fbfbd61b02544b2d4 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sat, 8 May 2021 10:47:12 +0800 Subject: [PATCH 02/14] 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; -- Gitee From 8d286a071877216c5b282bb14f34ff3b09d3f3f8 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sat, 8 May 2021 10:51:37 +0800 Subject: [PATCH 03/14] 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) { -- Gitee From f52bb54b58a81e92956510adb077c8ab416749d0 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sat, 8 May 2021 11:02:27 +0800 Subject: [PATCH 04/14] 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; -- Gitee From 6fd51eacd097284a68be623a455900ac26bb4604 Mon Sep 17 00:00:00 2001 From: Bin Meng Date: Sat, 8 May 2021 11:05:47 +0800 Subject: [PATCH 05/14] 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; -- Gitee From f34f6b6e78b8b3f401cc31a0d7c06a1c9ea9ad08 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 14 May 2021 10:14:02 +0800 Subject: [PATCH 06/14] 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, -- Gitee From 0eb0e31d48fa80dd1e57fc4b3c6ba288850ce380 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 14 May 2021 10:21:33 +0800 Subject: [PATCH 07/14] 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); } -- Gitee From 3c28d0dd733d8a7cf8417105fcd65d3cae226dce Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 14 May 2021 10:24:53 +0800 Subject: [PATCH 08/14] 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 */ -- Gitee From e36764a070b9caccf2ac7502f4656a81e2283823 Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 14 May 2021 10:30:23 +0800 Subject: [PATCH 09/14] 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); } -- Gitee From c75b8239c9505269c2ea9704a7af890f084edd7b Mon Sep 17 00:00:00 2001 From: Jason Wang Date: Fri, 14 May 2021 10:32:24 +0800 Subject: [PATCH 10/14] 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); } -- Gitee From beaa8c1788fa201ca4e4c8dc58b96c8d67ae8389 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Fri, 14 May 2021 10:35:11 +0800 Subject: [PATCH 11/14] 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); -- Gitee From 90e95b8873d1aa42ffc15f8d0e054d2b52453c5e Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Fri, 14 May 2021 10:37:29 +0800 Subject: [PATCH 12/14] 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) { -- Gitee From 22aa1e5315508da1ce8ec4565bbf2e525e79c6c2 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Fri, 14 May 2021 10:39:58 +0800 Subject: [PATCH 13/14] 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); -- Gitee From 827610834ff2a32522c73bee48984fff5521c389 Mon Sep 17 00:00:00 2001 From: Alexander Bulekov Date: Fri, 14 May 2021 10:41:41 +0800 Subject: [PATCH 14/14] 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); } -- Gitee