Skip to content

Commit 37e3cec

Browse files
committed
Merge branch 'net-data-races'
Eric Dumazet says: ==================== net: annotate data-races This series was inspired by a syzbot/KCSAN report. This will later also permit some optimizations, like not having to lock the socket while reading/writing some of its fields. ==================== Signed-off-by: David S. Miller <[email protected]>
2 parents 7938cd1 + 8bf43be commit 37e3cec

File tree

27 files changed

+94
-80
lines changed

27 files changed

+94
-80
lines changed

include/net/inet_sock.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -107,11 +107,12 @@ static inline struct inet_request_sock *inet_rsk(const struct request_sock *sk)
107107

108108
static inline u32 inet_request_mark(const struct sock *sk, struct sk_buff *skb)
109109
{
110-
if (!sk->sk_mark &&
111-
READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept))
110+
u32 mark = READ_ONCE(sk->sk_mark);
111+
112+
if (!mark && READ_ONCE(sock_net(sk)->ipv4.sysctl_tcp_fwmark_accept))
112113
return skb->mark;
113114

114-
return sk->sk_mark;
115+
return mark;
115116
}
116117

117118
static inline int inet_request_bound_dev_if(const struct sock *sk,

include/net/ip.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ static inline void ipcm_init_sk(struct ipcm_cookie *ipcm,
9393
{
9494
ipcm_init(ipcm);
9595

96-
ipcm->sockc.mark = inet->sk.sk_mark;
96+
ipcm->sockc.mark = READ_ONCE(inet->sk.sk_mark);
9797
ipcm->sockc.tsflags = inet->sk.sk_tsflags;
9898
ipcm->oif = READ_ONCE(inet->sk.sk_bound_dev_if);
9999
ipcm->addr = inet->inet_saddr;

include/net/route.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,7 @@ static inline struct rtable *ip_route_output_ports(struct net *net, struct flowi
168168
__be16 dport, __be16 sport,
169169
__u8 proto, __u8 tos, int oif)
170170
{
171-
flowi4_init_output(fl4, oif, sk ? sk->sk_mark : 0, tos,
171+
flowi4_init_output(fl4, oif, sk ? READ_ONCE(sk->sk_mark) : 0, tos,
172172
RT_SCOPE_UNIVERSE, proto,
173173
sk ? inet_sk_flowi_flags(sk) : 0,
174174
daddr, saddr, dport, sport, sock_net_uid(net, sk));
@@ -301,7 +301,7 @@ static inline void ip_route_connect_init(struct flowi4 *fl4, __be32 dst,
301301
if (inet_sk(sk)->transparent)
302302
flow_flags |= FLOWI_FLAG_ANYSRC;
303303

304-
flowi4_init_output(fl4, oif, sk->sk_mark, ip_sock_rt_tos(sk),
304+
flowi4_init_output(fl4, oif, READ_ONCE(sk->sk_mark), ip_sock_rt_tos(sk),
305305
ip_sock_rt_scope(sk), protocol, flow_flags, dst,
306306
src, dport, sport, sk->sk_uid);
307307
}

net/can/raw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -865,7 +865,7 @@ static int raw_sendmsg(struct socket *sock, struct msghdr *msg, size_t size)
865865

866866
skb->dev = dev;
867867
skb->priority = sk->sk_priority;
868-
skb->mark = sk->sk_mark;
868+
skb->mark = READ_ONCE(sk->sk_mark);
869869
skb->tstamp = sockc.transmit_time;
870870

871871
skb_setup_tx_timestamp(skb, sockc.tsflags);

net/core/sock.c

Lines changed: 40 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -429,6 +429,7 @@ static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,
429429
{
430430
struct __kernel_sock_timeval tv;
431431
int err = sock_copy_user_timeval(&tv, optval, optlen, old_timeval);
432+
long val;
432433

433434
if (err)
434435
return err;
@@ -439,19 +440,20 @@ static int sock_set_timeout(long *timeo_p, sockptr_t optval, int optlen,
439440
if (tv.tv_sec < 0) {
440441
static int warned __read_mostly;
441442

442-
*timeo_p = 0;
443+
WRITE_ONCE(*timeo_p, 0);
443444
if (warned < 10 && net_ratelimit()) {
444445
warned++;
445446
pr_info("%s: `%s' (pid %d) tries to set negative timeout\n",
446447
__func__, current->comm, task_pid_nr(current));
447448
}
448449
return 0;
449450
}
450-
*timeo_p = MAX_SCHEDULE_TIMEOUT;
451-
if (tv.tv_sec == 0 && tv.tv_usec == 0)
452-
return 0;
453-
if (tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1))
454-
*timeo_p = tv.tv_sec * HZ + DIV_ROUND_UP((unsigned long)tv.tv_usec, USEC_PER_SEC / HZ);
451+
val = MAX_SCHEDULE_TIMEOUT;
452+
if ((tv.tv_sec || tv.tv_usec) &&
453+
(tv.tv_sec < (MAX_SCHEDULE_TIMEOUT / HZ - 1)))
454+
val = tv.tv_sec * HZ + DIV_ROUND_UP((unsigned long)tv.tv_usec,
455+
USEC_PER_SEC / HZ);
456+
WRITE_ONCE(*timeo_p, val);
455457
return 0;
456458
}
457459

@@ -804,7 +806,7 @@ EXPORT_SYMBOL(sock_no_linger);
804806
void sock_set_priority(struct sock *sk, u32 priority)
805807
{
806808
lock_sock(sk);
807-
sk->sk_priority = priority;
809+
WRITE_ONCE(sk->sk_priority, priority);
808810
release_sock(sk);
809811
}
810812
EXPORT_SYMBOL(sock_set_priority);
@@ -813,9 +815,9 @@ void sock_set_sndtimeo(struct sock *sk, s64 secs)
813815
{
814816
lock_sock(sk);
815817
if (secs && secs < MAX_SCHEDULE_TIMEOUT / HZ - 1)
816-
sk->sk_sndtimeo = secs * HZ;
818+
WRITE_ONCE(sk->sk_sndtimeo, secs * HZ);
817819
else
818-
sk->sk_sndtimeo = MAX_SCHEDULE_TIMEOUT;
820+
WRITE_ONCE(sk->sk_sndtimeo, MAX_SCHEDULE_TIMEOUT);
819821
release_sock(sk);
820822
}
821823
EXPORT_SYMBOL(sock_set_sndtimeo);
@@ -988,7 +990,7 @@ EXPORT_SYMBOL(sock_set_rcvbuf);
988990
static void __sock_set_mark(struct sock *sk, u32 val)
989991
{
990992
if (val != sk->sk_mark) {
991-
sk->sk_mark = val;
993+
WRITE_ONCE(sk->sk_mark, val);
992994
sk_dst_reset(sk);
993995
}
994996
}
@@ -1007,7 +1009,7 @@ static void sock_release_reserved_memory(struct sock *sk, int bytes)
10071009
bytes = round_down(bytes, PAGE_SIZE);
10081010

10091011
WARN_ON(bytes > sk->sk_reserved_mem);
1010-
sk->sk_reserved_mem -= bytes;
1012+
WRITE_ONCE(sk->sk_reserved_mem, sk->sk_reserved_mem - bytes);
10111013
sk_mem_reclaim(sk);
10121014
}
10131015

@@ -1044,7 +1046,8 @@ static int sock_reserve_memory(struct sock *sk, int bytes)
10441046
}
10451047
sk->sk_forward_alloc += pages << PAGE_SHIFT;
10461048

1047-
sk->sk_reserved_mem += pages << PAGE_SHIFT;
1049+
WRITE_ONCE(sk->sk_reserved_mem,
1050+
sk->sk_reserved_mem + (pages << PAGE_SHIFT));
10481051

10491052
return 0;
10501053
}
@@ -1213,7 +1216,7 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
12131216
if ((val >= 0 && val <= 6) ||
12141217
sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_RAW) ||
12151218
sockopt_ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN))
1216-
sk->sk_priority = val;
1219+
WRITE_ONCE(sk->sk_priority, val);
12171220
else
12181221
ret = -EPERM;
12191222
break;
@@ -1438,7 +1441,8 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
14381441
cmpxchg(&sk->sk_pacing_status,
14391442
SK_PACING_NONE,
14401443
SK_PACING_NEEDED);
1441-
sk->sk_max_pacing_rate = ulval;
1444+
/* Pairs with READ_ONCE() from sk_getsockopt() */
1445+
WRITE_ONCE(sk->sk_max_pacing_rate, ulval);
14421446
sk->sk_pacing_rate = min(sk->sk_pacing_rate, ulval);
14431447
break;
14441448
}
@@ -1533,7 +1537,9 @@ int sk_setsockopt(struct sock *sk, int level, int optname,
15331537
}
15341538
if ((u8)val == SOCK_TXREHASH_DEFAULT)
15351539
val = READ_ONCE(sock_net(sk)->core.sysctl_txrehash);
1536-
/* Paired with READ_ONCE() in tcp_rtx_synack() */
1540+
/* Paired with READ_ONCE() in tcp_rtx_synack()
1541+
* and sk_getsockopt().
1542+
*/
15371543
WRITE_ONCE(sk->sk_txrehash, (u8)val);
15381544
break;
15391545

