Skip to content

Commit f355ed2

Browse files
q2venSasha Levin
authored andcommitted
af_unix: Annotate data-races around sk->sk_state in UNIX_DIAG.
[ Upstream commit 0aa3be7 ] While dumping AF_UNIX sockets via UNIX_DIAG, sk->sk_state is read locklessly. Let's use READ_ONCE() there. Note that the result could be inconsistent if the socket is dumped during the state change. This is common for other SOCK_DIAG and similar interfaces. Fixes: c9da99e ("unix_diag: Fixup RQLEN extension report") Fixes: 2aac7a2 ("unix_diag: Pending connections IDs NLA") Fixes: 45a96b9 ("unix_diag: Dumping all sockets core") Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent 073b4d2 commit f355ed2

File tree

1 file changed

+4
-4
lines changed

1 file changed

+4
-4
lines changed

net/unix/diag.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ static int sk_diag_dump_icons(struct sock *sk, struct sk_buff *nlskb)
6565
u32 *buf;
6666
int i;
6767

68-
if (sk->sk_state == TCP_LISTEN) {
68+
if (READ_ONCE(sk->sk_state) == TCP_LISTEN) {
6969
spin_lock(&sk->sk_receive_queue.lock);
7070

7171
attr = nla_reserve(nlskb, UNIX_DIAG_ICONS,
@@ -103,7 +103,7 @@ static int sk_diag_show_rqlen(struct sock *sk, struct sk_buff *nlskb)
103103
{
104104
struct unix_diag_rqlen rql;
105105

106-
if (sk->sk_state == TCP_LISTEN) {
106+
if (READ_ONCE(sk->sk_state) == TCP_LISTEN) {
107107
rql.udiag_rqueue = sk->sk_receive_queue.qlen;
108108
rql.udiag_wqueue = sk->sk_max_ack_backlog;
109109
} else {
@@ -136,7 +136,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_r
136136
rep = nlmsg_data(nlh);
137137
rep->udiag_family = AF_UNIX;
138138
rep->udiag_type = sk->sk_type;
139-
rep->udiag_state = sk->sk_state;
139+
rep->udiag_state = READ_ONCE(sk->sk_state);
140140
rep->pad = 0;
141141
rep->udiag_ino = sk_ino;
142142
sock_diag_save_cookie(sk, rep->udiag_cookie);
@@ -215,7 +215,7 @@ static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
215215
sk_for_each(sk, &net->unx.table.buckets[slot]) {
216216
if (num < s_num)
217217
goto next;
218-
if (!(req->udiag_states & (1 << sk->sk_state)))
218+
if (!(req->udiag_states & (1 << READ_ONCE(sk->sk_state))))
219219
goto next;
220220
if (sk_diag_dump(sk, skb, req, sk_user_ns(skb->sk),
221221
NETLINK_CB(cb->skb).portid,

0 commit comments

Comments
 (0)