diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c index 6d9571cb317d1c987c4d428a360d7aa99f0992fa..153e90687006b192c6a7328965090d5bfe0fdf86 100644 --- a/net/ipv6/ip6_output.c +++ b/net/ipv6/ip6_output.c @@ -81,6 +81,8 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * } skb = nskb; } + /* Make sure idev stays alive */ + rcu_read_lock(); if (skb && pskb_expand_head(skb, SKB_DATA_ALIGN(delta), 0, GFP_ATOMIC)) { kfree_skb(skb); @@ -88,8 +90,10 @@ static int ip6_finish_output2(struct net *net, struct sock *sk, struct sk_buff * } if (!skb) { IP6_INC_STATS(net, ip6_dst_idev(dst), IPSTATS_MIB_OUTDISCARDS); + rcu_read_unlock(); return -ENOMEM; } + rcu_read_unlock(); } if (ipv6_addr_is_multicast(&ipv6_hdr(skb)->daddr)) {