Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

inet: annotate data-races around isk->inet_num

UDP/TCP lookups are using RCU, thus isk->inet_num accesses
should use READ_ONCE() and WRITE_ONCE() where needed.

Fixes: 3ab5aee7fe84 ("net: Convert TCP & DCCP hash tables to use RCU / hlist_nulls")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260225203545.1512417-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Eric Dumazet and committed by
Jakub Kicinski
29252397 62413a9c

+10 -9
+1 -1
include/net/inet6_hashtables.h
··· 175 175 { 176 176 if (!net_eq(sock_net(sk), net) || 177 177 sk->sk_family != AF_INET6 || 178 - sk->sk_portpair != ports || 178 + READ_ONCE(sk->sk_portpair) != ports || 179 179 !ipv6_addr_equal(&sk->sk_v6_daddr, saddr) || 180 180 !ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr)) 181 181 return false;
+1 -1
include/net/inet_hashtables.h
··· 345 345 int dif, int sdif) 346 346 { 347 347 if (!net_eq(sock_net(sk), net) || 348 - sk->sk_portpair != ports || 348 + READ_ONCE(sk->sk_portpair) != ports || 349 349 sk->sk_addrpair != cookie) 350 350 return false; 351 351
+1 -1
include/net/ip.h
··· 101 101 102 102 ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if); 103 103 ipcm->addr = inet->inet_saddr; 104 - ipcm->protocol = inet->inet_num; 104 + ipcm->protocol = READ_ONCE(inet->inet_num); 105 105 } 106 106 107 107 #define IPCB(skb) ((struct inet_skb_parm*)((skb)->cb))
+4 -4
net/ipv4/inet_hashtables.c
··· 200 200 void inet_bind_hash(struct sock *sk, struct inet_bind_bucket *tb, 201 201 struct inet_bind2_bucket *tb2, unsigned short port) 202 202 { 203 - inet_sk(sk)->inet_num = port; 203 + WRITE_ONCE(inet_sk(sk)->inet_num, port); 204 204 inet_csk(sk)->icsk_bind_hash = tb; 205 205 inet_csk(sk)->icsk_bind2_hash = tb2; 206 206 sk_add_bind_node(sk, &tb2->owners); ··· 224 224 spin_lock(&head->lock); 225 225 tb = inet_csk(sk)->icsk_bind_hash; 226 226 inet_csk(sk)->icsk_bind_hash = NULL; 227 - inet_sk(sk)->inet_num = 0; 227 + WRITE_ONCE(inet_sk(sk)->inet_num, 0); 228 228 sk->sk_userlocks &= ~SOCK_CONNECT_BIND; 229 229 230 230 spin_lock(&head2->lock); ··· 352 352 { 353 353 int score = -1; 354 354 355 - if (net_eq(sock_net(sk), net) && sk->sk_num == hnum && 355 + if (net_eq(sock_net(sk), net) && READ_ONCE(sk->sk_num) == hnum && 356 356 !ipv6_only_sock(sk)) { 357 357 if (sk->sk_rcv_saddr != daddr) 358 358 return -1; ··· 1206 1206 1207 1207 sk->sk_hash = 0; 1208 1208 inet_sk(sk)->inet_sport = 0; 1209 - inet_sk(sk)->inet_num = 0; 1209 + WRITE_ONCE(inet_sk(sk)->inet_num, 0); 1210 1210 1211 1211 if (tw) 1212 1212 inet_twsk_bind_unhash(tw, hinfo);
+1 -1
net/ipv4/tcp_diag.c
··· 509 509 if (r->sdiag_family != AF_UNSPEC && 510 510 sk->sk_family != r->sdiag_family) 511 511 goto next_normal; 512 - if (r->id.idiag_sport != htons(sk->sk_num) && 512 + if (r->id.idiag_sport != htons(READ_ONCE(sk->sk_num)) && 513 513 r->id.idiag_sport) 514 514 goto next_normal; 515 515 if (r->id.idiag_dport != sk->sk_dport &&
+2 -1
net/ipv6/inet6_hashtables.c
··· 95 95 { 96 96 int score = -1; 97 97 98 - if (net_eq(sock_net(sk), net) && inet_sk(sk)->inet_num == hnum && 98 + if (net_eq(sock_net(sk), net) && 99 + READ_ONCE(inet_sk(sk)->inet_num) == hnum && 99 100 sk->sk_family == PF_INET6) { 100 101 if (!ipv6_addr_equal(&sk->sk_v6_rcv_saddr, daddr)) 101 102 return -1;