summaryrefslogtreecommitdiff
path: root/hw/eepro100.c
diff options
context:
space:
mode:
authorReimar Döffinger <Reimar.Doeffinger@gmx.de>2009-08-20 12:34:22 +0200
committerAnthony Liguori <aliguori@us.ibm.com>2009-08-27 20:35:30 -0500
commit24e6f3551f3c8ea7cc7524a3e64e84beca59618f (patch)
tree21bbfccd419644c35a743d587f47dc3faa5f59b8 /hw/eepro100.c
parentd0e7605ee0d91c3737052127a79199ddab3ff653 (diff)
downloadqemu-24e6f3551f3c8ea7cc7524a3e64e84beca59618f.tar.gz
fix stack buffer overflows in eepro100.c tx
Hello, the real world issue is that the hardware allows sends up to 2600 bytes, and for some reason FreeBSD sometimes sends frames larger than the ethernet frame size (102+1460 is the maximum I have seen so far), overflowing the on-stack tx buffer of the driver. Independent of that, the code should avoid allowing the guest to overwrite the stack. This is a minimal patch to fix the issue (you could leave out the size change of the buf array as well, networking still seems to work either way). Obviously there are better ways to handle it, but a proper fix IMO would involve first getting rid of the code duplication and given the number of patches pending for that code I see no point in working on that now. Signed-off-by: Reimar Döffinger <Reimar.Doeffinger@gmx.de> Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Diffstat (limited to 'hw/eepro100.c')
-rw-r--r--hw/eepro100.c6
1 files changed, 5 insertions, 1 deletions
diff --git a/hw/eepro100.c b/hw/eepro100.c
index 1990264437..d9b2e5d5dc 100644
--- a/hw/eepro100.c
+++ b/hw/eepro100.c
@@ -694,7 +694,8 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
logout
("illegal values of TBD array address and TCB byte count!\n");
}
- uint8_t buf[MAX_ETH_FRAME_SIZE + 4];
+ // sends larger than MAX_ETH_FRAME_SIZE are allowed, up to 2600 bytes
+ uint8_t buf[2600];
uint16_t size = 0;
uint32_t tbd_address = cb_address + 0x10;
assert(tcb_bytes <= sizeof(buf));
@@ -706,6 +707,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
logout
("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n",
tx_buffer_address, tx_buffer_size);
+ tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
cpu_physical_memory_read(tx_buffer_address, &buf[size],
tx_buffer_size);
size += tx_buffer_size;
@@ -726,6 +728,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
logout
("TBD (extended flexible mode): buffer address 0x%08x, size 0x%04x\n",
tx_buffer_address, tx_buffer_size);
+ tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
cpu_physical_memory_read(tx_buffer_address, &buf[size],
tx_buffer_size);
size += tx_buffer_size;
@@ -743,6 +746,7 @@ static void eepro100_cu_command(EEPRO100State * s, uint8_t val)
logout
("TBD (flexible mode): buffer address 0x%08x, size 0x%04x\n",
tx_buffer_address, tx_buffer_size);
+ tx_buffer_size = MIN(tx_buffer_size, sizeof(buf) - size);
cpu_physical_memory_read(tx_buffer_address, &buf[size],
tx_buffer_size);
size += tx_buffer_size;