Skip to content

Commit

Permalink
ipvlan: hold lower dev to avoid possible use-after-free
Browse files Browse the repository at this point in the history
Recently syzkaller discovered the issue of disappearing lower
device (NETDEV_UNREGISTER) while the virtual device (like
macvlan) is still having it as a lower device. So it's just
a matter of time similar discovery will be made for IPvlan
device setup. So fixing it preemptively. Also while at it,
add a refcount tracker.

Fixes: 2ad7bf3 ("ipvlan: Initial check-in of the IPVLAN driver.")
Signed-off-by: Mahesh Bandewar <maheshb@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Mahesh Bandewar authored and David S. Miller committed Nov 18, 2022
1 parent 8207f25 commit 40b9d1a
Show file tree
Hide file tree
Showing 2 changed files with 3 additions and 0 deletions.
1 change: 1 addition & 0 deletions drivers/net/ipvlan/ipvlan.h
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ struct ipvl_port {
struct sk_buff_head backlog;
int count;
struct ida ida;
netdevice_tracker dev_tracker;
};

struct ipvl_skb_cb {
Expand Down
2 changes: 2 additions & 0 deletions drivers/net/ipvlan/ipvlan_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ static int ipvlan_port_create(struct net_device *dev)
if (err)
goto err;

netdev_hold(dev, &port->dev_tracker, GFP_KERNEL);
return 0;

err:
Expand All @@ -95,6 +96,7 @@ static void ipvlan_port_destroy(struct net_device *dev)
struct ipvl_port *port = ipvlan_port_get_rtnl(dev);
struct sk_buff *skb;

netdev_put(dev, &port->dev_tracker);
if (port->mode == IPVLAN_MODE_L3S)
ipvlan_l3s_unregister(port);
netdev_rx_handler_unregister(dev);
Expand Down

0 comments on commit 40b9d1a

Please sign in to comment.