• Kuniyuki Iwashima's avatar
    af_unix: Read sk->sk_hash under bindlock during bind(). · 51d1b25a
    Kuniyuki Iwashima authored
    syzkaller reported data-race of sk->sk_hash in unix_autobind() [0],
    and the same ones exist in unix_bind_bsd() and unix_bind_abstract().
    
    The three bind() functions prefetch sk->sk_hash locklessly and
    use it later after validating that unix_sk(sk)->addr is NULL under
    unix_sk(sk)->bindlock.
    
    The prefetched sk->sk_hash is the hash value of unbound socket set
    in unix_create1() and does not change until bind() completes.
    
    There could be a chance that sk->sk_hash changes after the lockless
    read.  However, in such a case, non-NULL unix_sk(sk)->addr is visible
    under unix_sk(sk)->bindlock, and bind() returns -EINVAL without using
    the prefetched value.
    
    The KCSAN splat is false-positive, but let's silence it by reading
    sk->sk_hash under unix_sk(sk)->bindlock.
    
    [0]:
    BUG: KCSAN: data-race in unix_autobind / unix_autobind
    
    write to 0xffff888034a9fb88 of 4 bytes by task 4468 on cpu 0:
     __unix_set_addr_hash net/unix/af_unix.c:331 [inline]
     unix_autobind+0x47a/0x7d0 net/unix/af_unix.c:1185
     unix_dgram_connect+0x7e3/0x890 net/unix/af_unix.c:1373
     __sys_connect_file+0xd7/0xe0 net/socket.c:2048
     __sys_connect+0x114/0x140 net/socket.c:2065
     __do_sys_connect net/socket.c:2075 [inline]
     __se_sys_connect net/socket.c:2072 [inline]
     __x64_sys_connect+0x40/0x50 net/socket.c:2072
     do_syscall_x64 arch/x86/entry/common.c:52 [inline]
     do_syscall_64+0x4f/0x110 arch/x86/entry/common.c:83
     entry_SYSCALL_64_after_hwframe+0x46/0x4e
    
    read to 0xffff888034a9fb88 of 4 bytes by task 4465 on cpu 1:
     unix_autobind+0x28/0x7d0 net/unix/af_unix.c:1134
     unix_dgram_connect+0x7e3/0x890 net/unix/af_unix.c:1373
     __sys_connect_file+0xd7/0xe0 net/socket.c:2048
     __sys_connect+0x114/0x140 net/socket.c:2065
     __do_sys_connect net/socket.c:2075 [inline]
     __se_sys_connect net/socket.c:2072 [inline]
     __x64_sys_connect+0x40/0x50 net/socket.c:2072
     do_syscall_x64 arch/x86/entry/common.c:52 [inline]
     do_syscall_64+0x4f/0x110 arch/x86/entry/common.c:83
     entry_SYSCALL_64_after_hwframe+0x46/0x4e
    
    value changed: 0x000000e4 -> 0x000001e3
    
    Reported by Kernel Concurrency Sanitizer on:
    CPU: 1 PID: 4465 Comm: syz-executor.0 Not tainted 6.8.0-12822-gcd51db110a7e #12
    Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014
    
    Fixes: afd20b92 ("af_unix: Replace the big lock with small locks.")
    Reported-by: default avatarsyzkaller <syzkaller@googlegroups.com>
    Signed-off-by: default avatarKuniyuki Iwashima <kuniyu@amazon.com>
    Link: https://lore.kernel.org/r/20240522154218.78088-1-kuniyu@amazon.comSigned-off-by: default avatarPaolo Abeni <pabeni@redhat.com>
    51d1b25a
af_unix.c 86.6 KB