netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] lmc: Read outside array bounds
@ 2009-07-25 22:18 Roel Kluin
  2009-07-27  1:33 ` David Miller
       [not found] ` <20090728144307.c189810b.akpm@linux-foundation.org>
  0 siblings, 2 replies; 6+ messages in thread
From: Roel Kluin @ 2009-07-25 22:18 UTC (permalink / raw)
  To: khc, netdev, Andrew Morton

if dev_alloc_skb() fails on the first iteration of the allocation loop, and we
break out of the loop, then we end up writing before the start of the array.

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 45b1822..ac8d5b2 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -1865,7 +1865,7 @@ static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/
             if(skb == NULL){
                 printk(KERN_WARNING "%s: Failed to allocate receiver ring, will try again
", sc->name);
                 sc->failed_ring = 1;
-                break;
+                return;
             }
             else{
                 sc->lmc_rxq[i] = skb;

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] lmc: Read outside array bounds
  2009-07-25 22:18 [PATCH] lmc: Read outside array bounds Roel Kluin
@ 2009-07-27  1:33 ` David Miller
       [not found] ` <20090728144307.c189810b.akpm@linux-foundation.org>
  1 sibling, 0 replies; 6+ messages in thread
From: David Miller @ 2009-07-27  1:33 UTC (permalink / raw)
  To: roel.kluin; +Cc: khc, netdev, akpm

From: Roel Kluin <roel.kluin@gmail.com>
Date: Sun, 26 Jul 2009 00:18:17 +0200

> if dev_alloc_skb() fails on the first iteration of the allocation loop, and we
> break out of the loop, then we end up writing before the start of the array.
> 
> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
...
>                  sc->failed_ring = 1;
> -                break;
> +                return;

This won't work.

First of all, if we allocated at least one buffer we should
mark the last one in the code right after this loop.

Second of all, we should purge the TX skbs in the next
loop even if we could not allocate even one RX buffer.

The thing to do is probably to guard the set of "[i-1]" RX ring
accesses with a "if (i != 0)" check.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] lmc: Read outside array bounds
       [not found] ` <20090728144307.c189810b.akpm@linux-foundation.org>
@ 2009-08-07 14:54   ` Roel Kluin
  2009-08-10  4:27     ` David Miller
  0 siblings, 1 reply; 6+ messages in thread
From: Roel Kluin @ 2009-08-07 14:54 UTC (permalink / raw)
  To: David S. Miller, khc, netdev, Andrew Morton

If dev_alloc_skb() fails on the first iteration of the allocation loop, and we
break out of the loop, then we end up writing before the start of the array.

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
> First of all, if we allocated at least one buffer we should
> mark the last one in the code right after this loop.
> 
> Second of all, we should purge the TX skbs in the next
> loop even if we could not allocate even one RX buffer.
>
> The thing to do is probably to guard the set of "[i-1]" RX ring
> accesses with a "if (i != 0)" check.

Forgot a bit about this one, but I hope this is what you meant?

diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 45b1822..b26fabb 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -1838,7 +1838,7 @@ void lmc_mii_writereg (lmc_softc_t * const sc, unsigned devaddr, unsigned regno,
 
 static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/
 {
-    int i;
+    int i, j;
 
     lmc_trace(sc->lmc_device, "lmc_softreset in");
 
@@ -1897,24 +1897,27 @@ static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/
     /*
      * Sets end of ring
      */
-    sc->lmc_rxring[i - 1].length |= 0x02000000; /* Set end of buffers flag */
-    sc->lmc_rxring[i - 1].buffer2 = virt_to_bus (&sc->lmc_rxring[0]); /* Point back to the start */
-    LMC_CSR_WRITE (sc, csr_rxlist, virt_to_bus (sc->lmc_rxring)); /* write base address */
+    if (i > 0) {
+        sc->lmc_rxring[i - 1].length |= 0x02000000; /* Set end of buffers flag */
+        sc->lmc_rxring[i - 1].buffer2 = virt_to_bus(&sc->lmc_rxring[0]); /* Point back to the start */
+        LMC_CSR_WRITE(sc, csr_rxlist, virt_to_bus(sc->lmc_rxring)); /* write base address */
+    }
 
 
     /* Initialize the transmit rings and buffers */
-    for (i = 0; i < LMC_TXDESCS; i++)
-    {
-        if (sc->lmc_txq[i] != NULL){		/* have buffer */
-            dev_kfree_skb(sc->lmc_txq[i]);	/* free it */
+    for (j = 0; j < i; j++) {
+        if (sc->lmc_txq[j] != NULL) {		/* have buffer */
+            dev_kfree_skb(sc->lmc_txq[j]);	/* free it */
 	    sc->lmc_device->stats.tx_dropped++;	/* We just dropped a packet */
         }
-        sc->lmc_txq[i] = NULL;
-        sc->lmc_txring[i].status = 0x00000000;
-        sc->lmc_txring[i].buffer2 = virt_to_bus (&sc->lmc_txring[i + 1]);
+        sc->lmc_txq[j] = NULL;
+        sc->lmc_txring[j].status = 0x00000000;
+        sc->lmc_txring[j].buffer2 = virt_to_bus(&sc->lmc_txring[j + 1]);
+    }
+    if (j > 0) {
+        sc->lmc_txring[j - 1].buffer2 = virt_to_bus(&sc->lmc_txring[0]);
+        LMC_CSR_WRITE(sc, csr_txlist, virt_to_bus(sc->lmc_txring));
     }
-    sc->lmc_txring[i - 1].buffer2 = virt_to_bus (&sc->lmc_txring[0]);
-    LMC_CSR_WRITE (sc, csr_txlist, virt_to_bus (sc->lmc_txring));
 
     lmc_trace(sc->lmc_device, "lmc_softreset out");
 }

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] lmc: Read outside array bounds
  2009-08-07 14:54   ` Roel Kluin
