[PATCH 5.15 012/203] netlink: annotate accesses to nlk->cb_running

1 view
Skip to first unread message

Greg Kroah-Hartman

unread,
May 22, 2023, 3:12:48 PM5/22/23
to sta...@vger.kernel.org, Greg Kroah-Hartman, pat...@lists.linux.dev, syzbot, Eric Dumazet, David S. Miller, Sasha Levin
From: Eric Dumazet <edum...@google.com>

[ Upstream commit a939d14919b799e6fff8a9c80296ca229ba2f8a4 ]

Both netlink_recvmsg() and netlink_native_seq_show() read
nlk->cb_running locklessly. Use READ_ONCE() there.

Add corresponding WRITE_ONCE() to netlink_dump() and
__netlink_dump_start()

syzbot reported:
BUG: KCSAN: data-race in __netlink_dump_start / netlink_recvmsg

write to 0xffff88813ea4db59 of 1 bytes by task 28219 on cpu 0:
__netlink_dump_start+0x3af/0x4d0 net/netlink/af_netlink.c:2399
netlink_dump_start include/linux/netlink.h:308 [inline]
rtnetlink_rcv_msg+0x70f/0x8c0 net/core/rtnetlink.c:6130
netlink_rcv_skb+0x126/0x220 net/netlink/af_netlink.c:2577
rtnetlink_rcv+0x1c/0x20 net/core/rtnetlink.c:6192
netlink_unicast_kernel net/netlink/af_netlink.c:1339 [inline]
netlink_unicast+0x56f/0x640 net/netlink/af_netlink.c:1365
netlink_sendmsg+0x665/0x770 net/netlink/af_netlink.c:1942
sock_sendmsg_nosec net/socket.c:724 [inline]
sock_sendmsg net/socket.c:747 [inline]
sock_write_iter+0x1aa/0x230 net/socket.c:1138
call_write_iter include/linux/fs.h:1851 [inline]
new_sync_write fs/read_write.c:491 [inline]
vfs_write+0x463/0x760 fs/read_write.c:584
ksys_write+0xeb/0x1a0 fs/read_write.c:637
__do_sys_write fs/read_write.c:649 [inline]
__se_sys_write fs/read_write.c:646 [inline]
__x64_sys_write+0x42/0x50 fs/read_write.c:646
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd

read to 0xffff88813ea4db59 of 1 bytes by task 28222 on cpu 1:
netlink_recvmsg+0x3b4/0x730 net/netlink/af_netlink.c:2022
sock_recvmsg_nosec+0x4c/0x80 net/socket.c:1017
____sys_recvmsg+0x2db/0x310 net/socket.c:2718
___sys_recvmsg net/socket.c:2762 [inline]
do_recvmmsg+0x2e5/0x710 net/socket.c:2856
__sys_recvmmsg net/socket.c:2935 [inline]
__do_sys_recvmmsg net/socket.c:2958 [inline]
__se_sys_recvmmsg net/socket.c:2951 [inline]
__x64_sys_recvmmsg+0xe2/0x160 net/socket.c:2951
do_syscall_x64 arch/x86/entry/common.c:50 [inline]
do_syscall_64+0x41/0xc0 arch/x86/entry/common.c:80
entry_SYSCALL_64_after_hwframe+0x63/0xcd

value changed: 0x00 -> 0x01

Fixes: 16b304f3404f ("netlink: Eliminate kmalloc in netlink dump operation.")
Reported-by: syzbot <syzk...@googlegroups.com>
Signed-off-by: Eric Dumazet <edum...@google.com>
Signed-off-by: David S. Miller <da...@davemloft.net>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
net/netlink/af_netlink.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 84a7a29be49d8..998c736d3ae8b 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -2000,7 +2000,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,

skb_free_datagram(sk, skb);

