summaryrefslogtreecommitdiff
path: root/net/xfrm/espintcp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/xfrm/espintcp.c')
-rw-r--r--net/xfrm/espintcp.c9
1 files changed, 8 insertions, 1 deletions
diff --git a/net/xfrm/espintcp.c b/net/xfrm/espintcp.c
index 374e1b964438..674aedc5af5a 100644
--- a/net/xfrm/espintcp.c
+++ b/net/xfrm/espintcp.c
@@ -37,6 +37,11 @@ static void handle_esp(struct sk_buff *skb, struct sock *sk)
rcu_read_lock();
skb->dev = dev_get_by_index_rcu(sock_net(sk), skb->skb_iif);
+ if (!skb->dev) {
+ XFRM_INC_STATS(sock_net(sk), LINUX_MIB_XFRMINERROR);
+ kfree_skb(skb);
+ goto out;
+ }
local_bh_disable();
#if IS_ENABLED(CONFIG_IPV6)
if (sk->sk_family == AF_INET6)
@@ -45,6 +50,7 @@ static void handle_esp(struct sk_buff *skb, struct sock *sk)
#endif
xfrm4_rcv_encap(skb, IPPROTO_ESP, 0, TCP_ENCAP_ESPINTCP);
local_bh_enable();
+out:
rcu_read_unlock();
}
@@ -515,7 +521,8 @@ static void espintcp_close(struct sock *sk, long timeout)
strp_stop(&ctx->strp);
sk->sk_prot = &tcp_prot;
- barrier();
+
+ synchronize_rcu();
disable_work_sync(&ctx->work);
strp_done(&ctx->strp);