Skip to content

Commit d27a1aa

Browse files
edumazetgregkh
authored andcommitted
tcp: annotate data-races around tp->keepalive_probes
[ Upstream commit 6e5e1de ] do_tcp_getsockopt() reads tp->keepalive_probes while another cpu might change its value. Fixes: 1da177e ("Linux-2.6.12-rc2") Signed-off-by: Eric Dumazet <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Sasha Levin <[email protected]>
1 parent 161b069 commit d27a1aa

File tree

2 files changed

+10
-4
lines changed

2 files changed

+10
-4
lines changed

include/net/tcp.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1535,9 +1535,14 @@ static inline int keepalive_time_when(const struct tcp_sock *tp)
15351535
static inline int keepalive_probes(const struct tcp_sock *tp)
15361536
{
15371537
struct net *net = sock_net((struct sock *)tp);
1538+
int val;
1539+
1540+
/* Paired with WRITE_ONCE() in tcp_sock_set_keepcnt()
1541+
* and do_tcp_setsockopt().
1542+
*/
1543+
val = READ_ONCE(tp->keepalive_probes);
15381544

1539-
return tp->keepalive_probes ? :
1540-
READ_ONCE(net->ipv4.sysctl_tcp_keepalive_probes);
1545+
return val ? : READ_ONCE(net->ipv4.sysctl_tcp_keepalive_probes);
15411546
}
15421547

15431548
static inline u32 keepalive_time_elapsed(const struct tcp_sock *tp)

net/ipv4/tcp.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3463,7 +3463,8 @@ int tcp_sock_set_keepcnt(struct sock *sk, int val)
34633463
return -EINVAL;
34643464

34653465
lock_sock(sk);
3466-
tcp_sk(sk)->keepalive_probes = val;
3466+
/* Paired with READ_ONCE() in keepalive_probes() */
3467+
WRITE_ONCE(tcp_sk(sk)->keepalive_probes, val);
34673468
release_sock(sk);
34683469
return 0;
34693470
}
@@ -3671,7 +3672,7 @@ int do_tcp_setsockopt(struct sock *sk, int level, int optname,
36713672
if (val < 1 || val > MAX_TCP_KEEPCNT)
36723673
err = -EINVAL;
36733674
else
3674-
tp->keepalive_probes = val;
3675+
WRITE_ONCE(tp->keepalive_probes, val);
36753676
break;
36763677
case TCP_SYNCNT:
36773678
if (val < 1 || val > MAX_TCP_SYNCNT)

0 commit comments

Comments
 (0)