• Liping Zhang's avatar
    netfilter: cttimeout: fix use after free error when delete netns · b75911b6
    Liping Zhang authored
    In general, when we want to delete a netns, cttimeout_net_exit will
    be called before ipt_unregister_table, i.e. before ctnl_timeout_put.
    
    But after call kfree_rcu in cttimeout_net_exit, we will still decrease
    the timeout object's refcnt in ctnl_timeout_put, this is incorrect,
    and will cause a use after free error.
    
    It is easy to reproduce this problem:
      # while : ; do
      ip netns add xxx
      ip netns exec xxx nfct add timeout testx inet icmp timeout 200
      ip netns exec xxx iptables -t raw -p icmp -I OUTPUT -j CT --timeout testx
      ip netns del xxx
      done
    
      =======================================================================
      BUG kmalloc-96 (Tainted: G    B       E  ): Poison overwritten
      -----------------------------------------------------------------------
      INFO: 0xffff88002b5161e8-0xffff88002b5161e8. First byte 0x6a instead of
      0x6b
      INFO: Allocated in cttimeout_new_timeout+0xd4/0x240 [nfnetlink_cttimeout]
      age=104 cpu=0 pid=3330
      ___slab_alloc+0x4da/0x540
      __slab_alloc+0x20/0x40
      __kmalloc+0x1c8/0x240
      cttimeout_new_timeout+0xd4/0x240 [nfnetlink_cttimeout]
      nfnetlink_rcv_msg+0x21a/0x230 [nfnetlink]
      [ ... ]
    
    So only when the refcnt decreased to 0, we call kfree_rcu to free the
    timeout object. And like nfnetlink_acct do, use atomic_cmpxchg to
    avoid race between ctnl_timeout_try_del and ctnl_timeout_put.
    Signed-off-by: default avatarLiping Zhang <liping.zhang@spreadtrum.com>
    Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
    b75911b6
nfnetlink_cttimeout.c 15.9 KB