Skip to content

Commit e9b2bd9

Browse files
committed
Merge branch 'tcp-annotate-data-races-in-tcp_rsk-req'
Eric Dumazet says: ==================== tcp: annotate data-races in tcp_rsk(req) Small series addressing two syzbot reports around tcp_rsk(req) ==================== Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents e7002b3 + eba2081 commit e9b2bd9

File tree

4 files changed

+15
-11
lines changed

4 files changed

+15
-11
lines changed

net/ipv4/tcp_ipv4.c

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -988,11 +988,12 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
988988
tcp_rsk(req)->rcv_nxt,
989989
req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
990990
tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
991-
req->ts_recent,
991+
READ_ONCE(req->ts_recent),
992992
0,
993993
tcp_md5_do_lookup(sk, l3index, addr, AF_INET),
994994
inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0,
995-
ip_hdr(skb)->tos, tcp_rsk(req)->txhash);
995+
ip_hdr(skb)->tos,
996+
READ_ONCE(tcp_rsk(req)->txhash));
996997
}
997998

998999
/*

net/ipv4/tcp_minisocks.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
528528
newicsk->icsk_ack.lrcvtime = tcp_jiffies32;
529529

530530
newtp->lsndtime = tcp_jiffies32;
531-
newsk->sk_txhash = treq->txhash;
531+
newsk->sk_txhash = READ_ONCE(treq->txhash);
532532
newtp->total_retrans = req->num_retrans;
533533

534534
tcp_init_xmit_timers(newsk);
@@ -555,7 +555,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
555555
newtp->max_window = newtp->snd_wnd;
556556

557557
if (newtp->rx_opt.tstamp_ok) {
558-
newtp->rx_opt.ts_recent = req->ts_recent;
558+
newtp->rx_opt.ts_recent = READ_ONCE(req->ts_recent);
559559
newtp->rx_opt.ts_recent_stamp = ktime_get_seconds();
560560
newtp->tcp_header_len = sizeof(struct tcphdr) + TCPOLEN_TSTAMP_ALIGNED;
561561
} else {
@@ -619,7 +619,7 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
619619
tcp_parse_options(sock_net(sk), skb, &tmp_opt, 0, NULL);
620620

621621
if (tmp_opt.saw_tstamp) {
622-
tmp_opt.ts_recent = req->ts_recent;
622+
tmp_opt.ts_recent = READ_ONCE(req->ts_recent);
623623
if (tmp_opt.rcv_tsecr)
624624
tmp_opt.rcv_tsecr -= tcp_rsk(req)->ts_off;
625625
/* We do not store true stamp, but it is not required,
@@ -758,8 +758,11 @@ struct sock *tcp_check_req(struct sock *sk, struct sk_buff *skb,
758758

759759
/* In sequence, PAWS is OK. */
760760

761+
/* TODO: We probably should defer ts_recent change once
762+
* we take ownership of @req.
763+
*/
761764
if (tmp_opt.saw_tstamp && !after(TCP_SKB_CB(skb)->seq, tcp_rsk(req)->rcv_nxt))
762-
req->ts_recent = tmp_opt.rcv_tsval;
765+
WRITE_ONCE(req->ts_recent, tmp_opt.rcv_tsval);
763766

764767
if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) {
765768
/* Truncate SYN, it is out of window starting

net/ipv4/tcp_output.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,7 @@ static unsigned int tcp_synack_options(const struct sock *sk,
878878
if (likely(ireq->tstamp_ok)) {
879879
opts->options |= OPTION_TS;
880880
opts->tsval = tcp_skb_timestamp(skb) + tcp_rsk(req)->ts_off;
881-
opts->tsecr = req->ts_recent;
881+
opts->tsecr = READ_ONCE(req->ts_recent);
882882
remaining -= TCPOLEN_TSTAMP_ALIGNED;
883883
}
884884
if (likely(ireq->sack_ok)) {
@@ -3660,7 +3660,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
36603660
rcu_read_lock();
36613661
md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk, req_to_sk(req));
36623662
#endif
3663-
skb_set_hash(skb, tcp_rsk(req)->txhash, PKT_HASH_TYPE_L4);
3663+
skb_set_hash(skb, READ_ONCE(tcp_rsk(req)->txhash), PKT_HASH_TYPE_L4);
36643664
/* bpf program will be interested in the tcp_flags */
36653665
TCP_SKB_CB(skb)->tcp_flags = TCPHDR_SYN | TCPHDR_ACK;
36663666
tcp_header_size = tcp_synack_options(sk, req, mss, skb, &opts, md5,
@@ -4210,7 +4210,7 @@ int tcp_rtx_synack(const struct sock *sk, struct request_sock *req)
42104210

42114211
/* Paired with WRITE_ONCE() in sock_setsockopt() */
42124212
if (READ_ONCE(sk->sk_txrehash) == SOCK_TXREHASH_ENABLED)
4213-
tcp_rsk(req)->txhash = net_tx_rndhash();
4213+
WRITE_ONCE(tcp_rsk(req)->txhash, net_tx_rndhash());
42144214
res = af_ops->send_synack(sk, NULL, &fl, req, NULL, TCP_SYNACK_NORMAL,
42154215
NULL);
42164216
if (!res) {

net/ipv6/tcp_ipv6.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1126,10 +1126,10 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
11261126
tcp_rsk(req)->rcv_nxt,
11271127
req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
11281128
tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
1129-
req->ts_recent, sk->sk_bound_dev_if,
1129+
READ_ONCE(req->ts_recent), sk->sk_bound_dev_if,
11301130
tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index),
11311131
ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority,
1132-
tcp_rsk(req)->txhash);
1132+
READ_ONCE(tcp_rsk(req)->txhash));
11331133
}
11341134

11351135

0 commit comments

Comments
 (0)