@@ -86,27 +86,37 @@ int ip4_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
8686}
8787EXPORT_SYMBOL (ip4_datagram_connect );
8888
89+ /* Because UDP xmit path can manipulate sk_dst_cache without holding
90+ * socket lock, we need to use sk_dst_set() here,
91+ * even if we own the socket lock.
92+ */
8993void ip4_datagram_release_cb (struct sock * sk )
9094{
9195 const struct inet_sock * inet = inet_sk (sk );
9296 const struct ip_options_rcu * inet_opt ;
9397 __be32 daddr = inet -> inet_daddr ;
98+ struct dst_entry * dst ;
9499 struct flowi4 fl4 ;
95100 struct rtable * rt ;
96101
97- if (! __sk_dst_get (sk ) || __sk_dst_check (sk , 0 ))
98- return ;
99-
100102 rcu_read_lock ();
103+
104+ dst = __sk_dst_get (sk );
105+ if (!dst || !dst -> obsolete || dst -> ops -> check (dst , 0 )) {
106+ rcu_read_unlock ();
107+ return ;
108+ }
101109 inet_opt = rcu_dereference (inet -> inet_opt );
102110 if (inet_opt && inet_opt -> opt .srr )
103111 daddr = inet_opt -> opt .faddr ;
104112 rt = ip_route_output_ports (sock_net (sk ), & fl4 , sk , daddr ,
105113 inet -> inet_saddr , inet -> inet_dport ,
106114 inet -> inet_sport , sk -> sk_protocol ,
107115 RT_CONN_FLAGS (sk ), sk -> sk_bound_dev_if );
108- if (!IS_ERR (rt ))
109- __sk_dst_set (sk , & rt -> dst );
116+
117+ dst = !IS_ERR (rt ) ? & rt -> dst : NULL ;
118+ sk_dst_set (sk , dst );
119+
110120 rcu_read_unlock ();
111121}
112122EXPORT_SYMBOL_GPL (ip4_datagram_release_cb );
0 commit comments