@@ -861,7 +861,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
861861
862862 err = ip_build_and_send_pkt (skb , sk , ireq -> ir_loc_addr ,
863863 ireq -> ir_rmt_addr ,
864- ireq -> opt );
864+ rcu_dereference ( ireq -> ireq_opt ) );
865865 err = net_xmit_eval (err );
866866 }
867867
@@ -873,7 +873,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
873873 */
874874static void tcp_v4_reqsk_destructor (struct request_sock * req )
875875{
876- kfree (inet_rsk (req )-> opt );
876+ kfree (rcu_dereference_protected ( inet_rsk (req )-> ireq_opt , 1 ) );
877877}
878878
879879#ifdef CONFIG_TCP_MD5SIG
@@ -1199,7 +1199,7 @@ static void tcp_v4_init_req(struct request_sock *req,
11991199
12001200 sk_rcv_saddr_set (req_to_sk (req ), ip_hdr (skb )-> daddr );
12011201 sk_daddr_set (req_to_sk (req ), ip_hdr (skb )-> saddr );
1202- ireq -> opt = tcp_v4_save_options (skb );
1202+ RCU_INIT_POINTER ( ireq -> ireq_opt , tcp_v4_save_options (skb ) );
12031203}
12041204
12051205static struct dst_entry * tcp_v4_route_req (const struct sock * sk ,
@@ -1295,10 +1295,9 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
12951295 sk_daddr_set (newsk , ireq -> ir_rmt_addr );
12961296 sk_rcv_saddr_set (newsk , ireq -> ir_loc_addr );
12971297 newsk -> sk_bound_dev_if = ireq -> ir_iif ;
1298- newinet -> inet_saddr = ireq -> ir_loc_addr ;
1299- inet_opt = ireq -> opt ;
1300- rcu_assign_pointer (newinet -> inet_opt , inet_opt );
1301- ireq -> opt = NULL ;
1298+ newinet -> inet_saddr = ireq -> ir_loc_addr ;
1299+ inet_opt = rcu_dereference (ireq -> ireq_opt );
1300+ RCU_INIT_POINTER (newinet -> inet_opt , inet_opt );
13021301 newinet -> mc_index = inet_iif (skb );
13031302 newinet -> mc_ttl = ip_hdr (skb )-> ttl ;
13041303 newinet -> rcv_tos = ip_hdr (skb )-> tos ;
@@ -1346,9 +1345,12 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
13461345 if (__inet_inherit_port (sk , newsk ) < 0 )
13471346 goto put_and_exit ;
13481347 * own_req = inet_ehash_nolisten (newsk , req_to_sk (req_unhash ));
1349- if (* own_req )
1348+ if (likely ( * own_req )) {
13501349 tcp_move_syn (newtp , req );
1351-
1350+ ireq -> ireq_opt = NULL ;
1351+ } else {
1352+ newinet -> inet_opt = NULL ;
1353+ }
13521354 return newsk ;
13531355
13541356exit_overflow :
@@ -1359,6 +1361,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
13591361 tcp_listendrop (sk );
13601362 return NULL ;
13611363put_and_exit :
1364+ newinet -> inet_opt = NULL ;
13621365 inet_csk_prepare_forced_close (newsk );
13631366 tcp_done (newsk );
13641367 goto exit ;
0 commit comments