• Stanislav Fomichev's avatar
    tun: publish tfile after it's fully initialized · 0b7959b6
    Stanislav Fomichev authored
    BUG: unable to handle kernel NULL pointer dereference at 00000000000000d1
    Call Trace:
     ? napi_gro_frags+0xa7/0x2c0
     tun_get_user+0xb50/0xf20
     tun_chr_write_iter+0x53/0x70
     new_sync_write+0xff/0x160
     vfs_write+0x191/0x1e0
     __x64_sys_write+0x5e/0xd0
     do_syscall_64+0x47/0xf0
     entry_SYSCALL_64_after_hwframe+0x44/0xa9
    
    I think there is a subtle race between sending a packet via tap and
    attaching it:
    
    CPU0:                    CPU1:
    tun_chr_ioctl(TUNSETIFF)
      tun_set_iff
        tun_attach
          rcu_assign_pointer(tfile->tun, tun);
                             tun_fops->write_iter()
                               tun_chr_write_iter
                                 tun_napi_alloc_frags
                                   napi_get_frags
                                     napi->skb = napi_alloc_skb
          tun_napi_init
            netif_napi_add
              napi->skb = NULL
                                  napi->skb is NULL here
                                  napi_gro_frags
                                    napi_frags_skb
    				  skb = napi->skb
    				  skb_reset_mac_header(skb)
    				  panic()
    
    Move rcu_assign_pointer(tfile->tun) and rcu_assign_pointer(tun->tfiles) to
    be the last thing we do in tun_attach(); this should guarantee that when we
    call tun_get() we always get an initialized object.
    
    v2 changes:
    * remove extra napi_mutex locks/unlocks for napi operations
    Reported-by: default avatarsyzbot <syzkaller@googlegroups.com>
    Fixes: 90e33d45 ("tun: enable napi_gro_frags() for TUN/TAP driver")
    Signed-off-by: default avatarStanislav Fomichev <sdf@google.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    0b7959b6
tun.c 85.6 KB