netlink: annotate data races around nlk->portid
[ Upstream commit c1bb9484e3b05166880da8574504156ccbd0549e ]
syzbot reminds us netlink_getname() runs locklessly [1]
This first patch annotates the race against nlk->portid.
Following patches take care of the remaining races.
[1]
BUG: KCSAN: data-race in netlink_getname / netlink_insert
write to 0xffff88814176d310 of 4 bytes by task 2315 on cpu 1:
netlink_insert+0xf1/0x9a0 net/netlink/af_netlink.c:583
netlink_autobind+0xae/0x180 net/netlink/af_netlink.c:856
netlink_sendmsg+0x444/0x760 net/netlink/af_netlink.c:1895
sock_sendmsg_nosec net/socket.c:714 [inline]
sock_sendmsg net/socket.c:734 [inline]
____sys_sendmsg+0x38f/0x500 net/socket.c:2476
___sys_sendmsg net/socket.c:2530 [inline]
__sys_sendmsg+0x19a/0x230 net/socket.c:2559
__do_sys_sendmsg net/socket.c:2568 [inline]
__se_sys_sendmsg net/socket.c:2566 [inline]
__x64_sys_sendmsg+0x42/0x50 net/socket.c:2566
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x2b/0x70 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
read to 0xffff88814176d310 of 4 bytes by task 2316 on cpu 0:
netlink_getname+0xcd/0x1a0 net/netlink/af_netlink.c:1144
__sys_getsockname+0x11d/0x1b0 net/socket.c:2026
__do_sys_getsockname net/socket.c:2041 [inline]
__se_sys_getsockname net/socket.c:2038 [inline]
__x64_sys_getsockname+0x3e/0x50 net/socket.c:2038
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x2b/0x70 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd
value changed: 0x00000000 -> 0xc9a49780
Reported by Kernel Concurrency Sanitizer on:
CPU: 0 PID: 2316 Comm: syz-executor.2 Not tainted 6.2.0-rc3-syzkaller-00030-ge8f60cd7db24-dirty #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 10/26/2022
Fixes: 1da177e4c3
("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reported-by: syzbot <syzkaller@googlegroups.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
cfdd81ae47
commit
ea11a52f55
@ -569,7 +569,9 @@ static int netlink_insert(struct sock *sk, u32 portid)
|
|||||||
if (nlk_sk(sk)->bound)
|
if (nlk_sk(sk)->bound)
|
||||||
goto err;
|
goto err;
|
||||||
|
|
||||||
nlk_sk(sk)->portid = portid;
|
/* portid can be read locklessly from netlink_getname(). */
|
||||||
|
WRITE_ONCE(nlk_sk(sk)->portid, portid);
|
||||||
|
|
||||||
sock_hold(sk);
|
sock_hold(sk);
|
||||||
|
|
||||||
err = __netlink_insert(table, sk);
|
err = __netlink_insert(table, sk);
|
||||||
@ -1123,7 +1125,8 @@ static int netlink_getname(struct socket *sock, struct sockaddr *addr,
|
|||||||
nladdr->nl_pid = nlk->dst_portid;
|
nladdr->nl_pid = nlk->dst_portid;
|
||||||
nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
|
nladdr->nl_groups = netlink_group_mask(nlk->dst_group);
|
||||||
} else {
|
} else {
|
||||||
nladdr->nl_pid = nlk->portid;
|
/* Paired with WRITE_ONCE() in netlink_insert() */
|
||||||
|
nladdr->nl_pid = READ_ONCE(nlk->portid);
|
||||||
netlink_lock_table();
|
netlink_lock_table();
|
||||||
nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;
|
nladdr->nl_groups = nlk->groups ? nlk->groups[0] : 0;
|
||||||
netlink_unlock_table();
|
netlink_unlock_table();
|
||||||
|
Loading…
Reference in New Issue
Block a user