Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

ipvlan: hold lower dev to avoid possible use-after-free

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: 2ad7bf363841 ("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>

authored by

Mahesh Bandewar and committed by
David S. Miller
40b9d1ab 8207f253

+3
+1
drivers/net/ipvlan/ipvlan.h
··· 98 98 struct sk_buff_head backlog; 99 99 int count; 100 100 struct ida ida; 101 + netdevice_tracker dev_tracker; 101 102 }; 102 103 103 104 struct ipvl_skb_cb {
+2
drivers/net/ipvlan/ipvlan_main.c
··· 83 83 if (err) 84 84 goto err; 85 85 86 + netdev_hold(dev, &port->dev_tracker, GFP_KERNEL); 86 87 return 0; 87 88 88 89 err: ··· 96 95 struct ipvl_port *port = ipvlan_port_get_rtnl(dev); 97 96 struct sk_buff *skb; 98 97 98 + netdev_put(dev, &port->dev_tracker); 99 99 if (port->mode == IPVLAN_MODE_L3S) 100 100 ipvlan_l3s_unregister(port); 101 101 netdev_rx_handler_unregister(dev);