summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@gmail.com>2018-03-29 12:49:52 -0700
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>2018-04-13 19:50:27 +0200
commit56f8ae4e07d2f9d1513ad79d5a44a2c2a29b5a67 (patch)
treedc1035b73e2577d3b2d58681badeacc78631deb2
parentd7d9a326879134129637eb1c570475b6cb5d90ae (diff)
vrf: Fix use after free and double free in vrf_finish_output
commit 82dd0d2a9a76fc8fa2b18d80b987d455728bf83a upstream. Miguel reported an skb use after free / double free in vrf_finish_output when neigh_output returns an error. The vrf driver should return after the call to neigh_output as it takes over the skb on error path as well. Patch is a simplified version of Miguel's patch which was written for 4.9, and updated to top of tree. Fixes: 8f58336d3f78a ("net: Add ethernet header for pass through VRF device") Signed-off-by: Miguel Fadon Perlines <mfadon@teldat.com> Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net> [ backport to 4.4 and 4.9 dropped the sock_confirm_neigh and changed neigh_output to dst_neigh_output ] Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
-rw-r--r--drivers/net/vrf.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/net/vrf.c b/drivers/net/vrf.c
index ac945f8781ac..d3d59122a357 100644
--- a/drivers/net/vrf.c
+++ b/drivers/net/vrf.c
@@ -550,13 +550,15 @@ static int vrf_finish_output(struct net *net, struct sock *sk, struct sk_buff *s
neigh = __ipv4_neigh_lookup_noref(dev, nexthop);
if (unlikely(!neigh))
neigh = __neigh_create(&arp_tbl, &nexthop, dev, false);
- if (!IS_ERR(neigh))
+ if (!IS_ERR(neigh)) {
ret = dst_neigh_output(dst, neigh, skb);
+ rcu_read_unlock_bh();
+ return ret;
+ }
rcu_read_unlock_bh();
err:
- if (unlikely(ret < 0))
- vrf_tx_error(skb->dev, skb);
+ vrf_tx_error(skb->dev, skb);
return ret;
}