| From 82dd0d2a9a76fc8fa2b18d80b987d455728bf83a Mon Sep 17 00:00:00 2001 |
| From: David Ahern <dsahern@gmail.com> |
| Date: Thu, 29 Mar 2018 12:49:52 -0700 |
| Subject: vrf: Fix use after free and double free in vrf_finish_output |
| |
| From: David Ahern <dsahern@gmail.com> |
| |
| 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> |
| |
| --- |
| drivers/net/vrf.c | 8 +++++--- |
| 1 file changed, 5 insertions(+), 3 deletions(-) |
| |
| --- a/drivers/net/vrf.c |
| +++ b/drivers/net/vrf.c |
| @@ -585,13 +585,15 @@ static int vrf_finish_output(struct net |
| 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; |
| } |
| |