linux/net/core
Andrea Shepard 00c5a9834b net: Fix corruption of skb csum field in pskb_expand_head() of net/core/skbuff.c
Make pskb_expand_head() check ip_summed to make sure csum_start is really
csum_start and not csum before adjusting it.

This fixes a bug I encountered using a Sun Quad-Fast Ethernet card and VLANs.
On my configuration, the sunhme driver produces skbs with differing amounts
of headroom on receive depending on the packet size.  See line 2030 of
drivers/net/sunhme.c; packets smaller than RX_COPY_THRESHOLD have 52 bytes
of headroom but packets larger than that cutoff have only 20 bytes.

When these packets reach the VLAN driver, vlan_check_reorder_header()
calls skb_cow(), which, if the packet has less than NET_SKB_PAD (== 32) bytes
of headroom, uses pskb_expand_head() to make more.

Then, pskb_expand_head() needs to adjust a lot of offsets into the skb,
including csum_start.  Since csum_start is a union with csum, if the packet
has a valid csum value this will corrupt it, which was the effect I observed.
The sunhme hardware computes receive checksums, so the skbs would be created
by the driver with ip_summed == CHECKSUM_COMPLETE and a valid csum field, and
then pskb_expand_head() would corrupt the csum field, leading to an "hw csum
error" message later on, for example in icmp_rcv() for pings larger than the
sunhme RX_COPY_THRESHOLD.

On the basis of the comment at the beginning of include/linux/skbuff.h,
I believe that the csum_start skb field is only meaningful if ip_csummed is
CSUM_PARTIAL, so this patch makes pskb_expand_head() adjust it only in that
case to avoid corrupting a valid csum value.

Please see my more in-depth disucssion of tracking down this bug for
more details if you like:

http://puellavulnerata.livejournal.com/112186.html
http://puellavulnerata.livejournal.com/112567.html
http://puellavulnerata.livejournal.com/112891.html
http://puellavulnerata.livejournal.com/113096.html
http://puellavulnerata.livejournal.com/113591.html

I am not subscribed to this list, so please CC me on replies.

Signed-off-by: Andrea Shepard <andrea@persephoneslair.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
2010-07-22 13:25:18 -07:00
..
datagram.c net: fix lock_sock_bh/unlock_sock_bh 2010-05-27 00:30:53 -07:00
dev.c net: fix problem in reading sock TX queue 2010-07-14 20:50:29 -07:00
dev_addr_lists.c net: include linux/proc_fs.h in dev_addr_lists.c 2010-04-07 16:46:36 -07:00
drop_monitor.c tracing: Let tracepoints have data passed to tracepoint callbacks 2010-05-14 09:50:34 -04:00
dst.c dst: don't inline dst_ifdown 2010-04-13 03:32:44 -07:00
ethtool.c ethtool: Fix potential user buffer overflow for ETHTOOL_{G, S}RXFH 2010-06-29 01:00:29 -07:00
fib_rules.c net: fib_rules: mark arguments to fib_rules_register const and __net_initdata 2010-04-26 16:02:04 +02:00
filter.c net: Socket filter ancilliary data access for skb->dev->type 2010-04-22 16:05:44 -07:00
flow.c flow: delayed deletion of flow cache entries 2010-04-07 03:43:20 -07:00
gen_estimator.c pkt_sched: gen_estimator: add a new lock 2010-06-10 22:53:52 -07:00
gen_stats.c pkt_sched: gen_estimator: Dont report fake rate estimators 2009-10-07 01:07:42 -07:00
iovec.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
kmap_skb.h
link_watch.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
Makefile net: convert multicast list to list_head 2010-04-03 14:22:15 -07:00
neighbour.c net/core: neighbour update Oops 2010-07-14 18:02:16 -07:00
net-sysfs.c net: Expose all network devices in a namespaces in sysfs 2010-05-21 09:37:34 -07:00
net-sysfs.h net: Expose all network devices in a namespaces in sysfs 2010-05-21 09:37:34 -07:00
net-traces.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
net_namespace.c net: disallow to use net_assign_generic externally 2010-04-27 15:49:02 -07:00
netevent.c [NET]: net/core/netevent.c should #include <net/netevent.h> 2007-07-05 17:40:27 -07:00
netpoll.c netpoll: add generic support for bridge and bonding devices 2010-05-06 00:47:21 -07:00
pktgen.c pktgen: Fix accuracy of inter-packet delay. 2010-06-10 23:08:11 -07:00
request_sock.c net: convert BUG_TRAP to generic WARN_ON 2008-07-25 21:43:18 -07:00
rtnetlink.c netlink: bug fix: wrong size was calculated for vfinfo list blob 2010-05-28 03:42:43 -07:00
scm.c include cleanup: Update gfp.h and slab.h includes to prepare for breaking implicit slab.h inclusion from percpu.h 2010-03-30 22:02:32 +09:00
skbuff.c net: Fix corruption of skb csum field in pskb_expand_head() of net/core/skbuff.c 2010-07-22 13:25:18 -07:00
sock.c net: fix lock_sock_bh/unlock_sock_bh 2010-05-27 00:30:53 -07:00
stream.c net: sock_def_readable() and friends RCU conversion 2010-05-01 15:00:15 -07:00
sysctl_net_core.c net: Consistent skb timestamping 2010-05-15 23:57:10 -07:00
user_dma.c net/core/user_dma.c: Use frag list abstraction interfaces. 2009-06-09 00:19:10 -07:00
utils.c printk: Remove ratelimit.h from kernel.h 2009-09-22 16:18:09 +02:00