- if (nlk->cb_running &&
+ if (READ_ONCE(nlk->cb_running) &&
atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
ret = netlink_dump(sk);
if (ret) {
@@ -2312,7 +2312,7 @@ static int netlink_dump(struct sock *sk)
if (cb->done)
cb->done(cb);

- nlk->cb_running = false;
+ WRITE_ONCE(nlk->cb_running, false);
module = cb->module;
skb = cb->skb;
mutex_unlock(nlk->cb_mutex);
@@ -2375,7 +2375,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
goto error_put;
}

- nlk->cb_running = true;
+ WRITE_ONCE(nlk->cb_running, true);
nlk->dump_done_errno = INT_MAX;

mutex_unlock(nlk->cb_mutex);
@@ -2661,7 +2661,7 @@ static int netlink_native_seq_show(struct seq_file *seq, void *v)
nlk->groups ? (u32)nlk->groups[0] : 0,
sk_rmem_alloc_get(s),
sk_wmem_alloc_get(s),
- nlk->cb_running,
+ READ_ONCE(nlk->cb_running),
refcount_read(&s->sk_refcnt),
atomic_read(&s->sk_drops),
sock_i_ino(s)
--
2.39.2



Greg Kroah-Hartman

unread,
May 22, 2023, 3:22:30 PM5/22/23
to sta...@vger.kernel.org, Greg Kroah-Hartman, pat...@lists.linux.dev, syzbot, Eric Dumazet, David S. Miller, Sasha Levin
index b1dcc536521b6..d1b19618890b7 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1979,7 +1979,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,

skb_free_datagram(sk, skb);

- if (nlk->cb_running &&
+ if (READ_ONCE(nlk->cb_running) &&
atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
ret = netlink_dump(sk);
if (ret) {
@@ -2293,7 +2293,7 @@ static int netlink_dump(struct sock *sk)
if (cb->done)
cb->done(cb);

- nlk->cb_running = false;
+ WRITE_ONCE(nlk->cb_running, false);
module = cb->module;
skb = cb->skb;
mutex_unlock(nlk->cb_mutex);
@@ -2356,7 +2356,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
goto error_put;
}

- nlk->cb_running = true;
+ WRITE_ONCE(nlk->cb_running, true);
nlk->dump_done_errno = INT_MAX;

mutex_unlock(nlk->cb_mutex);
@@ -2681,7 +2681,7 @@ static int netlink_native_seq_show(struct seq_file *seq, void *v)

Greg Kroah-Hartman

unread,
May 22, 2023, 3:37:28 PM5/22/23
to sta...@vger.kernel.org, Greg Kroah-Hartman, pat...@lists.linux.dev, syzbot, Eric Dumazet, David S. Miller, Sasha Levin
index 9b6eb28e6e94f..45d47b39de225 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1990,7 +1990,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,

skb_free_datagram(sk, skb);

- if (nlk->cb_running &&
+ if (READ_ONCE(nlk->cb_running) &&
atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
ret = netlink_dump(sk);
if (ret) {
@@ -2304,7 +2304,7 @@ static int netlink_dump(struct sock *sk)
if (cb->done)
cb->done(cb);

- nlk->cb_running = false;
+ WRITE_ONCE(nlk->cb_running, false);
module = cb->module;
skb = cb->skb;
mutex_unlock(nlk->cb_mutex);
@@ -2367,7 +2367,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
goto error_put;
}

- nlk->cb_running = true;
+ WRITE_ONCE(nlk->cb_running, true);
nlk->dump_done_errno = INT_MAX;

mutex_unlock(nlk->cb_mutex);
@@ -2705,7 +2705,7 @@ static int netlink_native_seq_show(struct seq_file *seq, void *v)

Greg Kroah-Hartman

unread,
May 28, 2023, 3:13:08 PM5/28/23
to sta...@vger.kernel.org, Greg Kroah-Hartman, pat...@lists.linux.dev, syzbot, Eric Dumazet, David S. Miller, Sasha Levin
index d7b0a7aa29a83..4b40edb51b9e5 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1977,7 +1977,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,

skb_free_datagram(sk, skb);

- if (nlk->cb_running &&
+ if (READ_ONCE(nlk->cb_running) &&
atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
ret = netlink_dump(sk);
if (ret) {
@@ -2259,7 +2259,7 @@ static int netlink_dump(struct sock *sk)
if (cb->done)
cb->done(cb);

- nlk->cb_running = false;
+ WRITE_ONCE(nlk->cb_running, false);
module = cb->module;
skb = cb->skb;
mutex_unlock(nlk->cb_mutex);
@@ -2320,7 +2320,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
goto error_put;
}

- nlk->cb_running = true;
+ WRITE_ONCE(nlk->cb_running, true);
nlk->dump_done_errno = INT_MAX;

mutex_unlock(nlk->cb_mutex);
@@ -2633,7 +2633,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)

Greg Kroah-Hartman

unread,
May 28, 2023, 3:16:54 PM5/28/23
to sta...@vger.kernel.org, Greg Kroah-Hartman, pat...@lists.linux.dev, syzbot, Eric Dumazet, David S. Miller, Sasha Levin
index 6867158656b86..c73784b7b67dc 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1983,7 +1983,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,

skb_free_datagram(sk, skb);

- if (nlk->cb_running &&
+ if (READ_ONCE(nlk->cb_running) &&
atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
ret = netlink_dump(sk);
if (ret) {
@@ -2265,7 +2265,7 @@ static int netlink_dump(struct sock *sk)
if (cb->done)
cb->done(cb);

- nlk->cb_running = false;
+ WRITE_ONCE(nlk->cb_running, false);
module = cb->module;
skb = cb->skb;
mutex_unlock(nlk->cb_mutex);
@@ -2325,7 +2325,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
goto error_put;
}

- nlk->cb_running = true;
+ WRITE_ONCE(nlk->cb_running, true);
nlk->dump_done_errno = INT_MAX;

mutex_unlock(nlk->cb_mutex);
@@ -2631,7 +2631,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)

Greg Kroah-Hartman

unread,
May 28, 2023, 3:23:05 PM5/28/23
to sta...@vger.kernel.org, Greg Kroah-Hartman, pat...@lists.linux.dev, syzbot, Eric Dumazet, David S. Miller, Sasha Levin
index 00f040fb46b9c..31a3a562854fc 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1991,7 +1991,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,

skb_free_datagram(sk, skb);

- if (nlk->cb_running &&
+ if (READ_ONCE(nlk->cb_running) &&
atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
ret = netlink_dump(sk);
if (ret) {
@@ -2284,7 +2284,7 @@ static int netlink_dump(struct sock *sk)
if (cb->done)
cb->done(cb);

- nlk->cb_running = false;
+ WRITE_ONCE(nlk->cb_running, false);
module = cb->module;
skb = cb->skb;
mutex_unlock(nlk->cb_mutex);
@@ -2347,7 +2347,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
goto error_put;
}

- nlk->cb_running = true;
+ WRITE_ONCE(nlk->cb_running, true);
nlk->dump_done_errno = INT_MAX;

mutex_unlock(nlk->cb_mutex);
@@ -2636,7 +2636,7 @@ static int netlink_seq_show(struct seq_file *seq, void *v)

Greg Kroah-Hartman

unread,
May 28, 2023, 3:39:54 PM5/28/23
to sta...@vger.kernel.org, Greg Kroah-Hartman, pat...@lists.linux.dev, syzbot, Eric Dumazet, David S. Miller, Sasha Levin
index eedb16517f16a..651f8ca912af0 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1992,7 +1992,7 @@ static int netlink_recvmsg(struct socket *sock, struct msghdr *msg, size_t len,

skb_free_datagram(sk, skb);

- if (nlk->cb_running &&
+ if (READ_ONCE(nlk->cb_running) &&
atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf / 2) {
ret = netlink_dump(sk);
if (ret) {
@@ -2304,7 +2304,7 @@ static int netlink_dump(struct sock *sk)
if (cb->done)
cb->done(cb);

- nlk->cb_running = false;
+ WRITE_ONCE(nlk->cb_running, false);
module = cb->module;
skb = cb->skb;
mutex_unlock(nlk->cb_mutex);
@@ -2367,7 +2367,7 @@ int __netlink_dump_start(struct sock *ssk, struct sk_buff *skb,
goto error_put;
}

- nlk->cb_running = true;
+ WRITE_ONCE(nlk->cb_running, true);
nlk->dump_done_errno = INT_MAX;

mutex_unlock(nlk->cb_mutex);
@@ -2653,7 +2653,7 @@ static int netlink_native_seq_show(struct seq_file *seq, void *v)
Reply all
Reply to author
Forward
0 new messages