@@ -1633,11 +1639,11 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
16331639
break;
16341640

16351641
case SO_SNDBUF:
1636-
v.val = sk->sk_sndbuf;
1642+
v.val = READ_ONCE(sk->sk_sndbuf);
16371643
break;
16381644

16391645
case SO_RCVBUF:
1640-
v.val = sk->sk_rcvbuf;
1646+
v.val = READ_ONCE(sk->sk_rcvbuf);
16411647
break;
16421648

16431649
case SO_REUSEADDR:
@@ -1679,7 +1685,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
16791685
break;
16801686

16811687
case SO_PRIORITY:
1682-
v.val = sk->sk_priority;
1688+
v.val = READ_ONCE(sk->sk_priority);
16831689
break;
16841690

16851691
case SO_LINGER:
@@ -1717,16 +1723,18 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
17171723

17181724
case SO_RCVTIMEO_OLD:
17191725
case SO_RCVTIMEO_NEW:
1720-
lv = sock_get_timeout(sk->sk_rcvtimeo, &v, SO_RCVTIMEO_OLD == optname);
1726+
lv = sock_get_timeout(READ_ONCE(sk->sk_rcvtimeo), &v,
1727+
SO_RCVTIMEO_OLD == optname);
17211728
break;
17221729

17231730
case SO_SNDTIMEO_OLD:
17241731
case SO_SNDTIMEO_NEW:
1725-
lv = sock_get_timeout(sk->sk_sndtimeo, &v, SO_SNDTIMEO_OLD == optname);
1732+
lv = sock_get_timeout(READ_ONCE(sk->sk_sndtimeo), &v,
1733+
SO_SNDTIMEO_OLD == optname);
17261734
break;
17271735