@ 2009-08-10  4:27     ` David Miller
  2009-08-10 11:29       ` Roel Kluin
  0 siblings, 1 reply; 6+ messages in thread
From: David Miller @ 2009-08-10  4:27 UTC (permalink / raw)
  To: roel.kluin; +Cc: khc, netdev, akpm

From: Roel Kluin <roel.kluin@gmail.com>
Date: Fri, 07 Aug 2009 16:54:19 +0200

> If dev_alloc_skb() fails on the first iteration of the allocation loop, and we
> break out of the loop, then we end up writing before the start of the array.
> 
> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
> ---
>> First of all, if we allocated at least one buffer we should
>> mark the last one in the code right after this loop.
>> 
>> Second of all, we should purge the TX skbs in the next
>> loop even if we could not allocate even one RX buffer.
>>
>> The thing to do is probably to guard the set of "[i-1]" RX ring
>> accesses with a "if (i != 0)" check.
> 
> Forgot a bit about this one, but I hope this is what you meant?

It's not correct to limit the TX ring loop by how many RX
ring buffers we've been able to successfully allocate,
that doesn't make any sense.

I'm talking about the second loop which you unexplainably
changed to "for (j = 0; j < i; ..."

I'm not applying this.

^ permalink raw reply	[flat|nested] 6+ messages in thread

* Re: [PATCH] lmc: Read outside array bounds
  2009-08-10  4:27     ` David Miller
@ 2009-08-10 11:29       ` Roel Kluin
  2009-08-13 23:27         ` David Miller
  0 siblings, 1 reply; 6+ messages in thread
From: Roel Kluin @ 2009-08-10 11:29 UTC (permalink / raw)
  To: David Miller; +Cc: khc, netdev, akpm

If dev_alloc_skb() fails on the first iteration of the allocation loop,
then we end up writing before the start of the array.

Signed-off-by: Roel Kluin <roel.kluin@gmail.com>
---
>>> First of all, if we allocated at least one buffer we should
>>> mark the last one in the code right after this loop.
>>>
>>> Second of all, we should purge the TX skbs in the next
>>> loop even if we could not allocate even one RX buffer.
>>>
>>> The thing to do is probably to guard the set of "[i-1]" RX ring
>>> accesses with a "if (i != 0)" check.
>> Forgot a bit about this one, but I hope this is what you meant?
> 
> It's not correct to limit the TX ring loop by how many RX
> ring buffers we've been able to successfully allocate,
> that doesn't make any sense.
> 
> I'm talking about the second loop which you unexplainably
> changed to "for (j = 0; j < i; ..."

Ok, I apparently completely misunderstood. One remaining question is whether
the base address should still be written if i is 0?

diff --git a/drivers/net/wan/lmc/lmc_main.c b/drivers/net/wan/lmc/lmc_main.c
index 45b1822..8b61660 100644
--- a/drivers/net/wan/lmc/lmc_main.c
+++ b/drivers/net/wan/lmc/lmc_main.c
@@ -1897,11 +1897,12 @@ static void lmc_softreset (lmc_softc_t * const sc) /*fold00*/
     /*
      * Sets end of ring
      */
-    sc->lmc_rxring[i - 1].length |= 0x02000000; /* Set end of buffers flag */
-    sc->lmc_rxring[i - 1].buffer2 = virt_to_bus (&sc->lmc_rxring[0]); /* Point back to the start */
+    if (i != 0) {
+        sc->lmc_rxring[i - 1].length |= 0x02000000; /* Set end of buffers flag */
+        sc->lmc_rxring[i - 1].buffer2 = virt_to_bus(&sc->lmc_rxring[0]); /* Point back to the start */
+    }
     LMC_CSR_WRITE (sc, csr_rxlist, virt_to_bus (sc->lmc_rxring)); /* write base address */
 
-
     /* Initialize the transmit rings and buffers */
     for (i = 0; i < LMC_TXDESCS; i++)
     {

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* Re: [PATCH] lmc: Read outside array bounds
  2009-08-10 11:29       ` Roel Kluin
@ 2009-08-13 23:27         ` David Miller
  0 siblings, 0 replies; 6+ messages in thread
From: David Miller @ 2009-08-13 23:27 UTC (permalink / raw)
  To: roel.kluin; +Cc: khc, netdev, akpm

From: Roel Kluin <roel.kluin@gmail.com>
Date: Mon, 10 Aug 2009 13:29:52 +0200

> If dev_alloc_skb() fails on the first iteration of the allocation loop,
> then we end up writing before the start of the array.
> 
> Signed-off-by: Roel Kluin <roel.kluin@gmail.com>

Applied to net-next-2.6

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2009-08-13 23:26 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-07-25 22:18 [PATCH] lmc: Read outside array bounds Roel Kluin
2009-07-27  1:33 ` David Miller
     [not found] ` <20090728144307.c189810b.akpm@linux-foundation.org>
2009-08-07 14:54   ` Roel Kluin
2009-08-10  4:27     ` David Miller
2009-08-10 11:29       ` Roel Kluin
2009-08-13 23:27         ` David Miller

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).