Skip to content

Commit ac92f23

Browse files
q2vengregkh
authored andcommitted
af_unix: Fix data-races around user->unix_inflight.
[ Upstream commit 0bc36c0 ] user->unix_inflight is changed under spin_lock(unix_gc_lock), but too_many_unix_fds() reads it locklessly. Let's annotate the write/read accesses to user->unix_inflight. BUG: KCSAN: data-race in unix_attach_fds / unix_inflight write to 0xffffffff8546f2d0 of 8 bytes by task 44798 on cpu 1: unix_inflight+0x157/0x180 net/unix/scm.c:66 unix_attach_fds+0x147/0x1e0 net/unix/scm.c:123 unix_scm_to_skb net/unix/af_unix.c:1827 [inline] unix_dgram_sendmsg+0x46a/0x14f0 net/unix/af_unix.c:1950 unix_seqpacket_sendmsg net/unix/af_unix.c:2308 [inline] unix_seqpacket_sendmsg+0xba/0x130 net/unix/af_unix.c:2292 sock_sendmsg_nosec net/socket.c:725 [inline] sock_sendmsg+0x148/0x160 net/socket.c:748 ____sys_sendmsg+0x4e4/0x610 net/socket.c:2494 ___sys_sendmsg+0xc6/0x140 net/socket.c:2548 __sys_sendmsg+0x94/0x140 net/socket.c:2577 __do_sys_sendmsg net/socket.c:2586 [inline] __se_sys_sendmsg net/socket.c:2584 [inline] __x64_sys_sendmsg+0x45/0x50 net/socket.c:2584 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x6e/0xd8 read to 0xffffffff8546f2d0 of 8 bytes by task 44814 on cpu 0: too_many_unix_fds net/unix/scm.c:101 [inline] unix_attach_fds+0x54/0x1e0 net/unix/scm.c:110 unix_scm_to_skb net/unix/af_unix.c:1827 [inline] unix_dgram_sendmsg+0x46a/0x14f0 net/unix/af_unix.c:1950 unix_seqpacket_sendmsg net/unix/af_unix.c:2308 [inline] unix_seqpacket_sendmsg+0xba/0x130 net/unix/af_unix.c:2292 sock_sendmsg_nosec net/socket.c:725 [inline] sock_sendmsg+0x148/0x160 net/socket.c:748 ____sys_sendmsg+0x4e4/0x610 net/socket.c:2494 ___sys_sendmsg+0xc6/0x140 net/socket.c:2548 __sys_sendmsg+0x94/0x140 net/socket.c:2577 __do_sys_sendmsg net/socket.c:2586 [inline] __se_sys_sendmsg net/socket.c:2584 [inline] __x64_sys_sendmsg+0x45/0x50 net/socket.c:2584 do_syscall_x64 arch/x86/entry/common.c:50 [inline] do_syscall_64+0x3b/0x90 arch/x86/entry/common.c:80 entry_SYSCALL_64_after_hwframe+0x6e/0xd8 value changed: 0x000000000000000c -> 0x000000000000000d Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 44814 Comm: systemd-coredum Not tainted 6.4.0-11989-g6843306689af #6 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS rel-1.16.0-0-gd239552ce722-prebuilt.qemu.org 04/01/2014 Fixes: 712f4aa ("unix: properly account for FDs passed over unix sockets") Reported-by: syzkaller <[email protected]> Signed-off-by: Kuniyuki Iwashima <[email protected]> Acked-by: Willy Tarreau <[email protected]> Reviewed-by: Eric Dumazet <[email protected]> Signed-off-by: David S. Miller <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 51bd119 commit ac92f23

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

net/unix/scm.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ void unix_inflight(struct user_struct *user, struct file *fp)
6363
/* Paired with READ_ONCE() in wait_for_unix_gc() */
6464
WRITE_ONCE(unix_tot_inflight, unix_tot_inflight + 1);
6565
}
66-
user->unix_inflight++;
66+
WRITE_ONCE(user->unix_inflight, user->unix_inflight + 1);
6767
spin_unlock(&unix_gc_lock);
6868
}
6969

@@ -84,7 +84,7 @@ void unix_notinflight(struct user_struct *user, struct file *fp)
8484
/* Paired with READ_ONCE() in wait_for_unix_gc() */
8585
WRITE_ONCE(unix_tot_inflight, unix_tot_inflight - 1);
8686
}
87-
user->unix_inflight--;
87+
WRITE_ONCE(user->unix_inflight, user->unix_inflight - 1);
8888
spin_unlock(&unix_gc_lock);
8989
}
9090

@@ -98,7 +98,7 @@ static inline bool too_many_unix_fds(struct task_struct *p)
9898
{
9999
struct user_struct *user = current_user();
100100

101-
if (unlikely(user->unix_inflight > task_rlimit(p, RLIMIT_NOFILE)))
101+
if (unlikely(READ_ONCE(user->unix_inflight) > task_rlimit(p, RLIMIT_NOFILE)))
102102
return !capable(CAP_SYS_RESOURCE) && !capable(CAP_SYS_ADMIN);
103103
return false;
104104
}

0 commit comments

Comments
 (0)