17281736
case SO_RCVLOWAT:
1729-
v.val = sk->sk_rcvlowat;
1737+
v.val = READ_ONCE(sk->sk_rcvlowat);
17301738
break;
17311739

17321740
case SO_SNDLOWAT:
@@ -1843,7 +1851,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
18431851
optval, optlen, len);
18441852

18451853
case SO_MARK:
1846-
v.val = sk->sk_mark;
1854+
v.val = READ_ONCE(sk->sk_mark);
18471855
break;
18481856

18491857
case SO_RCVMARK:
@@ -1862,7 +1870,7 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
18621870
if (!sock->ops->set_peek_off)
18631871
return -EOPNOTSUPP;
18641872

1865-
v.val = sk->sk_peek_off;
1873+
v.val = READ_ONCE(sk->sk_peek_off);
18661874
break;
18671875
case SO_NOFCS:
18681876
v.val = sock_flag(sk, SOCK_NOFCS);
@@ -1892,20 +1900,22 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
18921900

18931901
#ifdef CONFIG_NET_RX_BUSY_POLL
18941902
case SO_BUSY_POLL:
1895-
v.val = sk->sk_ll_usec;
1903+
v.val = READ_ONCE(sk->sk_ll_usec);
18961904
break;
18971905
case SO_PREFER_BUSY_POLL:
18981906
v.val = READ_ONCE(sk->sk_prefer_busy_poll);
18991907
break;
19001908
#endif
19011909

