@@ -861,7 +861,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
861
861
862
862
err = ip_build_and_send_pkt (skb , sk , ireq -> ir_loc_addr ,
863
863
ireq -> ir_rmt_addr ,
864
- ireq -> opt );
864
+ rcu_dereference ( ireq -> ireq_opt ) );
865
865
err = net_xmit_eval (err );
866
866
}
867
867
@@ -873,7 +873,7 @@ static int tcp_v4_send_synack(const struct sock *sk, struct dst_entry *dst,
873
873
*/
874
874
static void tcp_v4_reqsk_destructor (struct request_sock * req )
875
875
{
876
- kfree (inet_rsk (req )-> opt );
876
+ kfree (rcu_dereference_protected ( inet_rsk (req )-> ireq_opt , 1 ) );
877
877
}
878
878
879
879
#ifdef CONFIG_TCP_MD5SIG
@@ -1199,7 +1199,7 @@ static void tcp_v4_init_req(struct request_sock *req,
1199
1199
1200
1200
sk_rcv_saddr_set (req_to_sk (req ), ip_hdr (skb )-> daddr );
1201
1201
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 ) );
1203
1203
}
1204
1204
1205
1205
static 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,
1295
1295
sk_daddr_set (newsk , ireq -> ir_rmt_addr );
1296
1296
sk_rcv_saddr_set (newsk , ireq -> ir_loc_addr );
1297
1297
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 );
1302
1301
newinet -> mc_index = inet_iif (skb );
1303
1302
newinet -> mc_ttl = ip_hdr (skb )-> ttl ;
1304
1303
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,
1346
1345
if (__inet_inherit_port (sk , newsk ) < 0 )
1347
1346
goto put_and_exit ;
1348
1347
* own_req = inet_ehash_nolisten (newsk , req_to_sk (req_unhash ));
1349
- if (* own_req )
1348
+ if (likely ( * own_req )) {
1350
1349
tcp_move_syn (newtp , req );
1351
-
1350
+ ireq -> ireq_opt = NULL ;
1351
+ } else {
1352
+ newinet -> inet_opt = NULL ;
1353
+ }
1352
1354
return newsk ;
1353
1355
1354
1356
exit_overflow :
@@ -1359,6 +1361,7 @@ struct sock *tcp_v4_syn_recv_sock(const struct sock *sk, struct sk_buff *skb,
1359
1361
tcp_listendrop (sk );
1360
1362
return NULL ;
1361
1363
put_and_exit :
1364
+ newinet -> inet_opt = NULL ;
1362
1365
inet_csk_prepare_forced_close (newsk );
1363
1366
tcp_done (newsk );
1364
1367
goto exit ;
0 commit comments