[638] in linux-net channel archive
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