Commit e9b2bd96 authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

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/20230717144445.653164-1-edumazet@google.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents e7002b3b eba20811
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -988,11 +988,12 @@ static void tcp_v4_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
			tcp_rsk(req)->rcv_nxt,
			req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
			tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
			req->ts_recent,
			READ_ONCE(req->ts_recent),
			0,
			tcp_md5_do_lookup(sk, l3index, addr, AF_INET),
			inet_rsk(req)->no_srccheck ? IP_REPLY_ARG_NOSRCCHECK : 0,
			ip_hdr(skb)->tos, tcp_rsk(req)->txhash);
			ip_hdr(skb)->tos,
			READ_ONCE(tcp_rsk(req)->txhash));
}

/*
+7 −4
Original line number Diff line number Diff line
@@ -528,7 +528,7 @@ struct sock *tcp_create_openreq_child(const struct sock *sk,
	newicsk->icsk_ack.lrcvtime = tcp_jiffies32;

	newtp->lsndtime = tcp_jiffies32;
	newsk->sk_txhash = treq->txhash;
	newsk->sk_txhash = READ_ONCE(treq->txhash);
	newtp->total_retrans = req->num_retrans;

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

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

		if (tmp_opt.saw_tstamp) {
			tmp_opt.ts_recent = req->ts_recent;
			tmp_opt.ts_recent = READ_ONCE(req->ts_recent);
			if (tmp_opt.rcv_tsecr)
				tmp_opt.rcv_tsecr -= tcp_rsk(req)->ts_off;
			/* 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,

	/* In sequence, PAWS is OK. */

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

	if (TCP_SKB_CB(skb)->seq == tcp_rsk(req)->rcv_isn) {
		/* Truncate SYN, it is out of window starting
+3 −3
Original line number Diff line number Diff line
@@ -878,7 +878,7 @@ static unsigned int tcp_synack_options(const struct sock *sk,
	if (likely(ireq->tstamp_ok)) {
		opts->options |= OPTION_TS;
		opts->tsval = tcp_skb_timestamp(skb) + tcp_rsk(req)->ts_off;
		opts->tsecr = req->ts_recent;
		opts->tsecr = READ_ONCE(req->ts_recent);
		remaining -= TCPOLEN_TSTAMP_ALIGNED;
	}
	if (likely(ireq->sack_ok)) {
@@ -3660,7 +3660,7 @@ struct sk_buff *tcp_make_synack(const struct sock *sk, struct dst_entry *dst,
	rcu_read_lock();
	md5 = tcp_rsk(req)->af_specific->req_md5_lookup(sk, req_to_sk(req));
#endif
	skb_set_hash(skb, tcp_rsk(req)->txhash, PKT_HASH_TYPE_L4);
	skb_set_hash(skb, READ_ONCE(tcp_rsk(req)->txhash), PKT_HASH_TYPE_L4);
	/* bpf program will be interested in the tcp_flags */
	TCP_SKB_CB(skb)->tcp_flags = TCPHDR_SYN | TCPHDR_ACK;
	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)

	/* Paired with WRITE_ONCE() in sock_setsockopt() */
	if (READ_ONCE(sk->sk_txrehash) == SOCK_TXREHASH_ENABLED)
		tcp_rsk(req)->txhash = net_tx_rndhash();
		WRITE_ONCE(tcp_rsk(req)->txhash, net_tx_rndhash());
	res = af_ops->send_synack(sk, NULL, &fl, req, NULL, TCP_SYNACK_NORMAL,
				  NULL);
	if (!res) {
+2 −2
Original line number Diff line number Diff line
@@ -1126,10 +1126,10 @@ static void tcp_v6_reqsk_send_ack(const struct sock *sk, struct sk_buff *skb,
			tcp_rsk(req)->rcv_nxt,
			req->rsk_rcv_wnd >> inet_rsk(req)->rcv_wscale,
			tcp_time_stamp_raw() + tcp_rsk(req)->ts_off,
			req->ts_recent, sk->sk_bound_dev_if,
			READ_ONCE(req->ts_recent), sk->sk_bound_dev_if,
			tcp_v6_md5_do_lookup(sk, &ipv6_hdr(skb)->saddr, l3index),
			ipv6_get_dsfield(ipv6_hdr(skb)), 0, sk->sk_priority,
			tcp_rsk(req)->txhash);
			READ_ONCE(tcp_rsk(req)->txhash));
}