Analyzing CVE-2012-6075 qemu: e1000 driver buffer overflow when processing large packets when SBP and LPE flags are disabled

This is an interesting bug in qemu, although since its in a emulation software, it is not that critical in production environment[as far as i know, things might be different].

the cve entry for this bug says following:

“Buffer overflow in the e1000_receive function in the e1000 device driver (hw/e1000.c) in QEMU 1.3.0-rc2 and other versions, when the SBP and LPE flags are disabled, allows remote attackers to cause a denial of service (guest OS crash) and possibly execute arbitrary guest code via a large packet.”

now e10oo is an emulated device on qemu, and from the description it seems that bug is in verification of large packets, which is also known as jumbo packets.

from wikipedia:

“In computer networkingjumbo frames are Ethernet frames with more than 1500 bytes of payload. Conventionally, jumbo frames can carry up to 9000 bytes of payload, but variations exist and some care must be taken using the term. Many Gigabit Ethernet switches and Gigabit Ethernet network interface cards support jumbo frames. Some Fast Ethernet switches and Fast Ethernet network interface cards also support jumbo frames.[1] Most national research and education networks (such as Internet2/NLR, ESnetGÉANT and AARNet) support jumbo frames, but most commercial Internet service providers do not.[citation needed]

so as someone might have guessed, if this emulated driver received a packet whose size is more then 1500 bytes, it will cause some corruption.

we can confirm this with the source code fix:

first there is a check for the max length:

<br />+/* this is the size past which hardware will drop packets when setting LPE=0 */<br />+#define MAXIMUM_ETHERNET_VLAN_SIZE 1522<br />

after that there is a check if the received packet length is more then the max length,if so packet will be discarded:

<br />+    /* Discard oversized packets if !LPE and !SBP. */<br />+    if (size &gt; MAXIMUM_ETHERNET_VLAN_SIZE<br />+        &amp;&amp; !(s-&gt;mac_reg[RCTL] &amp; E1000_RCTL_LPE)<br />+        &amp;&amp; !(s-&gt;mac_reg[RCTL] &amp; E1000_RCTL_SBP)) {<br />+        return size;<br />+    }<br />
 
Hope it helps.
 
Thanks,
Hardik

Leave a comment