From 3b04b467759e9291861715a60adb50c13f99c92e Mon Sep 17 00:00:00 2001 From: Jiajie Li Date: Fri, 11 Sep 2020 10:30:16 +0800 Subject: [PATCH 01/13] Drop bogus IPv6 messages Drop IPv6 message shorter than what's mentioned in the payload length header (+ the size of the IPv6 header). They're invalid and could lead to data leakage in icmp6_send_echoreply(). --- Drop-bogus-IPv6-messages.patch | 30 ++++++++++++++++++++++++++++++ qemu.spec | 6 +++++- 2 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 Drop-bogus-IPv6-messages.patch diff --git a/Drop-bogus-IPv6-messages.patch b/Drop-bogus-IPv6-messages.patch new file mode 100644 index 00000000..2fc1e0e7 --- /dev/null +++ b/Drop-bogus-IPv6-messages.patch @@ -0,0 +1,30 @@ +From e8b555c08061ad78920611a5e98ee14fcd967692 Mon Sep 17 00:00:00 2001 +From: Ralf Haferkamp +Date: Fri, 11 Sep 2020 10:55:49 +0800 +Subject: [PATCH] Drop bogus IPv6 messages + +Drop IPv6 message shorter than what's mentioned in the playload +length header (+the size of IPv6 header). They're invalid and could +lead to data leakage in icmp6_send_echoreply(). + +diff --git a/slirp/src/ip6_input.c b/slirp/src/ip6_input.c +index d9d2b7e..c2dce52 100644 +--- a/slirp/src/ip6_input.c ++++ b/slirp/src/ip6_input.c +@@ -49,6 +49,13 @@ void ip6_input(struct mbuf *m) + goto bad; + } + ++ // Check if the message size is big enough to hold what's ++ // set in the payload length header. If not this is an invalid ++ // packet ++ if (m->m_len < ntohs(ip6->ip_pl) + sizeof(struct ip6)) { ++ goto bad; ++ } ++ + /* check ip_ttl for a correct ICMP reply */ + if (ip6->ip_hl == 0) { + icmp6_send_error(m, ICMP6_TIMXCEED, ICMP6_TIMXCEED_INTRANS); +-- +1.8.3.1 + diff --git a/qemu.spec b/qemu.spec index 115f3f6d..3faf3e9d 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 18 +Release: 19 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY @@ -184,6 +184,7 @@ Patch0171: megasas-use-unsigned-type-for-positive-numeric-field.patch Patch0172: hw-scsi-megasas-Fix-possible-out-of-bounds-array-acc.patch Patch0173: hw-arm-acpi-enable-SHPC-native-hot-plug.patch PATCH0174: hw-usb-core-fix-buffer-overflow.patch +Patch0175: Drop-bogus-IPv6-messages.patch BuildRequires: flex BuildRequires: bison @@ -529,6 +530,9 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Fri Sep 11 2020 Huawei Technologies Co., Ltd +- slirp/src/ip6_input.c: fix out-of-bounds read information vulnerablity + * Thu Aug 27 2020 Huawei Technologies Co., Ltd - hw/usb/core.c: fix buffer overflow in do_token_setup function -- Gitee From 74e366ee0f390d5f9476791ce9f5c50e13c101e5 Mon Sep 17 00:00:00 2001 From: Jiajie Li Date: Fri, 18 Sep 2020 19:36:20 +0800 Subject: [PATCH 02/13] Fix CVE-2020-25085 & CVE-2020-25084 Signed-off-by Jiajie Li --- ...ci-Fix-DMA-Transfer-Block-Size-field.patch | 25 +++++++++++++++ ...check-return-value-of-usb_packet_map.patch | 31 +++++++++++++++++++ qemu.spec | 8 ++++- 3 files changed, 63 insertions(+), 1 deletion(-) create mode 100644 hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch create mode 100644 hw-xhci-check-return-value-of-usb_packet_map.patch diff --git a/hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch b/hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch new file mode 100644 index 00000000..42df9650 --- /dev/null +++ b/hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch @@ -0,0 +1,25 @@ +From 8b8d3992db22a583b69b6e2ae1d9cd87e2179e21 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Fri, 18 Sep 2020 10:55:22 +0800 +Subject: [PATCH] hw/sd/sdhci: Fix DMA Transfer Block Size field The 'Transfer + Block Size' field is 12-bit wide. See section '2.2.2 Block Size Register + (Offset 004h)' in datasheet. + +Buglink: https://bugs.launchpad.net/qemu/+bug/1892960 + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index 7b80b1d9..acf482b8 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -1127,7 +1127,7 @@ 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); ++ MASKED_WRITE(s->blksize, mask, extract32(value, 0, 12)); + MASKED_WRITE(s->blkcnt, mask >> 16, value >> 16); + } + +-- +2.23.0 + diff --git a/hw-xhci-check-return-value-of-usb_packet_map.patch b/hw-xhci-check-return-value-of-usb_packet_map.patch new file mode 100644 index 00000000..fd81478d --- /dev/null +++ b/hw-xhci-check-return-value-of-usb_packet_map.patch @@ -0,0 +1,31 @@ +From e43f0019b0aff881c562c8d2428bce6b3d55845c Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Fri, 18 Sep 2020 11:08:28 +0800 +Subject: [PATCH] hw: xhci: check return value of 'usb_packet_map' + +Currently we don't check the return value of 'usb_packet_map', +this will cause an NAF issue. This is LP#1891341. +Following is the reproducer provided in: +-->https://bugs.launchpad.net/qemu/+bug/1891341 + +This patch fixes this. + +diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c +index a21485fe..3b25abca 100644 +--- a/hw/usb/hcd-xhci.c ++++ b/hw/usb/hcd-xhci.c +@@ -1614,7 +1614,10 @@ static int xhci_setup_packet(XHCITransfer *xfer) + xhci_xfer_create_sgl(xfer, dir == USB_TOKEN_IN); /* Also sets int_req */ + usb_packet_setup(&xfer->packet, dir, ep, xfer->streamid, + xfer->trbs[0].addr, false, xfer->int_req); +- usb_packet_map(&xfer->packet, &xfer->sgl); ++ if (usb_packet_map(&xfer->packet, &xfer->sgl)) { ++ qemu_sglist_destroy(&xfer->sgl); ++ return -1; ++ } + DPRINTF("xhci: setup packet pid 0x%x addr %d ep %d\n", + xfer->packet.pid, ep->dev->addr, ep->nr); + return 0; +-- +2.23.0 + diff --git a/qemu.spec b/qemu.spec index 3faf3e9d..b17fc5fe 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 19 +Release: 20 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY @@ -185,6 +185,8 @@ Patch0172: hw-scsi-megasas-Fix-possible-out-of-bounds-array-acc.patch Patch0173: hw-arm-acpi-enable-SHPC-native-hot-plug.patch PATCH0174: hw-usb-core-fix-buffer-overflow.patch Patch0175: Drop-bogus-IPv6-messages.patch +Patch0176: hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch +Patch0177: hw-xhci-check-return-value-of-usb_packet_map.patch BuildRequires: flex BuildRequires: bison @@ -530,6 +532,10 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Fri Sep 18 2020 Huawei Technologies Co., Ltd +- hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch +- hw-xhci-check-return-value-of-usb_packet_map.patch + * Fri Sep 11 2020 Huawei Technologies Co., Ltd - slirp/src/ip6_input.c: fix out-of-bounds read information vulnerablity -- Gitee From a7b090aaca1b1544d6ba9228647736878d493b34 Mon Sep 17 00:00:00 2001 From: AlexChen Date: Thu, 24 Sep 2020 10:47:29 +0800 Subject: [PATCH 03/13] qemu: enrich commit info for some patchs Signed-off-by: AlexChen --- ...ci-Fix-DMA-Transfer-Block-Size-field.patch | 23 +++++++-- ...check-return-value-of-usb_packet_map.patch | 49 +++++++++++++++++-- qemu.spec | 7 ++- 3 files changed, 69 insertions(+), 10 deletions(-) diff --git a/hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch b/hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch index 42df9650..4d4533a0 100644 --- a/hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch +++ b/hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch @@ -1,14 +1,27 @@ -From 8b8d3992db22a583b69b6e2ae1d9cd87e2179e21 Mon Sep 17 00:00:00 2001 +From d99d965c232c649686b4d8bc42dc11dcaf90dc0b Mon Sep 17 00:00:00 2001 From: Prasad J Pandit Date: Fri, 18 Sep 2020 10:55:22 +0800 -Subject: [PATCH] hw/sd/sdhci: Fix DMA Transfer Block Size field The 'Transfer - Block Size' field is 12-bit wide. See section '2.2.2 Block Size Register - (Offset 004h)' in datasheet. +Subject: [PATCH] hw/sd/sdhci: Fix DMA Transfer Block Size field +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit +The 'Transfer Block Size' field is 12-bit wide. + +See section '2.2.2. Block Size Register (Offset 004h)' in datasheet. + +Cc: qemu-stable@nongnu.org +Cc: Igor Mitsyanko Buglink: https://bugs.launchpad.net/qemu/+bug/1892960 +Fixes: d7dfca0807a ("hw/sdhci: introduce standard SD host controller") +Reported-by: Alexander Bulekov +Signed-off-by: Philippe Mathieu-Daudé +--- + hw/sd/sdhci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c -index 7b80b1d9..acf482b8 100644 +index 7b80b1d93f..65a530aee4 100644 --- a/hw/sd/sdhci.c +++ b/hw/sd/sdhci.c @@ -1127,7 +1127,7 @@ sdhci_write(void *opaque, hwaddr offset, uint64_t val, unsigned size) diff --git a/hw-xhci-check-return-value-of-usb_packet_map.patch b/hw-xhci-check-return-value-of-usb_packet_map.patch index fd81478d..7c31967f 100644 --- a/hw-xhci-check-return-value-of-usb_packet_map.patch +++ b/hw-xhci-check-return-value-of-usb_packet_map.patch @@ -1,17 +1,60 @@ -From e43f0019b0aff881c562c8d2428bce6b3d55845c Mon Sep 17 00:00:00 2001 +From ff7545a6911bc7b9d818a541130f666a81077b44 Mon Sep 17 00:00:00 2001 From: Li Qiang Date: Fri, 18 Sep 2020 11:08:28 +0800 Subject: [PATCH] hw: xhci: check return value of 'usb_packet_map' Currently we don't check the return value of 'usb_packet_map', -this will cause an NAF issue. This is LP#1891341. +this will cause an UAF issue. This is LP#1891341. Following is the reproducer provided in: -->https://bugs.launchpad.net/qemu/+bug/1891341 +cat << EOF | ./i386-softmmu/qemu-system-i386 -device nec-usb-xhci \ +-trace usb\* -device usb-audio -device usb-storage,drive=mydrive \ +-drive id=mydrive,file=null-co://,size=2M,format=raw,if=none \ +-nodefaults -nographic -qtest stdio +outl 0xcf8 0x80001016 +outl 0xcfc 0x3c009f0d +outl 0xcf8 0x80001004 +outl 0xcfc 0xc77695e +writel 0x9f0d000000000040 0xffff3655 +writeq 0x9f0d000000002000 0xff2f9e0000000000 +write 0x1d 0x1 0x27 +write 0x2d 0x1 0x2e +write 0x17232 0x1 0x03 +write 0x17254 0x1 0x06 +write 0x17278 0x1 0x34 +write 0x3d 0x1 0x27 +write 0x40 0x1 0x2e +write 0x41 0x1 0x72 +write 0x42 0x1 0x01 +write 0x4d 0x1 0x2e +write 0x4f 0x1 0x01 +writeq 0x9f0d000000002000 0x5c051a0100000000 +write 0x34001d 0x1 0x13 +write 0x340026 0x1 0x30 +write 0x340028 0x1 0x08 +write 0x34002c 0x1 0xfe +write 0x34002d 0x1 0x08 +write 0x340037 0x1 0x5e +write 0x34003a 0x1 0x05 +write 0x34003d 0x1 0x05 +write 0x34004d 0x1 0x13 +writeq 0x9f0d000000002000 0xff00010100400009 +EOF + This patch fixes this. +Buglink: https://bugs.launchpad.net/qemu/+bug/1891341 +Reported-by: Alexander Bulekov +Signed-off-by: Li Qiang +Message-id: 20200812153139.15146-1-liq3ea@163.com +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-xhci.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + diff --git a/hw/usb/hcd-xhci.c b/hw/usb/hcd-xhci.c -index a21485fe..3b25abca 100644 +index a21485fe8a..3b25abcacd 100644 --- a/hw/usb/hcd-xhci.c +++ b/hw/usb/hcd-xhci.c @@ -1614,7 +1614,10 @@ static int xhci_setup_packet(XHCITransfer *xfer) diff --git a/qemu.spec b/qemu.spec index b17fc5fe..7bf64985 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 20 +Release: 21 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY @@ -183,7 +183,7 @@ Patch0170: megasas-avoid-NULL-pointer-dereference.patch Patch0171: megasas-use-unsigned-type-for-positive-numeric-field.patch Patch0172: hw-scsi-megasas-Fix-possible-out-of-bounds-array-acc.patch Patch0173: hw-arm-acpi-enable-SHPC-native-hot-plug.patch -PATCH0174: hw-usb-core-fix-buffer-overflow.patch +Patch0174: hw-usb-core-fix-buffer-overflow.patch Patch0175: Drop-bogus-IPv6-messages.patch Patch0176: hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch Patch0177: hw-xhci-check-return-value-of-usb_packet_map.patch @@ -532,6 +532,9 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Thu Sep 24 2020 Huawei Technologies Co., Ltd +- enrich commit info for some patchs + * Fri Sep 18 2020 Huawei Technologies Co., Ltd - hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch - hw-xhci-check-return-value-of-usb_packet_map.patch -- Gitee From 06f886beec4dbafa1b151f1f9752a94c68793bda Mon Sep 17 00:00:00 2001 From: AlexChen Date: Thu, 24 Sep 2020 10:59:22 +0800 Subject: [PATCH 04/13] qemu: rename some patches for slirp Signed-off-by: AlexChen --- qemu.spec | 13 +++++++------ ...es.patch => slirp-drop-bogus-IPv6-messages.patch | 0 ...patch => slirp-ip_reass-Fix-use-after-free.patch | 0 ...cess.patch => slirp-tcp_emu-Fix-oob-access.patch | 0 ...> slirp-tcp_emu-fix-unsafe-snprintf-usages.patch | 0 ....patch => slirp-util-add-slirp_fmt-helpers.patch | 0 6 files changed, 7 insertions(+), 6 deletions(-) rename Drop-bogus-IPv6-messages.patch => slirp-drop-bogus-IPv6-messages.patch (100%) rename ip_reass-Fix-use-after-free.patch => slirp-ip_reass-Fix-use-after-free.patch (100%) rename tcp_emu-Fix-oob-access.patch => slirp-tcp_emu-Fix-oob-access.patch (100%) rename tcp_emu-fix-unsafe-snprintf-usages.patch => slirp-tcp_emu-fix-unsafe-snprintf-usages.patch (100%) rename util-add-slirp_fmt-helpers.patch => slirp-util-add-slirp_fmt-helpers.patch (100%) diff --git a/qemu.spec b/qemu.spec index 7bf64985..ddf8110a 100644 --- a/qemu.spec +++ b/qemu.spec @@ -40,11 +40,11 @@ Patch0027: nbd-fix-uninitialized-variable-warning.patch Patch0028: xhci-Fix-memory-leak-in-xhci_kick_epctx-when-poweroff.patch Patch0029: block-fix-memleaks-in-bdrv_refresh_filename.patch Patch0030: iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch -Patch0031: tcp_emu-Fix-oob-access.patch +Patch0031: slirp-tcp_emu-Fix-oob-access.patch Patch0032: slirp-use-correct-size-while-emulating-IRC-commands.patch Patch0033: slirp-use-correct-size-while-emulating-commands.patch -Patch0034: util-add-slirp_fmt-helpers.patch -Patch0035: tcp_emu-fix-unsafe-snprintf-usages.patch +Patch0034: slirp-util-add-slirp_fmt-helpers.patch +Patch0035: slirp-tcp_emu-fix-unsafe-snprintf-usages.patch Patch0036: block-iscsi-use-MIN-between-mx_sb_len-and-sb_len_wr.patch Patch0037: monitor-fix-memory-leak-in-monitor_fdset_dup_fd_find.patch Patch0038: memory-Align-MemoryRegionSections-fields.patch @@ -165,7 +165,7 @@ Patch0152: arm-virt-Support-CPU-cold-plug.patch Patch0153: ide-Fix-incorrect-handling-of-some-PRDTs-in-ide_dma_.patch Patch0154: ati-vga-Fix-checks-in-ati_2d_blt-to-avoid-crash.patch Patch0155: slirp-tftp-restrict-relative-path-access.patch -Patch0156: ip_reass-Fix-use-after-free.patch +Patch0156: slirp-ip_reass-Fix-use-after-free.patch Patch0157: bt-use-size_t-type-for-length-parameters-instead-of-.patch Patch0158: log-Add-some-logs-on-VM-runtime-path.patch Patch0159: Revert-vtimer-compat-cross-version-migration-from-v4.patch @@ -184,7 +184,7 @@ Patch0171: megasas-use-unsigned-type-for-positive-numeric-field.patch Patch0172: hw-scsi-megasas-Fix-possible-out-of-bounds-array-acc.patch Patch0173: hw-arm-acpi-enable-SHPC-native-hot-plug.patch Patch0174: hw-usb-core-fix-buffer-overflow.patch -Patch0175: Drop-bogus-IPv6-messages.patch +Patch0175: slirp-drop-bogus-IPv6-messages.patch Patch0176: hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch Patch0177: hw-xhci-check-return-value-of-usb_packet_map.patch @@ -533,7 +533,8 @@ getent passwd qemu >/dev/null || \ %changelog * Thu Sep 24 2020 Huawei Technologies Co., Ltd -- enrich commit info for some patchs +- enrich commit info for some patches +- rename some patches for slirp * Fri Sep 18 2020 Huawei Technologies Co., Ltd - hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch diff --git a/Drop-bogus-IPv6-messages.patch b/slirp-drop-bogus-IPv6-messages.patch similarity index 100% rename from Drop-bogus-IPv6-messages.patch rename to slirp-drop-bogus-IPv6-messages.patch diff --git a/ip_reass-Fix-use-after-free.patch b/slirp-ip_reass-Fix-use-after-free.patch similarity index 100% rename from ip_reass-Fix-use-after-free.patch rename to slirp-ip_reass-Fix-use-after-free.patch diff --git a/tcp_emu-Fix-oob-access.patch b/slirp-tcp_emu-Fix-oob-access.patch similarity index 100% rename from tcp_emu-Fix-oob-access.patch rename to slirp-tcp_emu-Fix-oob-access.patch diff --git a/tcp_emu-fix-unsafe-snprintf-usages.patch b/slirp-tcp_emu-fix-unsafe-snprintf-usages.patch similarity index 100% rename from tcp_emu-fix-unsafe-snprintf-usages.patch rename to slirp-tcp_emu-fix-unsafe-snprintf-usages.patch diff --git a/util-add-slirp_fmt-helpers.patch b/slirp-util-add-slirp_fmt-helpers.patch similarity index 100% rename from util-add-slirp_fmt-helpers.patch rename to slirp-util-add-slirp_fmt-helpers.patch -- Gitee From 2a884f8abb6ac59dc4461fe0d239e8d791d56855 Mon Sep 17 00:00:00 2001 From: Mauro Matteo Cascella Date: Fri, 10 Jul 2020 11:19:41 +0200 Subject: [PATCH 05/13] hw/net/xgmac: Fix buffer overflow in xgmac_enet_send() A buffer overflow issue was reported by Mr. Ziming Zhang, CC'd here. It occurs while sending an Ethernet frame due to missing break statements and improper checking of the buffer size. Reported-by: Ziming Zhang Signed-off-by: Mauro Matteo Cascella Reviewed-by: Peter Maydell Signed-off-by: Jason Wang --- ...x-buffer-overflow-in-xgmac_enet_send.patch | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 hw-net-xgmac-Fix-buffer-overflow-in-xgmac_enet_send.patch diff --git a/hw-net-xgmac-Fix-buffer-overflow-in-xgmac_enet_send.patch b/hw-net-xgmac-Fix-buffer-overflow-in-xgmac_enet_send.patch new file mode 100644 index 00000000..778be396 --- /dev/null +++ b/hw-net-xgmac-Fix-buffer-overflow-in-xgmac_enet_send.patch @@ -0,0 +1,58 @@ +From a80a85c7c358febb164ace0dfa75c468f43e0f02 Mon Sep 17 00:00:00 2001 +From: Mauro Matteo Cascella +Date: Fri, 10 Jul 2020 11:19:41 +0200 +Subject: [PATCH] hw/net/xgmac: Fix buffer overflow in xgmac_enet_send() + +A buffer overflow issue was reported by Mr. Ziming Zhang, CC'd here. It +occurs while sending an Ethernet frame due to missing break statements +and improper checking of the buffer size. + +Reported-by: Ziming Zhang +Signed-off-by: Mauro Matteo Cascella +Reviewed-by: Peter Maydell +Signed-off-by: Jason Wang +--- + hw/net/xgmac.c | 14 ++++++++++++-- + 1 file changed, 12 insertions(+), 2 deletions(-) + +diff --git a/hw/net/xgmac.c b/hw/net/xgmac.c +index f49df95b07..f496f7ed4c 100644 +--- a/hw/net/xgmac.c ++++ b/hw/net/xgmac.c +@@ -217,21 +217,31 @@ static void xgmac_enet_send(XgmacState *s) + } + len = (bd.buffer1_size & 0xfff) + (bd.buffer2_size & 0xfff); + ++ /* ++ * FIXME: these cases of malformed tx descriptors (bad sizes) ++ * should probably be reported back to the guest somehow ++ * rather than simply silently stopping processing, but we ++ * don't know what the hardware does in this situation. ++ * This will only happen for buggy guests anyway. ++ */ + if ((bd.buffer1_size & 0xfff) > 2048) { + DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- " + "xgmac buffer 1 len on send > 2048 (0x%x)\n", + __func__, bd.buffer1_size & 0xfff); ++ break; + } + if ((bd.buffer2_size & 0xfff) != 0) { + DEBUGF_BRK("qemu:%s:ERROR...ERROR...ERROR... -- " + "xgmac buffer 2 len on send != 0 (0x%x)\n", + __func__, bd.buffer2_size & 0xfff); ++ break; + } +- if (len >= sizeof(frame)) { ++ if (frame_size + len >= sizeof(frame)) { + DEBUGF_BRK("qemu:%s: buffer overflow %d read into %zu " +- "buffer\n" , __func__, len, sizeof(frame)); ++ "buffer\n" , __func__, frame_size + len, sizeof(frame)); + DEBUGF_BRK("qemu:%s: buffer1.size=%d; buffer2.size=%d\n", + __func__, bd.buffer1_size, bd.buffer2_size); ++ break; + } + + cpu_physical_memory_read(bd.buffer1_addr, ptr, len); +-- +2.23.0 + -- Gitee From c30f07caded214d481e809b0150e86482f96112c Mon Sep 17 00:00:00 2001 From: Mauro Matteo Cascella Date: Sat, 1 Aug 2020 18:42:38 +0200 Subject: [PATCH 06/13] hw/net/net_tx_pkt: fix assertion failure in net_tx_pkt_add_raw_fragment() An assertion failure issue was found in the code that processes network packets while adding data fragments into the packet context. It could be abused by a malicious guest to abort the QEMU process on the host. This patch replaces the affected assert() with a conditional statement, returning false if the current data fragment exceeds max_raw_frags. Reported-by: Alexander Bulekov Reported-by: Ziming Zhang Reviewed-by: Dmitry Fleytman Signed-off-by: Mauro Matteo Cascella Signed-off-by: Jason Wang --- ...t-fix-assertion-failure-in-net_tx_pk.patch | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 hw-net-net_tx_pkt-fix-assertion-failure-in-net_tx_pk.patch diff --git a/hw-net-net_tx_pkt-fix-assertion-failure-in-net_tx_pk.patch b/hw-net-net_tx_pkt-fix-assertion-failure-in-net_tx_pk.patch new file mode 100644 index 00000000..15fcf571 --- /dev/null +++ b/hw-net-net_tx_pkt-fix-assertion-failure-in-net_tx_pk.patch @@ -0,0 +1,40 @@ +From d65a00000e56ee2cec2f506b1408128d2df56ad9 Mon Sep 17 00:00:00 2001 +From: Mauro Matteo Cascella +Date: Sat, 1 Aug 2020 18:42:38 +0200 +Subject: [PATCH] hw/net/net_tx_pkt: fix assertion failure in + net_tx_pkt_add_raw_fragment() + +An assertion failure issue was found in the code that processes network packets +while adding data fragments into the packet context. It could be abused by a +malicious guest to abort the QEMU process on the host. This patch replaces the +affected assert() with a conditional statement, returning false if the current +data fragment exceeds max_raw_frags. + +Reported-by: Alexander Bulekov +Reported-by: Ziming Zhang +Reviewed-by: Dmitry Fleytman +Signed-off-by: Mauro Matteo Cascella +Signed-off-by: Jason Wang +--- + hw/net/net_tx_pkt.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/hw/net/net_tx_pkt.c b/hw/net/net_tx_pkt.c +index 162f802dd7..54d4c3bbd0 100644 +--- a/hw/net/net_tx_pkt.c ++++ b/hw/net/net_tx_pkt.c +@@ -379,7 +379,10 @@ bool net_tx_pkt_add_raw_fragment(struct NetTxPkt *pkt, hwaddr pa, + hwaddr mapped_len = 0; + struct iovec *ventry; + assert(pkt); +- assert(pkt->max_raw_frags > pkt->raw_frags); ++ ++ if (pkt->raw_frags >= pkt->max_raw_frags) { ++ return false; ++ } + + if (!len) { + return true; +-- +2.23.0 + -- Gitee From 50dcc20a59b9f7f91f9a8f2f59d0a91ab6e37d96 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Thu, 21 May 2020 21:39:44 +0200 Subject: [PATCH 07/13] sm501: Convert printf + abort to qemu_log_mask MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some places already use qemu_log_mask() to log unimplemented features or errors but some others have printf() then abort(). Convert these to qemu_log_mask() and avoid aborting to prevent guests to easily cause denial of service. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-id: 305af87f59d81e92f2aaff09eb8a3603b8baa322.1590089984.git.balaton@eik.bme.hu Signed-off-by: Gerd Hoffmann --- ...onvert-printf-abort-to-qemu_log_mask.patch | 159 ++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 sm501-Convert-printf-abort-to-qemu_log_mask.patch diff --git a/sm501-Convert-printf-abort-to-qemu_log_mask.patch b/sm501-Convert-printf-abort-to-qemu_log_mask.patch new file mode 100644 index 00000000..a1516561 --- /dev/null +++ b/sm501-Convert-printf-abort-to-qemu_log_mask.patch @@ -0,0 +1,159 @@ +From c52852158aa010d534ee6d1c7a44f72ef87857a3 Mon Sep 17 00:00:00 2001 +From: BALATON Zoltan +Date: Thu, 21 May 2020 21:39:44 +0200 +Subject: [PATCH] sm501: Convert printf + abort to qemu_log_mask +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Some places already use qemu_log_mask() to log unimplemented features +or errors but some others have printf() then abort(). Convert these to +qemu_log_mask() and avoid aborting to prevent guests to easily cause +denial of service. + +Signed-off-by: BALATON Zoltan +Reviewed-by: Philippe Mathieu-Daudé +Message-id: 305af87f59d81e92f2aaff09eb8a3603b8baa322.1590089984.git.balaton@eik.bme.hu +Signed-off-by: Gerd Hoffmann +--- + hw/display/sm501.c | 57 ++++++++++++++++++++++------------------------ + 1 file changed, 27 insertions(+), 30 deletions(-) + +diff --git a/hw/display/sm501.c b/hw/display/sm501.c +index 5918f59b2b..aa4b202a48 100644 +--- a/hw/display/sm501.c ++++ b/hw/display/sm501.c +@@ -727,8 +727,8 @@ static void sm501_2d_operation(SM501State *s) + int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt); + + if (addressing != 0x0) { +- printf("%s: only XY addressing is supported.\n", __func__); +- abort(); ++ qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n"); ++ return; + } + + if (rop_mode == 0) { +@@ -754,8 +754,8 @@ static void sm501_2d_operation(SM501State *s) + + if ((s->twoD_source_base & 0x08000000) || + (s->twoD_destination_base & 0x08000000)) { +- printf("%s: only local memory is supported.\n", __func__); +- abort(); ++ qemu_log_mask(LOG_UNIMP, "sm501: only local memory is supported.\n"); ++ return; + } + + switch (operation) { +@@ -823,9 +823,9 @@ static void sm501_2d_operation(SM501State *s) + break; + + default: +- printf("non-implemented SM501 2D operation. %d\n", operation); +- abort(); +- break; ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2D operation: %d\n", ++ operation); ++ return; + } + + if (dst_base >= get_fb_addr(s, crt) && +@@ -892,9 +892,8 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr, + break; + + default: +- printf("sm501 system config : not implemented register read." +- " addr=%x\n", (int)addr); +- abort(); ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented system config" ++ "register read. addr=%" HWADDR_PRIx "\n", addr); + } + + return ret; +@@ -948,15 +947,15 @@ static void sm501_system_config_write(void *opaque, hwaddr addr, + break; + case SM501_ENDIAN_CONTROL: + if (value & 0x00000001) { +- printf("sm501 system config : big endian mode not implemented.\n"); +- abort(); ++ qemu_log_mask(LOG_UNIMP, "sm501: system config big endian mode not" ++ " implemented.\n"); + } + break; + + default: +- printf("sm501 system config : not implemented register write." +- " addr=%x, val=%x\n", (int)addr, (uint32_t)value); +- abort(); ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented system config" ++ "register write. addr=%" HWADDR_PRIx ++ ", val=%" PRIx64 "\n", addr, value); + } + } + +@@ -1207,9 +1206,8 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr, + break; + + default: +- printf("sm501 disp ctrl : not implemented register read." +- " addr=%x\n", (int)addr); +- abort(); ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register " ++ "read. addr=%" HWADDR_PRIx "\n", addr); + } + + return ret; +@@ -1345,9 +1343,9 @@ static void sm501_disp_ctrl_write(void *opaque, hwaddr addr, + break; + + default: +- printf("sm501 disp ctrl : not implemented register write." +- " addr=%x, val=%x\n", (int)addr, (unsigned)value); +- abort(); ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register " ++ "write. addr=%" HWADDR_PRIx ++ ", val=%" PRIx64 "\n", addr, value); + } + } + +@@ -1433,9 +1431,8 @@ static uint64_t sm501_2d_engine_read(void *opaque, hwaddr addr, + ret = 0; /* Should return interrupt status */ + break; + default: +- printf("sm501 disp ctrl : not implemented register read." +- " addr=%x\n", (int)addr); +- abort(); ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented disp ctrl register " ++ "read. addr=%" HWADDR_PRIx "\n", addr); + } + + return ret; +@@ -1520,9 +1517,9 @@ static void sm501_2d_engine_write(void *opaque, hwaddr addr, + /* ignored, writing 0 should clear interrupt status */ + break; + default: +- printf("sm501 2d engine : not implemented register write." +- " addr=%x, val=%x\n", (int)addr, (unsigned)value); +- abort(); ++ qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2d engine register " ++ "write. addr=%" HWADDR_PRIx ++ ", val=%" PRIx64 "\n", addr, value); + } + } + +@@ -1670,9 +1667,9 @@ static void sm501_update_display(void *opaque) + draw_line = draw_line32_funcs[dst_depth_index]; + break; + default: +- printf("sm501 update display : invalid control register value.\n"); +- abort(); +- break; ++ qemu_log_mask(LOG_GUEST_ERROR, "sm501: update display" ++ "invalid control register value.\n"); ++ return; + } + + /* set up to draw hardware cursor */ +-- +2.23.0 + -- Gitee From ef912f66296bf880f6aaedf8bbfe494bddc6ab75 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Thu, 21 May 2020 21:39:44 +0200 Subject: [PATCH 08/13] sm501: Shorten long variable names in sm501_2d_operation This increases readability and cleans up some confusing naming. Signed-off-by: BALATON Zoltan Message-id: b9b67b94c46e945252a73c77dfd117132c63c4fb.1590089984.git.balaton@eik.bme.hu Signed-off-by: Gerd Hoffmann --- ...ng-variable-names-in-sm501_2d_operat.patch | 134 ++++++++++++++++++ 1 file changed, 134 insertions(+) create mode 100644 sm501-Shorten-long-variable-names-in-sm501_2d_operat.patch diff --git a/sm501-Shorten-long-variable-names-in-sm501_2d_operat.patch b/sm501-Shorten-long-variable-names-in-sm501_2d_operat.patch new file mode 100644 index 00000000..9214016b --- /dev/null +++ b/sm501-Shorten-long-variable-names-in-sm501_2d_operat.patch @@ -0,0 +1,134 @@ +From 54c647d867891b58084d6b36ac2db794c19bed22 Mon Sep 17 00:00:00 2001 +From: BALATON Zoltan +Date: Thu, 21 May 2020 21:39:44 +0200 +Subject: [PATCH] sm501: Shorten long variable names in sm501_2d_operation + +This increases readability and cleans up some confusing naming. + +Signed-off-by: BALATON Zoltan +Message-id: b9b67b94c46e945252a73c77dfd117132c63c4fb.1590089984.git.balaton@eik.bme.hu +Signed-off-by: Gerd Hoffmann +--- + hw/display/sm501.c | 45 ++++++++++++++++++++++----------------------- + 1 file changed, 22 insertions(+), 23 deletions(-) + +diff --git a/hw/display/sm501.c b/hw/display/sm501.c +index aa4b202a48..51e7ccc39d 100644 +--- a/hw/display/sm501.c ++++ b/hw/display/sm501.c +@@ -700,17 +700,16 @@ static inline void hwc_invalidate(SM501State *s, int crt) + static void sm501_2d_operation(SM501State *s) + { + /* obtain operation parameters */ +- int operation = (s->twoD_control >> 16) & 0x1f; ++ int cmd = (s->twoD_control >> 16) & 0x1F; + int rtl = s->twoD_control & 0x8000000; + int src_x = (s->twoD_source >> 16) & 0x01FFF; + int src_y = s->twoD_source & 0xFFFF; + int dst_x = (s->twoD_destination >> 16) & 0x01FFF; + int dst_y = s->twoD_destination & 0xFFFF; +- int operation_width = (s->twoD_dimension >> 16) & 0x1FFF; +- int operation_height = s->twoD_dimension & 0xFFFF; ++ int width = (s->twoD_dimension >> 16) & 0x1FFF; ++ int height = s->twoD_dimension & 0xFFFF; + uint32_t color = s->twoD_foreground; +- int format_flags = (s->twoD_stretch >> 20) & 0x3; +- int addressing = (s->twoD_stretch >> 16) & 0xF; ++ int format = (s->twoD_stretch >> 20) & 0x3; + int rop_mode = (s->twoD_control >> 15) & 0x1; /* 1 for rop2, else rop3 */ + /* 1 if rop2 source is the pattern, otherwise the source is the bitmap */ + int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1; +@@ -721,12 +720,12 @@ static void sm501_2d_operation(SM501State *s) + /* get frame buffer info */ + uint8_t *src = s->local_mem + src_base; + uint8_t *dst = s->local_mem + dst_base; +- int src_width = s->twoD_pitch & 0x1FFF; +- int dst_width = (s->twoD_pitch >> 16) & 0x1FFF; ++ int src_pitch = s->twoD_pitch & 0x1FFF; ++ int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF; + int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0; + int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt); + +- if (addressing != 0x0) { ++ if ((s->twoD_stretch >> 16) & 0xF) { + qemu_log_mask(LOG_UNIMP, "sm501: only XY addressing is supported.\n"); + return; + } +@@ -758,20 +757,20 @@ static void sm501_2d_operation(SM501State *s) + return; + } + +- switch (operation) { ++ switch (cmd) { + case 0x00: /* copy area */ + #define COPY_AREA(_bpp, _pixel_type, rtl) { \ + int y, x, index_d, index_s; \ +- for (y = 0; y < operation_height; y++) { \ +- for (x = 0; x < operation_width; x++) { \ ++ for (y = 0; y < height; y++) { \ ++ for (x = 0; x < width; x++) { \ + _pixel_type val; \ + \ + if (rtl) { \ +- index_s = ((src_y - y) * src_width + src_x - x) * _bpp; \ +- index_d = ((dst_y - y) * dst_width + dst_x - x) * _bpp; \ ++ index_s = ((src_y - y) * src_pitch + src_x - x) * _bpp; \ ++ index_d = ((dst_y - y) * dst_pitch + dst_x - x) * _bpp; \ + } else { \ +- index_s = ((src_y + y) * src_width + src_x + x) * _bpp; \ +- index_d = ((dst_y + y) * dst_width + dst_x + x) * _bpp; \ ++ index_s = ((src_y + y) * src_pitch + src_x + x) * _bpp; \ ++ index_d = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \ + } \ + if (rop_mode == 1 && rop == 5) { \ + /* Invert dest */ \ +@@ -783,7 +782,7 @@ static void sm501_2d_operation(SM501State *s) + } \ + } \ + } +- switch (format_flags) { ++ switch (format) { + case 0: + COPY_AREA(1, uint8_t, rtl); + break; +@@ -799,15 +798,15 @@ static void sm501_2d_operation(SM501State *s) + case 0x01: /* fill rectangle */ + #define FILL_RECT(_bpp, _pixel_type) { \ + int y, x; \ +- for (y = 0; y < operation_height; y++) { \ +- for (x = 0; x < operation_width; x++) { \ +- int index = ((dst_y + y) * dst_width + dst_x + x) * _bpp; \ ++ for (y = 0; y < height; y++) { \ ++ for (x = 0; x < width; x++) { \ ++ int index = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \ + *(_pixel_type *)&dst[index] = (_pixel_type)color; \ + } \ + } \ + } + +- switch (format_flags) { ++ switch (format) { + case 0: + FILL_RECT(1, uint8_t); + break; +@@ -824,14 +823,14 @@ static void sm501_2d_operation(SM501State *s) + + default: + qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2D operation: %d\n", +- operation); ++ cmd); + return; + } + + if (dst_base >= get_fb_addr(s, crt) && + dst_base <= get_fb_addr(s, crt) + fb_len) { +- int dst_len = MIN(fb_len, ((dst_y + operation_height - 1) * dst_width + +- dst_x + operation_width) * (1 << format_flags)); ++ int dst_len = MIN(fb_len, ((dst_y + height - 1) * dst_pitch + ++ dst_x + width) * (1 << format)); + if (dst_len) { + memory_region_set_dirty(&s->local_mem_region, dst_base, dst_len); + } +-- +2.23.0 + -- Gitee From 277037225cd555ca2e852cfb80755339fdbffb42 Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Thu, 21 May 2020 21:39:44 +0200 Subject: [PATCH 09/13] sm501: Use BIT(x) macro to shorten constant MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-id: 124bf5de8d7cf503b32b377d0445029a76bfbd49.1590089984.git.balaton@eik.bme.hu Signed-off-by: Gerd Hoffmann --- ...-Use-BIT-x-macro-to-shorten-constant.patch | 42 +++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 sm501-Use-BIT-x-macro-to-shorten-constant.patch diff --git a/sm501-Use-BIT-x-macro-to-shorten-constant.patch b/sm501-Use-BIT-x-macro-to-shorten-constant.patch new file mode 100644 index 00000000..dbd41270 --- /dev/null +++ b/sm501-Use-BIT-x-macro-to-shorten-constant.patch @@ -0,0 +1,42 @@ +From a2622f39d8050c86100b40e47b2586d0ebf3b541 Mon Sep 17 00:00:00 2001 +From: BALATON Zoltan +Date: Thu, 21 May 2020 21:39:44 +0200 +Subject: [PATCH] sm501: Use BIT(x) macro to shorten constant +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Signed-off-by: BALATON Zoltan +Reviewed-by: Philippe Mathieu-Daudé +Message-id: 124bf5de8d7cf503b32b377d0445029a76bfbd49.1590089984.git.balaton@eik.bme.hu +Signed-off-by: Gerd Hoffmann +--- + hw/display/sm501.c | 5 ++--- + 1 file changed, 2 insertions(+), 3 deletions(-) + +diff --git a/hw/display/sm501.c b/hw/display/sm501.c +index 51e7ccc39d..f3d11d0b23 100644 +--- a/hw/display/sm501.c ++++ b/hw/display/sm501.c +@@ -701,7 +701,7 @@ static void sm501_2d_operation(SM501State *s) + { + /* obtain operation parameters */ + int cmd = (s->twoD_control >> 16) & 0x1F; +- int rtl = s->twoD_control & 0x8000000; ++ int rtl = s->twoD_control & BIT(27); + int src_x = (s->twoD_source >> 16) & 0x01FFF; + int src_y = s->twoD_source & 0xFFFF; + int dst_x = (s->twoD_destination >> 16) & 0x01FFF; +@@ -751,8 +751,7 @@ static void sm501_2d_operation(SM501State *s) + } + } + +- if ((s->twoD_source_base & 0x08000000) || +- (s->twoD_destination_base & 0x08000000)) { ++ if (s->twoD_source_base & BIT(27) || s->twoD_destination_base & BIT(27)) { + qemu_log_mask(LOG_UNIMP, "sm501: only local memory is supported.\n"); + return; + } +-- +2.23.0 + -- Gitee From 766ddaa416d5cf30a1db586a91a48e201ad2191d Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Thu, 21 May 2020 21:39:44 +0200 Subject: [PATCH 10/13] sm501: Clean up local variables in sm501_2d_operation MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make variables local to the block they are used in to make it clearer which operation they are needed for. Signed-off-by: BALATON Zoltan Reviewed-by: Philippe Mathieu-Daudé Message-id: ae59f8138afe7f6a5a4a82539d0f61496a906b06.1590089984.git.balaton@eik.bme.hu Signed-off-by: Gerd Hoffmann --- ...ocal-variables-in-sm501_2d_operation.patch | 95 +++++++++++++++++++ 1 file changed, 95 insertions(+) create mode 100644 sm501-Clean-up-local-variables-in-sm501_2d_operation.patch diff --git a/sm501-Clean-up-local-variables-in-sm501_2d_operation.patch b/sm501-Clean-up-local-variables-in-sm501_2d_operation.patch new file mode 100644 index 00000000..70d87926 --- /dev/null +++ b/sm501-Clean-up-local-variables-in-sm501_2d_operation.patch @@ -0,0 +1,95 @@ +From b08fddd2931fa2e3d12d2c26074835956b114d56 Mon Sep 17 00:00:00 2001 +From: BALATON Zoltan +Date: Thu, 21 May 2020 21:39:44 +0200 +Subject: [PATCH] sm501: Clean up local variables in sm501_2d_operation +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Make variables local to the block they are used in to make it clearer +which operation they are needed for. + +Signed-off-by: BALATON Zoltan +Reviewed-by: Philippe Mathieu-Daudé +Message-id: ae59f8138afe7f6a5a4a82539d0f61496a906b06.1590089984.git.balaton@eik.bme.hu +Signed-off-by: Gerd Hoffmann +--- + hw/display/sm501.c | 31 ++++++++++++++++--------------- + 1 file changed, 16 insertions(+), 15 deletions(-) + +diff --git a/hw/display/sm501.c b/hw/display/sm501.c +index f3d11d0b23..98b3b97f7b 100644 +--- a/hw/display/sm501.c ++++ b/hw/display/sm501.c +@@ -699,28 +699,19 @@ static inline void hwc_invalidate(SM501State *s, int crt) + + static void sm501_2d_operation(SM501State *s) + { +- /* obtain operation parameters */ + int cmd = (s->twoD_control >> 16) & 0x1F; + int rtl = s->twoD_control & BIT(27); +- int src_x = (s->twoD_source >> 16) & 0x01FFF; +- int src_y = s->twoD_source & 0xFFFF; +- int dst_x = (s->twoD_destination >> 16) & 0x01FFF; +- int dst_y = s->twoD_destination & 0xFFFF; +- int width = (s->twoD_dimension >> 16) & 0x1FFF; +- int height = s->twoD_dimension & 0xFFFF; +- uint32_t color = s->twoD_foreground; + int format = (s->twoD_stretch >> 20) & 0x3; + int rop_mode = (s->twoD_control >> 15) & 0x1; /* 1 for rop2, else rop3 */ + /* 1 if rop2 source is the pattern, otherwise the source is the bitmap */ + int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1; + int rop = s->twoD_control & 0xFF; +- uint32_t src_base = s->twoD_source_base & 0x03FFFFFF; ++ int dst_x = (s->twoD_destination >> 16) & 0x01FFF; ++ int dst_y = s->twoD_destination & 0xFFFF; ++ int width = (s->twoD_dimension >> 16) & 0x1FFF; ++ int height = s->twoD_dimension & 0xFFFF; + uint32_t dst_base = s->twoD_destination_base & 0x03FFFFFF; +- +- /* get frame buffer info */ +- uint8_t *src = s->local_mem + src_base; + uint8_t *dst = s->local_mem + dst_base; +- int src_pitch = s->twoD_pitch & 0x1FFF; + int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF; + int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0; + int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt); +@@ -758,6 +749,13 @@ static void sm501_2d_operation(SM501State *s) + + switch (cmd) { + case 0x00: /* copy area */ ++ { ++ int src_x = (s->twoD_source >> 16) & 0x01FFF; ++ int src_y = s->twoD_source & 0xFFFF; ++ uint32_t src_base = s->twoD_source_base & 0x03FFFFFF; ++ uint8_t *src = s->local_mem + src_base; ++ int src_pitch = s->twoD_pitch & 0x1FFF; ++ + #define COPY_AREA(_bpp, _pixel_type, rtl) { \ + int y, x, index_d, index_s; \ + for (y = 0; y < height; y++) { \ +@@ -793,8 +791,11 @@ static void sm501_2d_operation(SM501State *s) + break; + } + break; +- ++ } + case 0x01: /* fill rectangle */ ++ { ++ uint32_t color = s->twoD_foreground; ++ + #define FILL_RECT(_bpp, _pixel_type) { \ + int y, x; \ + for (y = 0; y < height; y++) { \ +@@ -819,7 +820,7 @@ static void sm501_2d_operation(SM501State *s) + break; + } + break; +- ++ } + default: + qemu_log_mask(LOG_UNIMP, "sm501: not implemented 2D operation: %d\n", + cmd); +-- +2.23.0 + -- Gitee From 7215180b05483b38ccf15926f36ac2ac1803a7ed Mon Sep 17 00:00:00 2001 From: BALATON Zoltan Date: Thu, 21 May 2020 21:39:44 +0200 Subject: [PATCH 11/13] sm501: Replace hand written implementation with pixman where possible Besides being faster this should also prevent malicious guests to abuse 2D engine to overwrite data or cause a crash. Signed-off-by: BALATON Zoltan Message-id: 58666389b6cae256e4e972a32c05cf8aa51bffc0.1590089984.git.balaton@eik.bme.hu Signed-off-by: Gerd Hoffmann --- ...nd-written-implementation-with-pixma.patch | 261 ++++++++++++++++++ 1 file changed, 261 insertions(+) create mode 100644 sm501-Replace-hand-written-implementation-with-pixma.patch diff --git a/sm501-Replace-hand-written-implementation-with-pixma.patch b/sm501-Replace-hand-written-implementation-with-pixma.patch new file mode 100644 index 00000000..67842bea --- /dev/null +++ b/sm501-Replace-hand-written-implementation-with-pixma.patch @@ -0,0 +1,261 @@ +From 2f57a288065de4fffcf182deacd3c75aec90a9ef Mon Sep 17 00:00:00 2001 +From: BALATON Zoltan +Date: Thu, 21 May 2020 21:39:44 +0200 +Subject: [PATCH] sm501: Replace hand written implementation with pixman where + possible + +Besides being faster this should also prevent malicious guests to +abuse 2D engine to overwrite data or cause a crash. + +Signed-off-by: BALATON Zoltan +Message-id: 58666389b6cae256e4e972a32c05cf8aa51bffc0.1590089984.git.balaton@eik.bme.hu +Signed-off-by: Gerd Hoffmann +--- + hw/display/sm501.c | 207 ++++++++++++++++++++++++++------------------- + 1 file changed, 119 insertions(+), 88 deletions(-) + +diff --git a/hw/display/sm501.c b/hw/display/sm501.c +index 98b3b97f7b..7dc4bb18b7 100644 +--- a/hw/display/sm501.c ++++ b/hw/display/sm501.c +@@ -706,13 +706,12 @@ static void sm501_2d_operation(SM501State *s) + /* 1 if rop2 source is the pattern, otherwise the source is the bitmap */ + int rop2_source_is_pattern = (s->twoD_control >> 14) & 0x1; + int rop = s->twoD_control & 0xFF; +- int dst_x = (s->twoD_destination >> 16) & 0x01FFF; +- int dst_y = s->twoD_destination & 0xFFFF; +- int width = (s->twoD_dimension >> 16) & 0x1FFF; +- int height = s->twoD_dimension & 0xFFFF; ++ unsigned int dst_x = (s->twoD_destination >> 16) & 0x01FFF; ++ unsigned int dst_y = s->twoD_destination & 0xFFFF; ++ unsigned int width = (s->twoD_dimension >> 16) & 0x1FFF; ++ unsigned int height = s->twoD_dimension & 0xFFFF; + uint32_t dst_base = s->twoD_destination_base & 0x03FFFFFF; +- uint8_t *dst = s->local_mem + dst_base; +- int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF; ++ unsigned int dst_pitch = (s->twoD_pitch >> 16) & 0x1FFF; + int crt = (s->dc_crt_control & SM501_DC_CRT_CONTROL_SEL) ? 1 : 0; + int fb_len = get_width(s, crt) * get_height(s, crt) * get_bpp(s, crt); + +@@ -721,104 +720,136 @@ static void sm501_2d_operation(SM501State *s) + return; + } + +- if (rop_mode == 0) { +- if (rop != 0xcc) { +- /* Anything other than plain copies are not supported */ +- qemu_log_mask(LOG_UNIMP, "sm501: rop3 mode with rop %x is not " +- "supported.\n", rop); +- } +- } else { +- if (rop2_source_is_pattern && rop != 0x5) { +- /* For pattern source, we support only inverse dest */ +- qemu_log_mask(LOG_UNIMP, "sm501: rop2 source being the pattern and " +- "rop %x is not supported.\n", rop); +- } else { +- if (rop != 0x5 && rop != 0xc) { +- /* Anything other than plain copies or inverse dest is not +- * supported */ +- qemu_log_mask(LOG_UNIMP, "sm501: rop mode %x is not " +- "supported.\n", rop); +- } +- } +- } +- + if (s->twoD_source_base & BIT(27) || s->twoD_destination_base & BIT(27)) { + qemu_log_mask(LOG_UNIMP, "sm501: only local memory is supported.\n"); + return; + } + ++ if (!dst_pitch) { ++ qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero dest pitch.\n"); ++ return; ++ } ++ ++ if (!width || !height) { ++ qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero size 2D op.\n"); ++ return; ++ } ++ ++ if (rtl) { ++ dst_x -= width - 1; ++ dst_y -= height - 1; ++ } ++ ++ if (dst_base >= get_local_mem_size(s) || dst_base + ++ (dst_x + width + (dst_y + height) * (dst_pitch + width)) * ++ (1 << format) >= get_local_mem_size(s)) { ++ qemu_log_mask(LOG_GUEST_ERROR, "sm501: 2D op dest is outside vram.\n"); ++ return; ++ } ++ + switch (cmd) { +- case 0x00: /* copy area */ ++ case 0: /* BitBlt */ + { +- int src_x = (s->twoD_source >> 16) & 0x01FFF; +- int src_y = s->twoD_source & 0xFFFF; ++ unsigned int src_x = (s->twoD_source >> 16) & 0x01FFF; ++ unsigned int src_y = s->twoD_source & 0xFFFF; + uint32_t src_base = s->twoD_source_base & 0x03FFFFFF; +- uint8_t *src = s->local_mem + src_base; +- int src_pitch = s->twoD_pitch & 0x1FFF; +- +-#define COPY_AREA(_bpp, _pixel_type, rtl) { \ +- int y, x, index_d, index_s; \ +- for (y = 0; y < height; y++) { \ +- for (x = 0; x < width; x++) { \ +- _pixel_type val; \ +- \ +- if (rtl) { \ +- index_s = ((src_y - y) * src_pitch + src_x - x) * _bpp; \ +- index_d = ((dst_y - y) * dst_pitch + dst_x - x) * _bpp; \ +- } else { \ +- index_s = ((src_y + y) * src_pitch + src_x + x) * _bpp; \ +- index_d = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \ +- } \ +- if (rop_mode == 1 && rop == 5) { \ +- /* Invert dest */ \ +- val = ~*(_pixel_type *)&dst[index_d]; \ +- } else { \ +- val = *(_pixel_type *)&src[index_s]; \ +- } \ +- *(_pixel_type *)&dst[index_d] = val; \ +- } \ +- } \ +- } +- switch (format) { +- case 0: +- COPY_AREA(1, uint8_t, rtl); +- break; +- case 1: +- COPY_AREA(2, uint16_t, rtl); +- break; +- case 2: +- COPY_AREA(4, uint32_t, rtl); +- break; ++ unsigned int src_pitch = s->twoD_pitch & 0x1FFF; ++ ++ if (!src_pitch) { ++ qemu_log_mask(LOG_GUEST_ERROR, "sm501: Zero src pitch.\n"); ++ return; ++ } ++ ++ if (rtl) { ++ src_x -= width - 1; ++ src_y -= height - 1; ++ } ++ ++ if (src_base >= get_local_mem_size(s) || src_base + ++ (src_x + width + (src_y + height) * (src_pitch + width)) * ++ (1 << format) >= get_local_mem_size(s)) { ++ qemu_log_mask(LOG_GUEST_ERROR, ++ "sm501: 2D op src is outside vram.\n"); ++ return; ++ } ++ ++ if ((rop_mode && rop == 0x5) || (!rop_mode && rop == 0x55)) { ++ /* Invert dest, is there a way to do this with pixman? */ ++ unsigned int x, y, i; ++ uint8_t *d = s->local_mem + dst_base; ++ ++ for (y = 0; y < height; y++) { ++ i = (dst_x + (dst_y + y) * dst_pitch) * (1 << format); ++ for (x = 0; x < width; x++, i += (1 << format)) { ++ switch (format) { ++ case 0: ++ d[i] = ~d[i]; ++ break; ++ case 1: ++ *(uint16_t *)&d[i] = ~*(uint16_t *)&d[i]; ++ break; ++ case 2: ++ *(uint32_t *)&d[i] = ~*(uint32_t *)&d[i]; ++ break; ++ } ++ } ++ } ++ } else { ++ /* Do copy src for unimplemented ops, better than unpainted area */ ++ if ((rop_mode && (rop != 0xc || rop2_source_is_pattern)) || ++ (!rop_mode && rop != 0xcc)) { ++ qemu_log_mask(LOG_UNIMP, ++ "sm501: rop%d op %x%s not implemented\n", ++ (rop_mode ? 2 : 3), rop, ++ (rop2_source_is_pattern ? ++ " with pattern source" : "")); ++ } ++ /* Check for overlaps, this could be made more exact */ ++ uint32_t sb, se, db, de; ++ sb = src_base + src_x + src_y * (width + src_pitch); ++ se = sb + width + height * (width + src_pitch); ++ db = dst_base + dst_x + dst_y * (width + dst_pitch); ++ de = db + width + height * (width + dst_pitch); ++ if (rtl && ((db >= sb && db <= se) || (de >= sb && de <= se))) { ++ /* regions may overlap: copy via temporary */ ++ int llb = width * (1 << format); ++ int tmp_stride = DIV_ROUND_UP(llb, sizeof(uint32_t)); ++ uint32_t *tmp = g_malloc(tmp_stride * sizeof(uint32_t) * ++ height); ++ pixman_blt((uint32_t *)&s->local_mem[src_base], tmp, ++ src_pitch * (1 << format) / sizeof(uint32_t), ++ tmp_stride, 8 * (1 << format), 8 * (1 << format), ++ src_x, src_y, 0, 0, width, height); ++ pixman_blt(tmp, (uint32_t *)&s->local_mem[dst_base], ++ tmp_stride, ++ dst_pitch * (1 << format) / sizeof(uint32_t), ++ 8 * (1 << format), 8 * (1 << format), ++ 0, 0, dst_x, dst_y, width, height); ++ g_free(tmp); ++ } else { ++ pixman_blt((uint32_t *)&s->local_mem[src_base], ++ (uint32_t *)&s->local_mem[dst_base], ++ src_pitch * (1 << format) / sizeof(uint32_t), ++ dst_pitch * (1 << format) / sizeof(uint32_t), ++ 8 * (1 << format), 8 * (1 << format), ++ src_x, src_y, dst_x, dst_y, width, height); ++ } + } + break; + } +- case 0x01: /* fill rectangle */ ++ case 1: /* Rectangle Fill */ + { + uint32_t color = s->twoD_foreground; + +-#define FILL_RECT(_bpp, _pixel_type) { \ +- int y, x; \ +- for (y = 0; y < height; y++) { \ +- for (x = 0; x < width; x++) { \ +- int index = ((dst_y + y) * dst_pitch + dst_x + x) * _bpp; \ +- *(_pixel_type *)&dst[index] = (_pixel_type)color; \ +- } \ +- } \ +- } +- +- switch (format) { +- case 0: +- FILL_RECT(1, uint8_t); +- break; +- case 1: +- color = cpu_to_le16(color); +- FILL_RECT(2, uint16_t); +- break; +- case 2: ++ if (format == 2) { + color = cpu_to_le32(color); +- FILL_RECT(4, uint32_t); +- break; ++ } else if (format == 1) { ++ color = cpu_to_le16(color); + } ++ ++ pixman_fill((uint32_t *)&s->local_mem[dst_base], ++ dst_pitch * (1 << format) / sizeof(uint32_t), ++ 8 * (1 << format), dst_x, dst_y, width, height, color); + break; + } + default: +-- +2.23.0 + -- Gitee From 632df052b87307e43c05af5e632933a8789e1206 Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Thu, 24 Sep 2020 16:09:40 +0800 Subject: [PATCH 12/13] spec: Update patch and changelog with !14 hw/net/xgmac: Fix buffer overflow in xgmac_enet_send() hw/net/net_tx_pkt: fix assertion failure in net_tx_pkt_add_raw_fragment() sm501: Convert printf + abort to qemu_log_mask sm501: Shorten long variable names in sm501_2d_operation sm501: Use BIT(x) macro to shorten constant sm501: Clean up local variables in sm501_2d_operation sm501: Replace hand written implementation with pixman where possible Signed-off-by: BALATON Zoltan Signed-off-by: Gerd Hoffmann Signed-off-by: Jason Wang Signed-off-by: Mauro Matteo Cascella --- qemu.spec | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/qemu.spec b/qemu.spec index ddf8110a..d7ae8717 100644 --- a/qemu.spec +++ b/qemu.spec @@ -187,6 +187,13 @@ Patch0174: hw-usb-core-fix-buffer-overflow.patch Patch0175: slirp-drop-bogus-IPv6-messages.patch Patch0176: hw-sd-sdhci-Fix-DMA-Transfer-Block-Size-field.patch Patch0177: hw-xhci-check-return-value-of-usb_packet_map.patch +Patch0178: hw-net-xgmac-Fix-buffer-overflow-in-xgmac_enet_send.patch +Patch0179: hw-net-net_tx_pkt-fix-assertion-failure-in-net_tx_pk.patch +Patch0180: sm501-Convert-printf-abort-to-qemu_log_mask.patch +Patch0181: sm501-Shorten-long-variable-names-in-sm501_2d_operat.patch +Patch0182: sm501-Use-BIT-x-macro-to-shorten-constant.patch +Patch0183: sm501-Clean-up-local-variables-in-sm501_2d_operation.patch +Patch0184: sm501-Replace-hand-written-implementation-with-pixma.patch BuildRequires: flex BuildRequires: bison @@ -532,6 +539,15 @@ getent passwd qemu >/dev/null || \ %endif %changelog +* Thu May 21 2020 BALATON Zoltan +- hw/net/xgmac: Fix buffer overflow in xgmac_enet_send() +- hw/net/net_tx_pkt: fix assertion failure in net_tx_pkt_add_raw_fragment() +- sm501: Convert printf + abort to qemu_log_mask +- sm501: Shorten long variable names in sm501_2d_operation +- sm501: Use BIT(x) macro to shorten constant +- sm501: Clean up local variables in sm501_2d_operation +- sm501: Replace hand written implementation with pixman where possible + * Thu Sep 24 2020 Huawei Technologies Co., Ltd - enrich commit info for some patches - rename some patches for slirp -- Gitee From 66e514cb459e28d87efbbf0df71b3fc043b3481f Mon Sep 17 00:00:00 2001 From: Euler Robot Date: Thu, 24 Sep 2020 16:09:40 +0800 Subject: [PATCH 13/13] spec: Update release version with !14 increase release verison by one Signed-off-by: Euler Robot --- qemu.spec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/qemu.spec b/qemu.spec index d7ae8717..71602dee 100644 --- a/qemu.spec +++ b/qemu.spec @@ -1,6 +1,6 @@ Name: qemu Version: 4.1.0 -Release: 21 +Release: 22 Epoch: 2 Summary: QEMU is a generic and open source machine emulator and virtualizer License: GPLv2 and BSD and MIT and CC-BY -- Gitee