Skip to content
  • Paolo Abeni's avatar
    l2tp: fix races with ipv4-mapped ipv6 addresses · b0850604
    Paolo Abeni authored
    commit b954f940
    
     upstream.
    
    The l2tp_tunnel_create() function checks for v4mapped ipv6
    sockets and cache that flag, so that l2tp core code can
    reusing it at xmit time.
    
    If the socket is provided by the userspace, the connection
    status of the tunnel sockets can change between the tunnel
    creation and the xmit call, so that syzbot is able to
    trigger the following splat:
    
    BUG: KASAN: use-after-free in ip6_dst_idev include/net/ip6_fib.h:192
    [inline]
    BUG: KASAN: use-after-free in ip6_xmit+0x1f76/0x2260
    net/ipv6/ip6_output.c:264
    Read of size 8 at addr ffff8801bd949318 by task syz-executor4/23448
    
    CPU: 0 PID: 23448 Comm: syz-executor4 Not tainted 4.16.0-rc4+ #65
    Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS
    Google 01/01/2011
    Call Trace:
      __dump_stack lib/dump_stack.c:17 [inline]
      dump_stack+0x194/0x24d lib/dump_stack.c:53
      print_address_description+0x73/0x250 mm/kasan/report.c:256
      kasan_report_error mm/kasan/report.c:354 [inline]
      kasan_report+0x23c/0x360 mm/kasan/report.c:412
      __asan_report_load8_noabort+0x14/0x20 mm/kasan/report.c:433
      ip6_dst_idev include/net/ip6_fib.h:192 [inline]
      ip6_xmit+0x1f76/0x2260 net/ipv6/ip6_output.c:264
      inet6_csk_xmit+0x2fc/0x580 net/ipv6/inet6_connection_sock.c:139
      l2tp_xmit_core net/l2tp/l2tp_core.c:1053 [inline]
      l2tp_xmit_skb+0x105f/0x1410 net/l2tp/l2tp_core.c:1148
      pppol2tp_sendmsg+0x470/0x670 net/l2tp/l2tp_ppp.c:341
      sock_sendmsg_nosec net/socket.c:630 [inline]
      sock_sendmsg+0xca/0x110 net/socket.c:640
      ___sys_sendmsg+0x767/0x8b0 net/socket.c:2046
      __sys_sendmsg+0xe5/0x210 net/socket.c:2080
      SYSC_sendmsg net/socket.c:2091 [inline]
      SyS_sendmsg+0x2d/0x50 net/socket.c:2087
      do_syscall_64+0x281/0x940 arch/x86/entry/common.c:287
      entry_SYSCALL_64_after_hwframe+0x42/0xb7
    RIP: 0033:0x453e69
    RSP: 002b:00007f819593cc68 EFLAGS: 00000246 ORIG_RAX: 000000000000002e
    RAX: ffffffffffffffda RBX: 00007f819593d6d4 RCX: 0000000000453e69
    RDX: 0000000000000081 RSI: 000000002037ffc8 RDI: 0000000000000004
    RBP: 000000000072bea0 R08: 0000000000000000 R09: 0000000000000000
    R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff
    R13: 00000000000004c3 R14: 00000000006f72e8 R15: 0000000000000000
    
    This change addresses the issues:
    * explicitly checking for TCP_ESTABLISHED for user space provided sockets
    * dropping the v4mapped flag usage - it can become outdated - and
      explicitly invoking ipv6_addr_v4mapped() instead
    
    The issue is apparently there since ancient times.
    
    v1 -> v2: (many thanks to Guillaume)
     - with csum issue introduced in v1
     - replace pr_err with pr_debug
     - fix build issue with IPV6 disabled
     - move l2tp_sk_is_v4mapped in l2tp_core.c
    
    v2 -> v3:
     - don't update inet_daddr for v4mapped address, unneeded
     - drop rendundant check at creation time
    
    Reported-and-tested-by: default avatar <syzbot+92fa328176eb07e4ac1a@syzkaller.appspotmail.com>
    Fixes: 3557baab
    
     ("[L2TP]: PPP over L2TP driver core")
    Signed-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>
    b0850604