diff mbox

[10/10] tcp: handle shift/merge of cloned skbs too

Message ID 1227536527-29713-11-git-send-email-ilpo.jarvinen@helsinki.fi
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Ilpo Järvinen Nov. 24, 2008, 2:22 p.m. UTC
This caused me to get repeatably:

  tcpdump: pcap_loop: recvfrom: Bad address

Happens occassionally when I tcpdump my for-looped test xfers:
  while [ : ]; do echo -n "$(date '+%s.%N') "; ./sendfile; sleep 20; done

Rest of the relevant commands:
  ethtool -K eth0 tso off
  tc qdisc add dev eth0 root netem drop 4%
  tcpdump -n -s0 -i eth0 -w sacklog.all

Running net-next under kvm, connection goes to the same host
(basically just out of kvm). The connection itself works ok
and data gets sent without corruption even with a large
number of tests while tcpdump fails usually within less than
5 tests.

Whether it only happens because of this change or not, I
don't know for sure but it's the only thing with which
I've seen that error. The non-cloned variant works w/o it
for much longer time. I'm yet to debug where the error
actually comes from.

Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@helsinki.fi>
---
 net/core/skbuff.c |    7 ++-----
 1 files changed, 2 insertions(+), 5 deletions(-)

Comments

David Miller Nov. 25, 2008, 5:32 a.m. UTC | #1
From: "Ilpo Järvinen" <ilpo.jarvinen@helsinki.fi>
Date: Mon, 24 Nov 2008 16:22:07 +0200

> This caused me to get repeatably:
> 
>   tcpdump: pcap_loop: recvfrom: Bad address
> 
> Happens occassionally when I tcpdump my for-looped test xfers:
>   while [ : ]; do echo -n "$(date '+%s.%N') "; ./sendfile; sleep 20; done
> 
> Rest of the relevant commands:
>   ethtool -K eth0 tso off
>   tc qdisc add dev eth0 root netem drop 4%
>   tcpdump -n -s0 -i eth0 -w sacklog.all

I'm applying this in any event.

What could be happening is some bad clone handling
elsewhere (AF_PACKET, for example) and thus for some
reason libpcap reads stale data then performs a packet
read using incorrect lengths and this leads to reading
past the end of it's user buffer and we -EFAULT.

Just capturing the -EFAULT'ing call arguments with strace
would be enough to give some deeper clues.  Do you have
that?
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 844b8ab..57555a4 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -2018,13 +2018,10 @@  void skb_split(struct sk_buff *skb, struct sk_buff *skb1, const u32 len)
 		skb_split_no_header(skb, skb1, len, pos);
 }
 
-/* Shifting from/to a cloned skb is a no-go.
- *
- * TODO: handle cloned skbs by using pskb_expand_head()
- */
+/* Shifting from/to a cloned skb is a no-go. */
 static int skb_prepare_for_shift(struct sk_buff *skb)
 {
-	return skb_cloned(skb);
+	return skb_cloned(skb) && pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
 }
 
 /**