Commit 7b50d009 authored by Gonglei's avatar Gonglei Committed by Stefan Hajnoczi
Browse files

pcnet: fix Negative array index read



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.
Signed-off-by: default avatarGonglei <arei.gonglei@huawei.com>
Signed-off-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
Reviewed-by: default avatarJason Wang <jasowang@redhat.com>
Reviewed-by: default avatarJason Wang <jasowang@redhat.com>
Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
parent 8db804ac
...@@ -1212,7 +1212,7 @@ static void pcnet_transmit(PCNetState *s) ...@@ -1212,7 +1212,7 @@ static void pcnet_transmit(PCNetState *s)
hwaddr xmit_cxda = 0; hwaddr xmit_cxda = 0;
int count = CSR_XMTRL(s)-1; int count = CSR_XMTRL(s)-1;
int add_crc = 0; int add_crc = 0;
int bcnt;
s->xmit_pos = -1; s->xmit_pos = -1;
if (!CSR_TXON(s)) { if (!CSR_TXON(s)) {
...@@ -1247,35 +1247,40 @@ static void pcnet_transmit(PCNetState *s) ...@@ -1247,35 +1247,40 @@ static void pcnet_transmit(PCNetState *s)
s->xmit_pos = -1; s->xmit_pos = -1;
goto txdone; 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)) { if (!GET_FIELD(tmd.status, TMDS, ENP)) {
int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); goto txdone;
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;
#ifdef PCNET_DEBUG #ifdef PCNET_DEBUG
printf("pcnet_transmit size=%d\n", s->xmit_pos); printf("pcnet_transmit size=%d\n", s->xmit_pos);
#endif #endif
if (CSR_LOOP(s)) { if (CSR_LOOP(s)) {
if (BCR_SWSTYLE(s) == 1) if (BCR_SWSTYLE(s) == 1)
add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS); add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS);
s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC;
pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos); pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos);
s->looptest = 0; s->looptest = 0;
} else } else {
if (s->nic) if (s->nic) {
qemu_send_packet(qemu_get_queue(s->nic), s->buffer, qemu_send_packet(qemu_get_queue(s->nic), s->buffer,
s->xmit_pos); s->xmit_pos);
}
s->csr[0] &= ~0x0008; /* clear TDMD */
s->csr[4] |= 0x0004; /* set TXSTRT */
s->xmit_pos = -1;
} }
s->csr[0] &= ~0x0008; /* clear TDMD */
s->csr[4] |= 0x0004; /* set TXSTRT */
s->xmit_pos = -1;
txdone: txdone:
SET_FIELD(&tmd.status, TMDS, OWN, 0); SET_FIELD(&tmd.status, TMDS, OWN, 0);
TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s))); TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s)));
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment