• Shigeru Yoshida's avatar
    l2tp: Avoid possible recursive deadlock in l2tp_tunnel_register() · 9ca5e7ec
    Shigeru Yoshida authored
    When a file descriptor of pppol2tp socket is passed as file descriptor
    of UDP socket, a recursive deadlock occurs in l2tp_tunnel_register().
    This situation is reproduced by the following program:
    
    int main(void)
    {
    	int sock;
    	struct sockaddr_pppol2tp addr;
    
    	sock = socket(AF_PPPOX, SOCK_DGRAM, PX_PROTO_OL2TP);
    	if (sock < 0) {
    		perror("socket");
    		return 1;
    	}
    
    	addr.sa_family = AF_PPPOX;
    	addr.sa_protocol = PX_PROTO_OL2TP;
    	addr.pppol2tp.pid = 0;
    	addr.pppol2tp.fd = sock;
    	addr.pppol2tp.addr.sin_family = PF_INET;
    	addr.pppol2tp.addr.sin_port = htons(0);
    	addr.pppol2tp.addr.sin_addr.s_addr = inet_addr("192.168.0.1");
    	addr.pppol2tp.s_tunnel = 1;
    	addr.pppol2tp.s_session = 0;
    	addr.pppol2tp.d_tunnel = 0;
    	addr.pppol2tp.d_session = 0;
    
    	if (connect(sock, (const struct sockaddr *)&addr, sizeof(addr)) < 0) {
    		perror("connect");
    		return 1;
    	}
    
    	return 0;
    }
    
    This program causes the following lockdep warning:
    
     ============================================
     WARNING: possible recursive locking detected
     6.2.0-rc5-00205-gc9661827 #56 Not tainted
     --------------------------------------------
     repro/8607 is trying to acquire lock:
     ffff8880213c8130 (sk_lock-AF_PPPOX){+.+.}-{0:0}, at: l2tp_tunnel_register+0x2b7/0x11c0
    
     but task is already holding lock:
     ffff8880213c8130 (sk_lock-AF_PPPOX){+.+.}-{0:0}, at: pppol2tp_connect+0xa82/0x1a30
    
     other info that might help us debug this:
      Possible unsafe locking scenario:
    
            CPU0
            ----
       lock(sk_lock-AF_PPPOX);
       lock(sk_lock-AF_PPPOX);
    
      *** DEADLOCK ***
    
      May be due to missing lock nesting notation
    
     1 lock held by repro/8607:
      #0: ffff8880213c8130 (sk_lock-AF_PPPOX){+.+.}-{0:0}, at: pppol2tp_connect+0xa82/0x1a30
    
     stack backtrace:
     CPU: 0 PID: 8607 Comm: repro Not tainted 6.2.0-rc5-00205-gc9661827 #56
     Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.1-2.fc37 04/01/2014
     Call Trace:
      <TASK>
      dump_stack_lvl+0x100/0x178
      __lock_acquire.cold+0x119/0x3b9
      ? lockdep_hardirqs_on_prepare+0x410/0x410
      lock_acquire+0x1e0/0x610
      ? l2tp_tunnel_register+0x2b7/0x11c0
      ? lock_downgrade+0x710/0x710
      ? __fget_files+0x283/0x3e0
      lock_sock_nested+0x3a/0xf0
      ? l2tp_tunnel_register+0x2b7/0x11c0
      l2tp_tunnel_register+0x2b7/0x11c0
      ? sprintf+0xc4/0x100
      ? l2tp_tunnel_del_work+0x6b0/0x6b0
      ? debug_object_deactivate+0x320/0x320
      ? lockdep_init_map_type+0x16d/0x7a0
      ? lockdep_init_map_type+0x16d/0x7a0
      ? l2tp_tunnel_create+0x2bf/0x4b0
      ? l2tp_tunnel_create+0x3c6/0x4b0
      pppol2tp_connect+0x14e1/0x1a30
      ? pppol2tp_put_sk+0xd0/0xd0
      ? aa_sk_perm+0x2b7/0xa80
      ? aa_af_perm+0x260/0x260
      ? bpf_lsm_socket_connect+0x9/0x10
      ? pppol2tp_put_sk+0xd0/0xd0
      __sys_connect_file+0x14f/0x190
      __sys_connect+0x133/0x160
      ? __sys_connect_file+0x190/0x190
      ? lockdep_hardirqs_on+0x7d/0x100
      ? ktime_get_coarse_real_ts64+0x1b7/0x200
      ? ktime_get_coarse_real_ts64+0x147/0x200
      ? __audit_syscall_entry+0x396/0x500
      __x64_sys_connect+0x72/0xb0
      do_syscall_64+0x38/0xb0
      entry_SYSCALL_64_after_hwframe+0x63/0xcd
    
    This patch fixes the issue by getting/creating the tunnel before
    locking the pppol2tp socket.
    
    Fixes: 0b2c5972 ("l2tp: close all race conditions in l2tp_tunnel_register()")
    Cc: Cong Wang <cong.wang@bytedance.com>
    Signed-off-by: default avatarShigeru Yoshida <syoshida@redhat.com>
    Reviewed-by: default avatarGuillaume Nault <gnault@redhat.com>
    Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
    9ca5e7ec
l2tp_ppp.c 42.6 KB