[638] in linux-net channel archive

home help back first fref pref prev next nref lref last post

Re: Another NULL dereference in 1.3.8

daemon@ATHENA.MIT.EDU (Paul Gortmaker)
Sun Jul 9 15:35:38 1995

From: Paul Gortmaker <gpg109@rsphy1.anu.edu.au>
To: iialan@iifeak.swan.ac.uk (Alan Cox)
Date: Sun, 9 Jul 1995 20:33:21 +1000 (EST)
Cc: torvalds@cs.Helsinki.FI (Linus Torvalds), linux-net@vger.rutgers.edu
In-Reply-To: <m0sU8ru-00013rC@iiit.swan.ac.uk> from "Alan Cox" at Jul 7, 95 09:34:36 am

Hi Alan,

> > Oh, and another minor nit -- the prototype for eth_copy_and_sum() should
> > be stuck in some header file somewhere so gcc doesn't complain when
> > compiling the lance driver (and others that use it).
> 
> Yep.. minor oversight.
> 
> Alan

But it would have caught the fact that the fix in 1.3.8 was wrong if it
had been there. The NULL dereference was because eth_copy_and_sum()
is expecting an skb, and not the skb->tail returned from skb_put().
Basically you removed the wrong skb_put() in the 1.3.8 patch.

Now I can boot without exploding. Note however that the csums in
csum_partial_copy() are still broken and only some packets get through.
I have verified this by doing in eth_copy_and_sum() a:

-	if(eth->h_proto!=htons(ETH_P_IP))
+	if (1)		/* Do checksum later */

which forces the csum to be done by the original routine, and then all
works as expected. I am not brave enough to tackle the asm in checksum.c 

Anyway here is the proper fix so the lance won't explode at boot. I guess 
you or Tom will have to figure out the asm problem in csum_partial_copy().

Regards,
Paul.

--- linux-oem-138/drivers/net/lance.c	Fri Jul  7 18:45:45 1995
+++ linux/drivers/net/lance.c	Sun Jul  9 19:28:24 1995
@@ -1000,7 +1000,8 @@
 			}
 			skb->dev = dev;
 			skb_reserve(skb,2);	/* 16 byte align */
-			eth_copy_and_sum(skb_put(skb,pkt_len),
+			skb_put(skb,pkt_len);	/* Make room */
+			eth_copy_and_sum(skb,
 				   (unsigned char *)(lp->rx_ring[entry].base & 0x00ffffff),
 				   pkt_len,0);
 			skb->protocol=eth_type_trans(skb,dev);
--- linux-oem-138/net/ethernet/eth.c	Wed Jul  5 20:06:27 1995
+++ linux/net/ethernet/eth.c	Sun Jul  9 19:23:10 1995
@@ -233,9 +233,12 @@
  *	Copy from an ethernet device memory space to an sk_buff while checksumming if IP
  */
  
-void eth_copy_and_sum(struct sk_buff *dest,unsigned char *src, int length, int base)
+void eth_copy_and_sum(struct sk_buff *dest, unsigned char *src, int length, int base)
 {
-	struct ethhdr *eth=(struct ethhdr *)dest->data;
+	struct ethhdr *eth;
+
+	IS_SKB(dest);
+	eth=(struct ethhdr *)dest->data;
 	memcpy(dest->data,src,34);	/* ethernet is always >= 60 */
 	length-=34;
 	if(eth->h_proto!=htons(ETH_P_IP))
--- linux-oem-138/include/linux/etherdevice.h	Fri Jun 30 02:18:51 1995
+++ linux/include/linux/etherdevice.h	Sun Jul  9 18:12:22 1995
@@ -34,6 +34,8 @@
 extern int		eth_rebuild_header(void *buff, struct device *dev,
 			unsigned long dst, struct sk_buff *skb);
 extern unsigned short	eth_type_trans(struct sk_buff *skb, struct device *dev);
+extern void		eth_copy_and_sum(struct sk_buff *dest,
+				unsigned char *src, int length, int base);
 
 #endif
 


home help back first fref pref prev next nref lref last post