aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/rxrpc/input.c12
-rw-r--r--net/rxrpc/local_object.c3
2 files changed, 10 insertions, 5 deletions
diff --git a/net/rxrpc/input.c b/net/rxrpc/input.c
index 4c6f9d0a00e7..c2c35cf4e308 100644
--- a/net/rxrpc/input.c
+++ b/net/rxrpc/input.c
@@ -1161,19 +1161,19 @@ int rxrpc_extract_header(struct rxrpc_skb_priv *sp, struct sk_buff *skb)
1161 * handle data received on the local endpoint 1161 * handle data received on the local endpoint
1162 * - may be called in interrupt context 1162 * - may be called in interrupt context
1163 * 1163 *
1164 * The socket is locked by the caller and this prevents the socket from being 1164 * [!] Note that as this is called from the encap_rcv hook, the socket is not
1165 * shut down and the local endpoint from going away, thus sk_user_data will not 1165 * held locked by the caller and nothing prevents sk_user_data on the UDP from
1166 * be cleared until this function returns. 1166 * being cleared in the middle of processing this function.
1167 * 1167 *
1168 * Called with the RCU read lock held from the IP layer via UDP. 1168 * Called with the RCU read lock held from the IP layer via UDP.
1169 */ 1169 */
1170int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb) 1170int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
1171{ 1171{
1172 struct rxrpc_local *local = rcu_dereference_sk_user_data(udp_sk);
1172 struct rxrpc_connection *conn; 1173 struct rxrpc_connection *conn;
1173 struct rxrpc_channel *chan; 1174 struct rxrpc_channel *chan;
1174 struct rxrpc_call *call = NULL; 1175 struct rxrpc_call *call = NULL;
1175 struct rxrpc_skb_priv *sp; 1176 struct rxrpc_skb_priv *sp;
1176 struct rxrpc_local *local = udp_sk->sk_user_data;
1177 struct rxrpc_peer *peer = NULL; 1177 struct rxrpc_peer *peer = NULL;
1178 struct rxrpc_sock *rx = NULL; 1178 struct rxrpc_sock *rx = NULL;
1179 unsigned int channel; 1179 unsigned int channel;
@@ -1181,6 +1181,10 @@ int rxrpc_input_packet(struct sock *udp_sk, struct sk_buff *skb)
1181 1181
1182 _enter("%p", udp_sk); 1182 _enter("%p", udp_sk);
1183 1183
1184 if (unlikely(!local)) {
1185 kfree_skb(skb);
1186 return 0;
1187 }
1184 if (skb->tstamp == 0) 1188 if (skb->tstamp == 0)
1185 skb->tstamp = ktime_get_real(); 1189 skb->tstamp = ktime_get_real();
1186 1190
diff --git a/net/rxrpc/local_object.c b/net/rxrpc/local_object.c
index 15cf42d5b53a..01959db51445 100644
--- a/net/rxrpc/local_object.c
+++ b/net/rxrpc/local_object.c
@@ -304,7 +304,8 @@ nomem:
304 ret = -ENOMEM; 304 ret = -ENOMEM;
305sock_error: 305sock_error:
306 mutex_unlock(&rxnet->local_mutex); 306 mutex_unlock(&rxnet->local_mutex);
307 kfree(local); 307 if (local)
308 call_rcu(&local->rcu, rxrpc_local_rcu);
308 _leave(" = %d", ret); 309 _leave(" = %d", ret);
309 return ERR_PTR(ret); 310 return ERR_PTR(ret);
310 311