Bug 6409 - llc_rcv doesn't handle receives using nr_frags and frags[]
Summary: llc_rcv doesn't handle receives using nr_frags and frags[]
Status: RESOLVED CODE_FIX
Alias: None
Product: Networking
Classification: Unclassified
Component: Other (show other bugs)
Hardware: i386 Linux
: P2 normal
Assignee: Arnaldo Carvalho de Melo
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-04-19 11:32 UTC by Jesse Brandeburg
Modified: 2006-04-21 14:49 UTC (History)
0 users

See Also:
Kernel Version: 2.6.16
Subsystem:
Regression: ---
Bisected commit-id:


Attachments
distro kernel BUG output (1.61 KB, text/plain)
2006-04-19 11:35 UTC, Jesse Brandeburg
Details

Description Jesse Brandeburg 2006-04-19 11:32:15 UTC
Most recent kernel where this bug did not occur:
Distribution: n/a
Hardware Environment: i686
Software Environment: n/a
Problem Description:
after hitting a *very hard to repro* BUG in a distro kernel I did some code
inspection that seems to show that llc_rcv does not handle receive packets using 
skb->data *and* skb_shinfo(skb)->frags[]/nr_frags

Steps to reproduce:
Apparently receiving some netware (802_2) traffic when using one of the
PCI-Express e1000 adapters with packet splitting enabled.  Even if the packet is
not split a large frame will use skb->data and ->frags[]

Analysis:
llc_rcv 
  does a skb_clone inside skb_share_check
llc_fixup_skb
skb_trim
__skb_trim
___pskb_trim(x,x,0) <-- realloc set to 0
___pskb_trim BUG on !realloc inside skb_cloned check

I'll attach the trace from the vendor kernel, I believe the problem is still
relevant to 2.6.16.
Comment 1 Jesse Brandeburg 2006-04-19 11:35:56 UTC
Created attachment 7903 [details]
distro kernel BUG output

yes, this is on a distro kernel, but the bug is nearly impossible to reproduce.
 Please see the analysis for how it can happen on 2.6.16
Comment 2 Andrew Morton 2006-04-19 11:39:00 UTC

Begin forwarded message:

Date: Wed, 19 Apr 2006 11:32:18 -0700
From: bugme-daemon@bugzilla.kernel.org
To: bugme-new@lists.osdl.org
Subject: [Bugme-new] [Bug 6409] New: llc_rcv doesn't handle receives using nr_frags and frags[]


http://bugzilla.kernel.org/show_bug.cgi?id=6409

           Summary: llc_rcv doesn't handle receives using nr_frags and
                    frags[]
    Kernel Version: 2.6.16
            Status: NEW
          Severity: normal
             Owner: acme@conectiva.com.br
         Submitter: jesse.brandeburg@intel.com


Most recent kernel where this bug did not occur:
Distribution: n/a
Hardware Environment: i686
Software Environment: n/a
Problem Description:
after hitting a *very hard to repro* BUG in a distro kernel I did some code
inspection that seems to show that llc_rcv does not handle receive packets using 
skb->data *and* skb_shinfo(skb)->frags[]/nr_frags

Steps to reproduce:
Apparently receiving some netware (802_2) traffic when using one of the
PCI-Express e1000 adapters with packet splitting enabled.  Even if the packet is
not split a large frame will use skb->data and ->frags[]

Analysis:
llc_rcv 
  does a skb_clone inside skb_share_check
llc_fixup_skb
skb_trim
__skb_trim
___pskb_trim(x,x,0) <-- realloc set to 0
___pskb_trim BUG on !realloc inside skb_cloned check

I'll attach the trace from the vendor kernel, I believe the problem is still
relevant to 2.6.16.

------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.

Comment 3 Anonymous Emailer 2006-04-19 15:37:55 UTC
Reply-To: davem@davemloft.net

From: Andrew Morton <akpm@osdl.org>
Date: Wed, 19 Apr 2006 11:38:06 -0700

> Analysis:
> llc_rcv 
>   does a skb_clone inside skb_share_check
> llc_fixup_skb
> skb_trim
> __skb_trim
> ___pskb_trim(x,x,0) <-- realloc set to 0
> ___pskb_trim BUG on !realloc inside skb_cloned check

I'll fix it like this:

diff-tree 5185db09f46ed64d520d09db6e93852e44106628 (from 3672558c6180ca28a7aa46765702467a37e58fc5)
Author: David S. Miller <davem@sunset.davemloft.net>
Date:   Wed Apr 19 15:37:13 2006 -0700

    [LLC]: Use pskb_trim_rcsum() in llc_fixup_skb().
    
    Kernel Bugzilla #6409
    
    If we use plain skb_trim(), that's wrong, because if
    the SKB is cloned, and it can be because we unshared
    it in the caller, we have to allow reallocation.  The
    pskb_trim*() family of routines is therefore the most
    appropriate here.
    
    Signed-off-by: David S. Miller <davem@davemloft.net>

diff --git a/net/llc/llc_input.c b/net/llc/llc_input.c
index 8f3addf..d62e0f9 100644
--- a/net/llc/llc_input.c
+++ b/net/llc/llc_input.c
@@ -118,7 +118,8 @@ static inline int llc_fixup_skb(struct s
 		u16 pdulen = eth_hdr(skb)->h_proto,
 		    data_size = ntohs(pdulen) - llc_len;
 
-		skb_trim(skb, data_size);
+		if (unlikely(pskb_trim_rcsum(skb, data_size)))
+			return 0;
 	}
 	return 1;
 }

Comment 4 Jesse Brandeburg 2006-04-21 14:49:08 UTC
testing to see if this patch fixes the issue.

Note You need to log in before you can comment on or make changes to this bug.