19021910
case SO_MAX_PACING_RATE:
1911+
/* The READ_ONCE() pair with the WRITE_ONCE() in sk_setsockopt() */
19031912
if (sizeof(v.ulval) != sizeof(v.val) && len >= sizeof(v.ulval)) {
19041913
lv = sizeof(v.ulval);
1905-
v.ulval = sk->sk_max_pacing_rate;
1914+
v.ulval = READ_ONCE(sk->sk_max_pacing_rate);
19061915
} else {
19071916
/* 32bit version */
1908-
v.val = min_t(unsigned long, sk->sk_max_pacing_rate, ~0U);
1917+
v.val = min_t(unsigned long, ~0U,
1918+
READ_ONCE(sk->sk_max_pacing_rate));
19091919
}
19101920
break;
19111921

@@ -1973,11 +1983,12 @@ int sk_getsockopt(struct sock *sk, int level, int optname,
19731983
break;
19741984

19751985
case SO_RESERVE_MEM:
1976-
v.val = sk->sk_reserved_mem;
1986+
v.val = READ_ONCE(sk->sk_reserved_mem);
19771987
break;
19781988

19791989
case SO_TXREHASH:
1980-
v.val = sk->sk_txrehash;
1990+
/* Paired with WRITE_ONCE() in sk_setsockopt() */
1991+
v.val = READ_ONCE(sk->sk_txrehash);
19811992
break;
19821993

19831994
default:
@@ -3168,7 +3179,7 @@ EXPORT_SYMBOL(__sk_mem_reclaim);
31683179

31693180
int sk_set_peek_off(struct sock *sk, int val)
31703181
{
3171-
sk->sk_peek_off = val;
3182+
WRITE_ONCE(sk->sk_peek_off, val);
31723183
return 0;
31733184
}
31743185
EXPORT_SYMBOL_GPL(sk_set_peek_off);

net/dccp/ipv6.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,8 @@ static int dccp_v6_send_response(const struct sock *sk, struct request_sock *req
238238
opt = ireq->ipv6_opt;
239239
if (!opt)
240240
opt = rcu_dereference(np->opt);
241-
err = ip6_xmit(sk, skb, &fl6, sk->sk_mark, opt, np->tclass,
242-
sk->sk_priority);
241+
err = ip6_xmit(sk, skb, &fl6, READ_ONCE(sk->sk_mark), opt,
242+
np->tclass, sk->sk_priority);
243243
rcu_read_unlock();
244244
err = net_xmit_eval(err);
245245
}

net/ipv4/inet_diag.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ int inet_diag_msg_attrs_fill(struct sock *sk, struct sk_buff *skb,
150150
}
151151
#endif
152152

153-
if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, sk->sk_mark))
153+
if (net_admin && nla_put_u32(skb, INET_DIAG_MARK, READ_ONCE(sk->sk_mark)))
154154
goto errout;
155155

156156
if (ext & (1 << (INET_DIAG_CLASS_ID - 1)) ||
@@ -799,7 +799,7 @@ int inet_diag_bc_sk(const struct nlattr *bc, struct sock *sk)
799799
entry.ifindex = sk->sk_bound_dev_if;
800800
entry.userlocks = sk_fullsock(sk) ? sk->sk_userlocks : 0;
801801
if (sk_fullsock(sk))
802-
entry.mark = sk->sk_mark;
802+
entry.mark = READ_ONCE(sk->sk_mark);
803803
else if (sk->sk_state == TCP_NEW_SYN_RECV)
804804
entry.mark = inet_rsk(inet_reqsk(sk))->ir_mark;
805805
else if (sk->sk_state == TCP_TIME_WAIT)

net/ipv4/ip_output.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -184,9 +184,9 @@ int ip_build_and_send_pkt(struct sk_buff *skb, const struct sock *sk,
184184
ip_options_build(skb, &opt->opt, daddr, rt);
185185
}
186186

187-
skb->priority = sk->sk_priority;
187+
skb->priority = READ_ONCE(sk->sk_priority);
188188
if (!skb->mark)
189-
skb->mark = sk->sk_mark;
189+
skb->mark = READ_ONCE(sk->sk_mark);
190190

191191
/* Send it out. */
192192
return ip_local_out(net, skb->sk, skb);
@@ -528,8 +528,8 @@ int __ip_queue_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl,
528528
skb_shinfo(skb)->gso_segs ?: 1);
529529

