Skip to contentSkip to conversation

SMC911X: Fix using of dereferenced skb after netif_rx

PATCH In review Wang Chen 4 participants 7 messages Dec 3, 2007 – Dec 4, 2007

Subsystems (2)
lore
Share & tools
lore

Wang Chen

author
#0 lore raw

PATCH 1/1 SMC911X: Fix using of dereferenced skb after netif_rx

After netif_rx(), skb will be freed. So get the
skb->len before netif_rx().

---
 smc911x.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
drivers/net/smc911x.c +3 -2
@@ -1287,7 +1287,7 @@ smc911x_rx_dma_irq(int dma, void *data)
 	struct smc911x_local *lp = netdev_priv(dev);
 	struct sk_buff *skb = lp->current_rx_skb;
 	unsigned long flags;
-	unsigned int pkts;
+	unsigned int pkts, len;
 
 	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
 	DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, "%s: RX DMA irq handler\n", dev->name);
@@ -1299,9 +1299,10 @@ smc911x_rx_dma_irq(int dma, void *data)
 	PRINT_PKT(skb->data, skb->len);
 	dev->last_rx = jiffies;
 	skb->protocol = eth_type_trans(skb, dev);
+	len = skb->len;
 	netif_rx(skb);
 	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += skb->len;
+	dev->stats.rx_bytes += len;
 
 	spin_lock_irqsave(&lp->lock, flags);
 	pkts = (SMC_GET_RX_FIFO_INF() & RX_FIFO_INF_RXSUSED_) >> 16;
#1 lore raw
Quoted 4 lines · Wang Chen

After netif_rx(), skb will be freed. So get the
skb->len before netif_rx().

Please send driver patches to Jeff Garzik <[email protected]>.

Thanks,

Signature · 4 lines
Visit Openswan at http://www.openswan.org/
Email: Herbert Xu ~{PmV>HI~} <[email protected]>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
author
#2 lore raw

Herbert Xu said the following on 2007-12-3 18:11:

Quoted 2 lines

Please send driver patches to Jeff Garzik <[email protected]>.

Sorry. Resend the patch.

After netif_rx(), skb will be freed. So get the
skb->len before netif_rx().

---
 smc911x.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
drivers/net/smc911x.c +3 -2
@@ -1287,7 +1287,7 @@ smc911x_rx_dma_irq(int dma, void *data)
 	struct smc911x_local *lp = netdev_priv(dev);
 	struct sk_buff *skb = lp->current_rx_skb;
 	unsigned long flags;
-	unsigned int pkts;
+	unsigned int pkts, len;
 
 	DBG(SMC_DEBUG_FUNC, "%s: --> %s\n", dev->name, __FUNCTION__);
 	DBG(SMC_DEBUG_RX | SMC_DEBUG_DMA, "%s: RX DMA irq handler\n", dev->name);
@@ -1299,9 +1299,10 @@ smc911x_rx_dma_irq(int dma, void *data)
 	PRINT_PKT(skb->data, skb->len);
 	dev->last_rx = jiffies;
 	skb->protocol = eth_type_trans(skb, dev);
+	len = skb->len;
 	netif_rx(skb);
 	dev->stats.rx_packets++;
-	dev->stats.rx_bytes += skb->len;
+	dev->stats.rx_bytes += len;
 
 	spin_lock_irqsave(&lp->lock, flags);
 	pkts = (SMC_GET_RX_FIFO_INF() & RX_FIFO_INF_RXSUSED_) >> 16;
#3 lore raw
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"Wang" == Wang Chen <[email protected]> writes:

Hi,

Wang> + len = skb->len;
Wang> netif_rx(skb);
dev-> stats.rx_packets++;
Wang> - dev->stats.rx_bytes += skb->len;
Wang> + dev->stats.rx_bytes += len;

Why not simply update the stats before calling netif_rx as the return value isn't checked anyway?

Signature · 1 line
Bye, Peter Korsgaard
author
#4 lore raw

Peter Korsgaard said the following on 2007-12-3 21:47:

Quoted 4 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"Wang" == Wang Chen <[email protected]> writes:

Hi,

Quoted 9 lines

Wang> + len = skb->len;
Wang> netif_rx(skb);
dev-> stats.rx_packets++;
Wang> - dev->stats.rx_bytes += skb->len;
Wang> + dev->stats.rx_bytes += len;

Why not simply update the stats before calling netif_rx as the return value isn't checked anyway?

Even the return value of netif_rx isn't checked, dev->stats maybe changed in netif_rx. But fortunately dev->stats isn't changed in netif_rx.
So, I agree.
Here is the new patch.

---
 smc911x.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)
drivers/net/smc911x.c +1 -1
@@ -1299,9 +1299,9 @@ smc911x_rx_dma_irq(int dma, void *data)
 	PRINT_PKT(skb->data, skb->len);
 	dev->last_rx = jiffies;
 	skb->protocol = eth_type_trans(skb, dev);
-	netif_rx(skb);
 	dev->stats.rx_packets++;
 	dev->stats.rx_bytes += skb->len;
+	netif_rx(skb);
 
 	spin_lock_irqsave(&lp->lock, flags);
 	pkts = (SMC_GET_RX_FIFO_INF() & RX_FIFO_INF_RXSUSED_) >> 16;
#5 lore raw
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"Wang" == Wang Chen <[email protected]> writes:

Hi,

Quoted 2 lines
Quoted 2 lines

Why not simply update the stats before calling netif_rx as the return value isn't checked anyway?

Wang> Even the return value of netif_rx isn't checked, dev->stats maybe Wang> changed in netif_rx. But fortunately dev->stats isn't changed in Wang> netif_rx.
Wang> So, I agree.
Wang> Here is the new patch.

Thanks.

Wang> Signed-off-by: Wang Chen <[email protected]>

Signature · 1 line
Bye, Peter Korsgaard
#6 lore raw
In reply to Wang Chen
Quoted 27 lines · Wang Chen

Peter Korsgaard said the following on 2007-12-3 21:47:

Quoted 12 lines
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line

"Wang" == Wang Chen <[email protected]> writes:

Hi,

Wang> + len = skb->len;
Wang> netif_rx(skb);
dev-> stats.rx_packets++;
Wang> - dev->stats.rx_bytes += skb->len;
Wang> + dev->stats.rx_bytes += len;

Why not simply update the stats before calling netif_rx as the return value isn't checked anyway?

Even the return value of netif_rx isn't checked, dev->stats maybe changed in netif_rx. But fortunately dev->stats isn't changed in netif_rx.
So, I agree. Here is the new patch.

---
 smc911x.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)

drivers/net/smc911x.c smc911x_rx_dma_irq(int dma, void *data) · line 1305

Quoted 8 lines
drivers/net/smc911x.c +1 -1
@@ -1299,9 +1299,9 @@ smc911x_rx_dma_irq(int dma, void *data)
 	PRINT_PKT(skb->data, skb->len);
 	dev->last_rx = jiffies;
 	skb->protocol = eth_type_trans(skb, dev);
-	netif_rx(skb);
 	dev->stats.rx_packets++;
 	dev->stats.rx_bytes += skb->len;
+	netif_rx(skb);
 

applied #upstream-fixes