• WANG Cong's avatar
    sit: fix a double free on error path · c683ac5e
    WANG Cong authored
    [ Upstream commit d7426c69 ]
    
    Dmitry reported a double free in sit_init_net():
    
      kernel BUG at mm/percpu.c:689!
      invalid opcode: 0000 [#1] SMP KASAN
      Dumping ftrace buffer:
         (ftrace buffer empty)
      Modules linked in:
      CPU: 0 PID: 15692 Comm: syz-executor1 Not tainted 4.10.0-rc6-next-20170206 #1
      Hardware name: Google Google Compute Engine/Google Compute Engine,
      BIOS Google 01/01/2011
      task: ffff8801c9cc27c0 task.stack: ffff88017d1d8000
      RIP: 0010:pcpu_free_area+0x68b/0x810 mm/percpu.c:689
      RSP: 0018:ffff88017d1df488 EFLAGS: 00010046
      RAX: 0000000000010000 RBX: 00000000000007c0 RCX: ffffc90002829000
      RDX: 0000000000010000 RSI: ffffffff81940efb RDI: ffff8801db841d94
      RBP: ffff88017d1df590 R08: dffffc0000000000 R09: 1ffffffff0bb3bdd
      R10: dffffc0000000000 R11: 00000000000135dd R12: ffff8801db841d80
      R13: 0000000000038e40 R14: 00000000000007c0 R15: 00000000000007c0
      FS:  00007f6ea608f700(0000) GS:ffff8801dbe00000(0000) knlGS:0000000000000000
      CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
      CR2: 000000002000aff8 CR3: 00000001c8d44000 CR4: 00000000001426f0
      DR0: 0000000020000000 DR1: 0000000020000000 DR2: 0000000000000000
      DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000600
      Call Trace:
       free_percpu+0x212/0x520 mm/percpu.c:1264
       ipip6_dev_free+0x43/0x60 net/ipv6/sit.c:1335
       sit_init_net+0x3cb/0xa10 net/ipv6/sit.c:1831
       ops_init+0x10a/0x530 net/core/net_namespace.c:115
       setup_net+0x2ed/0x690 net/core/net_namespace.c:291
       copy_net_ns+0x26c/0x530 net/core/net_namespace.c:396
       create_new_namespaces+0x409/0x860 kernel/nsproxy.c:106
       unshare_nsproxy_namespaces+0xae/0x1e0 kernel/nsproxy.c:205
       SYSC_unshare kernel/fork.c:2281 [inline]
       SyS_unshare+0x64e/0xfc0 kernel/fork.c:2231
       entry_SYSCALL_64_fastpath+0x1f/0xc2
    
    This is because when tunnel->dst_cache init fails, we free dev->tstats
    once in ipip6_tunnel_init() and twice in sit_init_net(). This looks
    redundant but its ndo_uinit() does not seem enough to clean up everything
    here. So avoid this by setting dev->tstats to NULL after the first free,
    at least for -net.
    Reported-by: default avatarDmitry Vyukov <dvyukov@google.com>
    Signed-off-by: default avatarCong Wang <xiyou.wangcong@gmail.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: default avatarBen Hutchings <ben@decadent.org.uk>
    c683ac5e
sit.c 41.5 KB