diff options
| -rw-r--r-- | net/ipv4/inet_connection_sock.c | 7 | 
1 files changed, 6 insertions, 1 deletions
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c index db0cf17c00f..7f75f21d7b8 100644 --- a/net/ipv4/inet_connection_sock.c +++ b/net/ipv4/inet_connection_sock.c @@ -404,12 +404,15 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,  {  	const struct inet_request_sock *ireq = inet_rsk(req);  	struct inet_sock *newinet = inet_sk(newsk); -	struct ip_options_rcu *opt = ireq->opt; +	struct ip_options_rcu *opt;  	struct net *net = sock_net(sk);  	struct flowi4 *fl4;  	struct rtable *rt;  	fl4 = &newinet->cork.fl.u.ip4; + +	rcu_read_lock(); +	opt = rcu_dereference(newinet->inet_opt);  	flowi4_init_output(fl4, sk->sk_bound_dev_if, sk->sk_mark,  			   RT_CONN_FLAGS(sk), RT_SCOPE_UNIVERSE,  			   sk->sk_protocol, inet_sk_flowi_flags(sk), @@ -421,11 +424,13 @@ struct dst_entry *inet_csk_route_child_sock(struct sock *sk,  		goto no_route;  	if (opt && opt->opt.is_strictroute && rt->rt_gateway)  		goto route_err; +	rcu_read_unlock();  	return &rt->dst;  route_err:  	ip_rt_put(rt);  no_route: +	rcu_read_unlock();  	IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES);  	return NULL;  }  |