aa42255b5b
- Include upstream patches targeted for the next stable release (bug fixes only) spapr-Fix-failure-path-for-attempting-to.patch target-i386-do-not-set-unsupported-VMX-s.patch target-xtensa-fix-pasto-in-pfwait.r-opco.patch tcg-i386-Fix-INDEX_op_dup2_vec.patch tcg-mips-mips-sync-encode-error.patch vhost-user-gpu-Release-memory-returned-b.patch vpc-Don-t-round-up-already-aligned-BAT-s.patch xen-block-Fix-double-qlist-remove-and-re.patch - Fix bug causing weak encryption in PAuth for ARM (CVE-2020-10702 bsc#1168681) target-arm-Fix-PAuth-sbox-functions.patch - Fix OOB in tulip NIC emulation (CVE-2020-11102 bsc#1168713 net-tulip-check-frame-size-and-r-w-data-.patch - Note that previously included patch addresses CVE-2020-1711 and bsc#1166240 iscsi-Cap-block-count-from-GET-LBA-STATU.patch - Include performance improvement (and related?) patch aio-wait-delegate-polling-of-main-AioCon.patch async-use-explicit-memory-barriers.patch - Rework previous patch at Olaf H.'s direction hw-i386-disable-smbus-migration-for-xenf.patch - Eliminate is_opensuse usage in producing seabios version string what we are doing here is just replacing the upstream string with one indicating that the openSUSE build service built it, and so just leave it as "-rebuilt.opensuse.org" - Alter algorithm used to produce "unique" symbol for coordinating qemu with the optional modules it may load. This is a reasonable relaxation for broader compatibility configure-remove-pkgversion-from-CONFIG_.patch - Tweak supported.*.txt for latest deprecations, and other fixes - Tweak update_git.sh, config.sh - One more fix is needed for: s390x Protected Virtualization support - start and control guest in secure mode (bsc#1167075 jsc#SLE-7407) s390x-s390-virtio-ccw-Fix-build-on-syste.patch OBS-URL: https://build.opensuse.org/request/show/795118 OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=542
145 lines
4.9 KiB
Diff
145 lines
4.9 KiB
Diff
From: Prasad J Pandit <pjp@fedoraproject.org>
|
|
Date: Tue, 24 Mar 2020 22:57:22 +0530
|
|
Subject: net: tulip: check frame size and r/w data length
|
|
|
|
Git-commit: 8ffb7265af64ec81748335ec8f20e7ab542c3850
|
|
References: bsc#1168713, CVE-2020-11102
|
|
|
|
Tulip network driver while copying tx/rx buffers does not check
|
|
frame size against r/w data length. This may lead to OOB buffer
|
|
access. Add check to avoid it.
|
|
|
|
Limit iterations over descriptors to avoid potential infinite
|
|
loop issue in tulip_xmit_list_update.
|
|
|
|
Reported-by: Li Qiang <pangpei.lq@antfin.com>
|
|
Reported-by: Ziming Zhang <ezrakiez@gmail.com>
|
|
Reported-by: Jason Wang <jasowang@redhat.com>
|
|
Tested-by: Li Qiang <liq3ea@gmail.com>
|
|
Reviewed-by: Li Qiang <liq3ea@gmail.com>
|
|
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
|
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
|
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
|
---
|
|
hw/net/tulip.c | 36 +++++++++++++++++++++++++++---------
|
|
1 file changed, 27 insertions(+), 9 deletions(-)
|
|
|
|
diff --git a/hw/net/tulip.c b/hw/net/tulip.c
|
|
index f85f54341fab635a4d5756a6c444..1167c1bb07d74783f3fa47b01996 100644
|
|
--- a/hw/net/tulip.c
|
|
+++ b/hw/net/tulip.c
|
|
@@ -170,6 +170,10 @@ static void tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc)
|
|
} else {
|
|
len = s->rx_frame_len;
|
|
}
|
|
+
|
|
+ if (s->rx_frame_len + len > sizeof(s->rx_frame)) {
|
|
+ return;
|
|
+ }
|
|
pci_dma_write(&s->dev, desc->buf_addr1, s->rx_frame +
|
|
(s->rx_frame_size - s->rx_frame_len), len);
|
|
s->rx_frame_len -= len;
|
|
@@ -181,6 +185,10 @@ static void tulip_copy_rx_bytes(TULIPState *s, struct tulip_descriptor *desc)
|
|
} else {
|
|
len = s->rx_frame_len;
|
|
}
|
|
+
|
|
+ if (s->rx_frame_len + len > sizeof(s->rx_frame)) {
|
|
+ return;
|
|
+ }
|
|
pci_dma_write(&s->dev, desc->buf_addr2, s->rx_frame +
|
|
(s->rx_frame_size - s->rx_frame_len), len);
|
|
s->rx_frame_len -= len;
|
|
@@ -227,7 +235,8 @@ static ssize_t tulip_receive(TULIPState *s, const uint8_t *buf, size_t size)
|
|
|
|
trace_tulip_receive(buf, size);
|
|
|
|
- if (size < 14 || size > 2048 || s->rx_frame_len || tulip_rx_stopped(s)) {
|
|
+ if (size < 14 || size > sizeof(s->rx_frame) - 4
|
|
+ || s->rx_frame_len || tulip_rx_stopped(s)) {
|
|
return 0;
|
|
}
|
|
|
|
@@ -275,7 +284,6 @@ static ssize_t tulip_receive_nc(NetClientState *nc,
|
|
return tulip_receive(qemu_get_nic_opaque(nc), buf, size);
|
|
}
|
|
|
|
-
|
|
static NetClientInfo net_tulip_info = {
|
|
.type = NET_CLIENT_DRIVER_NIC,
|
|
.size = sizeof(NICState),
|
|
@@ -558,7 +566,7 @@ static void tulip_tx(TULIPState *s, struct tulip_descriptor *desc)
|
|
if ((s->csr[6] >> CSR6_OM_SHIFT) & CSR6_OM_MASK) {
|
|
/* Internal or external Loopback */
|
|
tulip_receive(s, s->tx_frame, s->tx_frame_len);
|
|
- } else {
|
|
+ } else if (s->tx_frame_len <= sizeof(s->tx_frame)) {
|
|
qemu_send_packet(qemu_get_queue(s->nic),
|
|
s->tx_frame, s->tx_frame_len);
|
|
}
|
|
@@ -570,23 +578,31 @@ static void tulip_tx(TULIPState *s, struct tulip_descriptor *desc)
|
|
}
|
|
}
|
|
|
|
-static void tulip_copy_tx_buffers(TULIPState *s, struct tulip_descriptor *desc)
|
|
+static int tulip_copy_tx_buffers(TULIPState *s, struct tulip_descriptor *desc)
|
|
{
|
|
int len1 = (desc->control >> TDES1_BUF1_SIZE_SHIFT) & TDES1_BUF1_SIZE_MASK;
|
|
int len2 = (desc->control >> TDES1_BUF2_SIZE_SHIFT) & TDES1_BUF2_SIZE_MASK;
|
|
|
|
+ if (s->tx_frame_len + len1 > sizeof(s->tx_frame)) {
|
|
+ return -1;
|
|
+ }
|
|
if (len1) {
|
|
pci_dma_read(&s->dev, desc->buf_addr1,
|
|
s->tx_frame + s->tx_frame_len, len1);
|
|
s->tx_frame_len += len1;
|
|
}
|
|
|
|
+ if (s->tx_frame_len + len2 > sizeof(s->tx_frame)) {
|
|
+ return -1;
|
|
+ }
|
|
if (len2) {
|
|
pci_dma_read(&s->dev, desc->buf_addr2,
|
|
s->tx_frame + s->tx_frame_len, len2);
|
|
s->tx_frame_len += len2;
|
|
}
|
|
desc->status = (len1 + len2) ? 0 : 0x7fffffff;
|
|
+
|
|
+ return 0;
|
|
}
|
|
|
|
static void tulip_setup_filter_addr(TULIPState *s, uint8_t *buf, int n)
|
|
@@ -651,13 +667,15 @@ static uint32_t tulip_ts(TULIPState *s)
|
|
|
|
static void tulip_xmit_list_update(TULIPState *s)
|
|
{
|
|
+#define TULIP_DESC_MAX 128
|
|
+ uint8_t i = 0;
|
|
struct tulip_descriptor desc;
|
|
|
|
if (tulip_ts(s) != CSR5_TS_SUSPENDED) {
|
|
return;
|
|
}
|
|
|
|
- for (;;) {
|
|
+ for (i = 0; i < TULIP_DESC_MAX; i++) {
|
|
tulip_desc_read(s, s->current_tx_desc, &desc);
|
|
tulip_dump_tx_descriptor(s, &desc);
|
|
|
|
@@ -675,10 +693,10 @@ static void tulip_xmit_list_update(TULIPState *s)
|
|
s->tx_frame_len = 0;
|
|
}
|
|
|
|
- tulip_copy_tx_buffers(s, &desc);
|
|
-
|
|
- if (desc.control & TDES1_LS) {
|
|
- tulip_tx(s, &desc);
|
|
+ if (!tulip_copy_tx_buffers(s, &desc)) {
|
|
+ if (desc.control & TDES1_LS) {
|
|
+ tulip_tx(s, &desc);
|
|
+ }
|
|
}
|
|
}
|
|
tulip_desc_write(s, s->current_tx_desc, &desc);
|