530530
/* TODO : should we use skb->sk here instead of sk ? */
531-
skb->priority = sk->sk_priority;
532-
skb->mark = sk->sk_mark;
531+
skb->priority = READ_ONCE(sk->sk_priority);
532+
skb->mark = READ_ONCE(sk->sk_mark);
533533

534534
res = ip_local_out(net, sk, skb);
535535
rcu_read_unlock();

net/ipv4/ip_sockglue.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -592,7 +592,7 @@ void __ip_sock_set_tos(struct sock *sk, int val)
592592
}
593593
if (inet_sk(sk)->tos != val) {
594594
inet_sk(sk)->tos = val;
595-
sk->sk_priority = rt_tos2priority(val);
595+
WRITE_ONCE(sk->sk_priority, rt_tos2priority(val));
596596
sk_dst_reset(sk);
597597
}
598598
}

net/ipv4/raw.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -348,7 +348,7 @@ static int raw_send_hdrinc(struct sock *sk, struct flowi4 *fl4,
348348
goto error;
349349
skb_reserve(skb, hlen);
350350

351-
skb->priority = sk->sk_priority;
351+
skb->priority = READ_ONCE(sk->sk_priority);
352352
skb->mark = sockc->mark;
353353
skb->tstamp = sockc->transmit_time;
354354
skb_dst_set(skb, &rt->dst);

net/ipv4/route.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -518,7 +518,7 @@ static void __build_flow_key(const struct net *net, struct flowi4 *fl4,
518518
const struct inet_sock *inet = inet_sk(sk);
519519

520520
oif = sk->sk_bound_dev_if;
521-
mark = sk->sk_mark;
521+
mark = READ_ONCE(sk->sk_mark);
522522
tos = ip_sock_rt_tos(sk);
523523
scope = ip_sock_rt_scope(sk);
524524
prot = inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol;
@@ -552,7 +552,7 @@ static void build_sk_flow_key(struct flowi4 *fl4, const struct sock *sk)
552552
inet_opt = rcu_dereference(inet->inet_opt);
553553
if (inet_opt && inet_opt->opt.srr)
554554
daddr = inet_opt->opt.faddr;
555-
flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark,
555+
flowi4_init_output(fl4, sk->sk_bound_dev_if, READ_ONCE(sk->sk_mark),
556556
ip_sock_rt_tos(sk) & IPTOS_RT_MASK,
557557
ip_sock_rt_scope(sk),
558558
inet->hdrincl ? IPPROTO_RAW : sk->sk_protocol,

net/ipv4/tcp_ipv4.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -931,9 +931,9 @@ static void tcp_v4_send_ack(const struct sock *sk,
931931
ctl_sk = this_cpu_read(ipv4_tcp_sk);
932932
sock_net_set(ctl_sk, net);
933933
ctl_sk->sk_mark = (sk->sk_state == TCP_TIME_WAIT) ?
934-
inet_twsk(sk)->tw_mark : sk->sk_mark;
934+
inet_twsk(sk)->tw_mark : READ_ONCE(sk->sk_mark);
935935
ctl_sk->sk_priority = (sk->sk_state == TCP_TIME_WAIT) ?
936-
inet_twsk(sk)->tw_priority : sk->sk_priority;
936+
inet_twsk(sk)->tw_priority : READ_ONCE(sk->sk_priority);
937937
transmit_time = tcp_transmit_time(sk);
938938
ip_send_unicast_reply(ctl_sk,
939939
skb, &TCP_SKB_CB(skb)->header.h4.opt,

net/ipv6/ping.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ static int ping_v6_sendmsg(struct sock *sk, struct msghdr *msg, size_t len)
120120

121121
ipcm6_init_sk(&ipc6, np);
122122
ipc6.sockc.tsflags = sk->sk_tsflags;
123-
ipc6.sockc.mark = sk->sk_mark;
123+
ipc6.sockc.mark = READ_ONCE(sk->sk_mark);
124124

125125
fl6.flowi6_oif = oif;
126126

0 commit comments

Comments
 (0)