WARNING - OLD ARCHIVES

This is an archived copy of the Xen.org mailing list, which we have preserved to ensure that existing links to archives are not broken. The live archive, which contains the latest emails, can be found at http://lists.xen.org/
   
 
 
Xen 
 
Home Products Support Community News
 
   
 

xen-devel

[Xen-devel] [QEMU] ne2000: Stop memory access beyond buffer

To: Keir Fraser <keir@xxxxxxxxxxxxx>, Xen Development Mailing List <xen-devel@xxxxxxxxxxxxxxxxxxx>
Subject: [Xen-devel] [QEMU] ne2000: Stop memory access beyond buffer
From: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>
Date: Fri, 27 Oct 2006 17:44:16 +1000
Delivery-date: Fri, 27 Oct 2006 00:44:56 -0700
Envelope-to: www-data@xxxxxxxxxxxxxxxxxx
List-help: <mailto:xen-devel-request@lists.xensource.com?subject=help>
List-id: Xen developer discussion <xen-devel.lists.xensource.com>
List-post: <mailto:xen-devel@lists.xensource.com>
List-subscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=subscribe>
List-unsubscribe: <http://lists.xensource.com/cgi-bin/mailman/listinfo/xen-devel>, <mailto:xen-devel-request@lists.xensource.com?subject=unsubscribe>
Sender: xen-devel-bounces@xxxxxxxxxxxxxxxxxxx
User-agent: Mutt/1.5.9i
Hi Keir:

This patch is probably not quite right since I don't know how you
guys deal with qemu patches.  Let me know if I should send this to
the qemu folks instead.

[QEMU] ne2000: Stop memory access beyond buffer

As a program that runs in dom0 which serves users from guests,
the qemu drivers need to be vigilant to the input that comes
from the guests since they may be malicious.

As it is there are multiple ways to get ne2000 to read/write
memory beyond the 48K buffer that it has allocated for each
adapter.

This patch checks the addresses and prevents this from occuring.

The boundary is checked each time since it's changed for every
packet received while the other parameters are only changed
(by the guest) during setup.

Signed-off: Herbert Xu <herbert@xxxxxxxxxxxxxxxxxxx>

Cheers,
-- 
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <herbert@xxxxxxxxxxxxxxxxxxx>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
--
diff -r 4a320d26fc24 tools/ioemu/hw/ne2000.c
--- a/tools/ioemu/hw/ne2000.c   Thu Oct 26 16:56:16 2006 +0100
+++ b/tools/ioemu/hw/ne2000.c   Fri Oct 27 17:39:39 2006 +1000
@@ -137,6 +137,7 @@ typedef struct NE2000State {
     uint8_t curpag;
     uint8_t mult[8]; /* multicast mask array */
     int irq;
+    int tainted;
     PCIDevice *pci_dev;
     VLANClientState *vc;
     uint8_t macaddr[6];
@@ -226,6 +227,27 @@ static int ne2000_can_receive(void *opaq
 
 #define MIN_BUF_SIZE 60
 
+static inline int ne2000_valid_ring_addr(NE2000State *s, unsigned int addr)
+{
+    addr <<= 8;
+    return addr < s->stop && addr >= s->start;
+}
+
+static inline int ne2000_check_state(NE2000State *s)
+{
+    if (!s->tainted)
+       return 0;
+
+    if (s->start >= s->stop || s->stop > NE2000_MEM_SIZE)
+       return -EINVAL;
+
+    if (!ne2000_valid_ring_addr(s, s->curpag))
+       return -EINVAL;
+
+    s->tainted = 0;
+    return 0;
+}
+
 static void ne2000_receive(void *opaque, const uint8_t *buf, int size)
 {
     NE2000State *s = opaque;
@@ -238,6 +260,12 @@ static void ne2000_receive(void *opaque,
 #if defined(DEBUG_NE2000)
     printf("NE2000: received len=%d\n", size);
 #endif
+
+    if (ne2000_check_state(s))
+       return;
+
+    if (!ne2000_valid_ring_addr(s, s->boundary))
+       return;
 
     if (s->cmd & E8390_STOP || ne2000_buffer_full(s))
         return;
@@ -359,9 +387,11 @@ static void ne2000_ioport_write(void *op
         switch(offset) {
         case EN0_STARTPG:
             s->start = val << 8;
+           s->tainted = 1;
             break;
         case EN0_STOPPG:
             s->stop = val << 8;
+           s->tainted = 1;
             break;
         case EN0_BOUNDARY:
             s->boundary = val;
@@ -406,6 +436,7 @@ static void ne2000_ioport_write(void *op
             break;
         case EN1_CURPAG:
             s->curpag = val;
+           s->tainted = 1;
             break;
         case EN1_MULT ... EN1_MULT + 7:
             s->mult[offset - EN1_MULT] = val;
@@ -509,7 +540,7 @@ static inline void ne2000_mem_writel(NE2
 {
     addr &= ~1; /* XXX: check exact behaviour if not even */
     if (addr < 32 || 
-        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
         cpu_to_le32wu((uint32_t *)(s->mem + addr), val);
     }
 }
@@ -539,7 +570,7 @@ static inline uint32_t ne2000_mem_readl(
 {
     addr &= ~1; /* XXX: check exact behaviour if not even */
     if (addr < 32 || 
-        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) {
+        (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE - 2)) {
         return le32_to_cpupu((uint32_t *)(s->mem + addr));
     } else {
         return 0xffffffff;

_______________________________________________
Xen-devel mailing list
Xen-devel@xxxxxxxxxxxxxxxxxxx
http://lists.xensource.com/xen-devel

<Prev in Thread] Current Thread [Next in Thread>