Bug 674622 - Oops NULL pointer tcp_write_xmit
Summary: Oops NULL pointer tcp_write_xmit
Keywords:
Status: CLOSED WORKSFORME
Alias: None
Product: Fedora
Classification: Fedora
Component: kernel
Version: rawhide
Hardware: x86_64
OS: Unspecified
unspecified
unspecified
Target Milestone: ---
Assignee: Neil Horman
QA Contact: Fedora Extras Quality Assurance
URL:
Whiteboard:
Depends On:
Blocks:
TreeView+ depends on / blocked
 
Reported: 2011-02-02 16:46 UTC by John Reiser
Modified: 2011-04-29 14:24 UTC (History)
6 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed: 2011-04-29 14:24:08 UTC
Type: ---
Embargoed:


Attachments (Terms of Use)
kernel Oops traceback (4.90 KB, text/plain)
2011-02-02 16:46 UTC, John Reiser
no flags Details
patch to check pointers before assignment (413 bytes, patch)
2011-04-28 19:35 UTC, Neil Horman
no flags Details | Diff

Description John Reiser 2011-02-02 16:46:23 UTC
Created attachment 476615 [details]
kernel Oops traceback

Description of problem: Kernel Oops on NULL pointer dereference from tcp_write_xmit.


Version-Release number of selected component (if applicable):
kernel-2.6.38-0.rc3.git0.1.fc15.x86_64

How reproducible:


Steps to Reproduce:
1. scp <local> <remote>
2.
3.
  
Actual results: Oops


Expected results: no Oops


Additional info:

Comment 1 Chuck Ebbert 2011-02-04 20:01:56 UTC
OOPS is at include/linux/skbuff.h:895:
static inline void __skb_insert(struct sk_buff *newsk,
                                struct sk_buff *prev, struct sk_buff *next,
                                struct sk_buff_head *list)
{
        newsk->next = next;
        newsk->prev = prev;
==>     next->prev  = prev->next = newsk;
        list->qlen++;
}

  next is NULL here


Called from include/linux/skbuff.h:991:
static inline void __skb_queue_after(struct sk_buff_head *list,
                                     struct sk_buff *prev,
                                     struct sk_buff *newsk)
{
        __skb_insert(newsk, prev, prev->next, list);
}

Called from include/net/tcp.h:1294:
static inline void tcp_insert_write_queue_after(struct sk_buff *skb,
                                                struct sk_buff *buff,
                                                struct sock *sk)
{
        __skb_queue_after(&sk->sk_write_queue, skb, buff);
}

Called from net/ipv4/tcp_output.c:tso_fragment:1515:
        /* Link BUFF into the send queue. */
        skb_header_release(buff);
==>     tcp_insert_write_queue_after(skb, buff, sk);


Called from net/ipv4/tcp_output.c:tcp_write_xmit:1784:
                if (skb->len > limit &&
==>                 unlikely(tso_fragment(sk, skb, limit, mss_now, gfp)))
                        break;

Comment 2 Chuck Ebbert 2011-02-06 01:12:35 UTC
Reported upstream 02/04/2011:
http://marc.info/?l=linux-netdev&m=129685175319992&w=4

Comment 3 Chuck Ebbert 2011-02-10 19:17:43 UTC
Are you doing anything out of the ordinary with the network, like changing the qdisc, altering network adapter settings with ethtool, changing default routing options or using different / unusual iptables options?

Comment 4 John Reiser 2011-02-10 19:23:45 UTC
No, I did not touch anything that I know of, and in particular nothing mentioned in Comment #3.

Comment 5 Neil Horman 2011-04-28 19:34:16 UTC
If chucks decode of the location is right, It seems that __skb_insert is just a little bit to simple for its own good.  specifically it seems to not take into account the possibility that the skb you are inserting before or after might be at the head of tail of a list (implying that skb->next or skb->prev is null respectively).  I'll attach a patch for you to try shortly

Comment 6 Neil Horman 2011-04-28 19:35:41 UTC
Created attachment 495655 [details]
patch to check pointers before assignment

Here you go, could you please give this a try and confirm if it fixes the problem?  Thanks!

Comment 7 Neil Horman 2011-04-28 23:50:17 UTC
Actually, sorry, scrap what I just said, that list is supposed to be circular, so there shouldn't ever be NULL.  It is, however a bit odd that the skb that we insert after in tso_fragment, is never unlinked from the list its on in sk_send_head (retrieved from tcp_send_head in tcp_write_xmit).  I wonder if we're not getting an odd race there.  Feel free to try this patch, but it shouldn't be needed.  I'll have a better patch for you ASAP.

Comment 8 John Reiser 2011-04-29 02:08:45 UTC
Don't spend too much time on this one.  It only happened once, not quite three months ago.  "How reproducible" is empty (blank).  When it did happen, it was 'scp' doing a "push".  Oops is always worth of a report, but this one might well be stale.

Comment 9 Neil Horman 2011-04-29 14:24:08 UTC
Ok, copy that, I'll close it as WORKSFORME, but if you run into it again, please reopen.


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