summaryrefslogtreecommitdiff
path: root/sysutils/xen-tools/files/xsa135-qemuu-4.5-1.patch
diff options
context:
space:
mode:
Diffstat (limited to 'sysutils/xen-tools/files/xsa135-qemuu-4.5-1.patch')
-rw-r--r--sysutils/xen-tools/files/xsa135-qemuu-4.5-1.patch94
1 files changed, 94 insertions, 0 deletions
diff --git a/sysutils/xen-tools/files/xsa135-qemuu-4.5-1.patch b/sysutils/xen-tools/files/xsa135-qemuu-4.5-1.patch
new file mode 100644
index 000000000000..31b161026f14
--- /dev/null
+++ b/sysutils/xen-tools/files/xsa135-qemuu-4.5-1.patch
@@ -0,0 +1,94 @@
+pcnet: fix Negative array index read
+
+From: Gonglei <arei.gonglei@huawei.com>
+
+s->xmit_pos maybe assigned to a negative value (-1),
+but in this branch variable s->xmit_pos as an index to
+array s->buffer. Let's add a check for s->xmit_pos.
+
+upstream-commit-id: 7b50d00911ddd6d56a766ac5671e47304c20a21b
+
+Signed-off-by: Gonglei <arei.gonglei@huawei.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: Jason Wang <jasowang@redhat.com>
+Reviewed-by: Jason Wang <jasowang@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+
+diff --git a/hw/net/pcnet.c b/hw/net/pcnet.c
+index d344c15..f409b92 100644
+--- a/hw/net/pcnet.c
++++ b/hw/net/pcnet.c
+@@ -1212,7 +1212,7 @@ static void pcnet_transmit(PCNetState *s)
+ hwaddr xmit_cxda = 0;
+ int count = CSR_XMTRL(s)-1;
+ int add_crc = 0;
+-
++ int bcnt;
+ s->xmit_pos = -1;
+
+ if (!CSR_TXON(s)) {
+@@ -1247,35 +1247,40 @@ static void pcnet_transmit(PCNetState *s)
+ s->xmit_pos = -1;
+ goto txdone;
+ }
++
++ if (s->xmit_pos < 0) {
++ goto txdone;
++ }
++
++ bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
++ s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
++ s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
++ s->xmit_pos += bcnt;
++
+ if (!GET_FIELD(tmd.status, TMDS, ENP)) {
+- int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
+- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
+- s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
+- s->xmit_pos += bcnt;
+- } else if (s->xmit_pos >= 0) {
+- int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT);
+- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr),
+- s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s));
+- s->xmit_pos += bcnt;
++ goto txdone;
++ }
++
+ #ifdef PCNET_DEBUG
+- printf("pcnet_transmit size=%d\n", s->xmit_pos);
++ printf("pcnet_transmit size=%d\n", s->xmit_pos);
+ #endif
+- if (CSR_LOOP(s)) {
+- 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);
+- s->looptest = 0;
+- } else
+- if (s->nic)
+- qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
+- s->xmit_pos);
+-
+- s->csr[0] &= ~0x0008; /* clear TDMD */
+- s->csr[4] |= 0x0004; /* set TXSTRT */
+- s->xmit_pos = -1;
++ if (CSR_LOOP(s)) {
++ 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);
++ s->looptest = 0;
++ } else {
++ if (s->nic) {
++ qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
++ s->xmit_pos);
++ }
+ }
+
++ s->csr[0] &= ~0x0008; /* clear TDMD */
++ s->csr[4] |= 0x0004; /* set TXSTRT */
++ s->xmit_pos = -1;
++
+ txdone:
+ SET_FIELD(&tmd.status, TMDS, OWN, 0);
+ TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));