diff options
author | pbrook | 2006-02-04 23:15:28 +0100 |
---|---|---|
committer | pbrook | 2006-02-04 23:15:28 +0100 |
commit | d861b05ea30e6ac177de9b679da96194ebe21afc (patch) | |
tree | 6bb3605e24633c0e64c9b7396873bbe28fe93be1 /hw/ne2000.c | |
parent | Fix Arm interrupted ldm bug. (diff) | |
download | qemu-d861b05ea30e6ac177de9b679da96194ebe21afc.tar.gz qemu-d861b05ea30e6ac177de9b679da96194ebe21afc.tar.xz qemu-d861b05ea30e6ac177de9b679da96194ebe21afc.zip |
Avoid buffer overflow when sending slirp packets.
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1744 c046a42c-6fe2-441c-8c8c-71466251a162
Diffstat (limited to 'hw/ne2000.c')
-rw-r--r-- | hw/ne2000.c | 29 |
1 files changed, 18 insertions, 11 deletions
diff --git a/hw/ne2000.c b/hw/ne2000.c index efc3ea8ece..674d83e490 100644 --- a/hw/ne2000.c +++ b/hw/ne2000.c @@ -200,14 +200,10 @@ static int compute_mcast_idx(const uint8_t *ep) return (crc >> 26); } -/* return the max buffer size if the NE2000 can receive more data */ -static int ne2000_can_receive(void *opaque) +static int ne2000_buffer_full(NE2000State *s) { - NE2000State *s = opaque; int avail, index, boundary; - - if (s->cmd & E8390_STOP) - return 0; + index = s->curpag << 8; boundary = s->boundary << 8; if (index < boundary) @@ -215,8 +211,17 @@ static int ne2000_can_receive(void *opaque) else avail = (s->stop - s->start) - (index - boundary); if (avail < (MAX_ETH_FRAME_SIZE + 4)) - return 0; - return MAX_ETH_FRAME_SIZE; + return 1; + return 0; +} + +static int ne2000_can_receive(void *opaque) +{ + NE2000State *s = opaque; + + if (s->cmd & E8390_STOP) + return 1; + return !ne2000_buffer_full(s); } #define MIN_BUF_SIZE 60 @@ -234,7 +239,7 @@ static void ne2000_receive(void *opaque, const uint8_t *buf, int size) printf("NE2000: received len=%d\n", size); #endif - if (!ne2000_can_receive(s)) + if (s->cmd & E8390_STOP || ne2000_buffer_full(s)) return; /* XXX: check this */ @@ -722,7 +727,8 @@ void isa_ne2000_init(int base, int irq, NICInfo *nd) ne2000_reset(s); - s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s); + s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, + ne2000_can_receive, s); snprintf(s->vc->info_str, sizeof(s->vc->info_str), "ne2000 macaddr=%02x:%02x:%02x:%02x:%02x:%02x", @@ -791,7 +797,8 @@ void pci_ne2000_init(PCIBus *bus, NICInfo *nd) s->pci_dev = (PCIDevice *)d; memcpy(s->macaddr, nd->macaddr, 6); ne2000_reset(s); - s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, s); + s->vc = qemu_new_vlan_client(nd->vlan, ne2000_receive, + ne2000_can_receive, s); snprintf(s->vc->info_str, sizeof(s->vc->info_str), "ne2000 pci macaddr=%02x:%02x:%02x:%02x:%02x:%02x", |