diff options
Diffstat (limited to 'net/ipv4/tcp_minisocks.c')
| -rw-r--r-- | net/ipv4/tcp_minisocks.c | 11 | 
1 files changed, 7 insertions, 4 deletions
diff --git a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c index 04fc328727e6..c8f2aa003387 100644 --- a/net/ipv4/tcp_minisocks.c +++ b/net/ipv4/tcp_minisocks.c @@ -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  |