• Stefan Bader's avatar
    UBUNTU: SAUCE: ipv6: frags: fix skb extraction in ip6_expire_frag_queue() · 4abd842e
    Stefan Bader authored
    BugLink: https://bugs.launchpad.net/bugs/1824687
    
    The backport of
    
      05c0b86b ("ipv6: frags: rewrite ip6_expire_frag_queue()")
    
    to linux-4.4.y stable changed ip6_expire_frag_queue() to be similar
    to ip_expire(). However, using skb_get() leads to a crash while
    sending the ICMP message due to a check for shared SKBs.
    
       kernel BUG at linux-4.4.0/net/core/skbuff.c:1207!
       RIP: 0010:[<ffffffff81740953>]
        [<ffffffff81740953>] pskb_expand_head+0x243/0x250
        [<ffffffff81740e50>] __pskb_pull_tail+0x50/0x350
        [<ffffffff8183939a>] _decode_session6+0x26a/0x400
        [<ffffffff817ec719>] __xfrm_decode_session+0x39/0x50
        [<ffffffff818239d0>] icmpv6_route_lookup+0xf0/0x1c0
        [<ffffffff81824421>] icmp6_send+0x5e1/0x940
        [<ffffffff8183d431>] icmpv6_send+0x21/0x30
        [<ffffffff8182b500>] ip6_expire_frag_queue+0xe0/0x120
    
    For IPv4 the ip_expire() function however did change considerably
    since then. In
    
      fa0f5273 ("ip: use rb trees for IP frag queue.")
    
    the SKB might be taken from a rbtree (use of rbtrees for IPv4 was
    backported to 4.4.y upstream).
    Along with those obvious changes, the code also is modified to
    actually de-queue the SKB from whichever source it was taken.
    This also got rid of the skb_get() which causes problems in
    icmpv6_send(). And latest upstream code uses inet_frag_pull_head()
    which does the same.
    
    To fix the crash in IPv6, we use the same modifications added
    to ip_expire() by fa0f5273. This might be too much change for
    now because IPv6 only starts using rbtrees for frags with
    
      997dd964 ("net: IP6 defrag: use rbtrees in nf_conntrack_reasm.c")
    
    which has not been backported to 4.4.y. Testing by a reporter was
    showing good results. Likely the else part never gets used until
    997dd964 is backported, too. And that needs more changes.
    Some upstream (stable) discussion was started but has not yet
    resulted in any usable results. So adding this as SAUCE for now
    to get the kernel stable (based on testing).
    
    Fixes: bf8187348f ("ipv6: frags: rewrite ip6_expire_frag_queue()")
           in the linux-4.4.y stable tree.
    (based-on: f78a3f45e7 ("ip: use rb trees for IP frag queue." 4.4.y))
    Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
    Acked-by: default avatarColin King <colin.king@canonical.com>
    Acked-by: default avatarAndrea Righi <andrea.righi@canonical.com>
    Signed-off-by: default avatarStefan Bader <stefan.bader@canonical.com>
    4abd842e
reassembly.c 19.5 KB