• Erik Hugne's avatar
    tipc: correctly unlink packets from deferred packet queue · 732256b9
    Erik Hugne authored
    When we pull a received packet from a link's 'deferred packets' queue
    for processing, its 'next' pointer is not cleared, and still refers to
    the next packet in that queue, if any. This is incorrect, but caused
    no harm before commit 40ba3cdf ("tipc:
    message reassembly using fragment chain") was introduced. After that
    commit, it may sometimes lead to the following oops:
    
    general protection fault: 0000 [#1] SMP DEBUG_PAGEALLOC
    Modules linked in: tipc
    CPU: 4 PID: 0 Comm: swapper/4 Tainted: G        W 3.13.0-rc2+ #6
    Hardware name: Bochs Bochs, BIOS Bochs 01/01/2007
    task: ffff880017af4880 ti: ffff880017aee000 task.ti: ffff880017aee000
    RIP: 0010:[<ffffffff81710694>]  [<ffffffff81710694>] skb_try_coalesce+0x44/0x3d0
    RSP: 0018:ffff880016603a78  EFLAGS: 00010212
    RAX: 6b6b6b6bd6d6d6d6 RBX: ffff880013106ac0 RCX: ffff880016603ad0
    RDX: ffff880016603ad7 RSI: ffff88001223ed00 RDI: ffff880013106ac0
    RBP: ffff880016603ab8 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000001 R11: 0000000000000000 R12: ffff88001223ed00
    R13: ffff880016603ad0 R14: 000000000000058c R15: ffff880012297650
    FS:  0000000000000000(0000) GS:ffff880016600000(0000) knlGS:0000000000000000
    CS:  0010 DS: 0000 ES: 0000 CR0: 000000008005003b
    CR2: 000000000805b000 CR3: 0000000011f5d000 CR4: 00000000000006e0
    Stack:
     ffff880016603a88 ffffffff810a38ed ffff880016603aa8 ffff88001223ed00
     0000000000000001 ffff880012297648 ffff880016603b68 ffff880012297650
     ffff880016603b08 ffffffffa0006c51 ffff880016603b08 00ffffffa00005fc
    Call Trace:
     <IRQ>
     [<ffffffff810a38ed>] ? trace_hardirqs_on+0xd/0x10
     [<ffffffffa0006c51>] tipc_link_recv_fragment+0xd1/0x1b0 [tipc]
     [<ffffffffa0007214>] tipc_recv_msg+0x4e4/0x920 [tipc]
     [<ffffffffa00016f0>] ? tipc_l2_rcv_msg+0x40/0x250 [tipc]
     [<ffffffffa000177c>] tipc_l2_rcv_msg+0xcc/0x250 [tipc]
     [<ffffffffa00016f0>] ? tipc_l2_rcv_msg+0x40/0x250 [tipc]
     [<ffffffff8171e65b>] __netif_receive_skb_core+0x80b/0xd00
     [<ffffffff8171df94>] ? __netif_receive_skb_core+0x144/0xd00
     [<ffffffff8171eb76>] __netif_receive_skb+0x26/0x70
     [<ffffffff8171ed6d>] netif_receive_skb+0x2d/0x200
     [<ffffffff8171fe70>] napi_gro_receive+0xb0/0x130
     [<ffffffff815647c2>] e1000_clean_rx_irq+0x2c2/0x530
     [<ffffffff81565986>] e1000_clean+0x266/0x9c0
     [<ffffffff81985f7b>] ? notifier_call_chain+0x2b/0x160
     [<ffffffff8171f971>] net_rx_action+0x141/0x310
     [<ffffffff81051c1b>] __do_softirq+0xeb/0x480
     [<ffffffff819817bb>] ? _raw_spin_unlock+0x2b/0x40
     [<ffffffff810b8c42>] ? handle_fasteoi_irq+0x72/0x100
     [<ffffffff81052346>] irq_exit+0x96/0xc0
     [<ffffffff8198cbc3>] do_IRQ+0x63/0xe0
     [<ffffffff81981def>] common_interrupt+0x6f/0x6f
     <EOI>
    
    This happens when the last fragment of a message has passed through the
    the receiving link's 'deferred packets' queue, and at least one other
    packet was added to that queue while it was there. After the fragment
    chain with the complete message has been successfully delivered to the
    receiving socket, it is released. Since 'next' pointer of the last
    fragment in the released chain now is non-NULL, we get the crash shown
    above.
    
    We fix this by clearing the 'next' pointer of all received packets,
    including those being pulled from the 'deferred' queue, before they
    undergo any further processing.
    
    Fixes: 40ba3cdf ("tipc: message reassembly using fragment chain")
    Signed-off-by: default avatarErik Hugne <erik.hugne@ericsson.com>
    Reported-by: default avatarYing Xue <ying.xue@windriver.com>
    Reviewed-by: default avatarPaul Gortmaker <paul.gortmaker@windriver.com>
    Signed-off-by: default avatarJon Maloy <jon.maloy@ericsson.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    732256b9
link.c 73.8 KB