: rtnl_link: fix use-after-free
Subsystems (2)
commit 6e470bd53fb50632fe1878bb74bb8531a21b6731
Author: Patrick McHardy <[email protected]> Date: Sun Jan 20 18:19:15 2008 +0100
[NET]: rtnl_link: fix use-after-free
When unregistering the rtnl_link_ops, all existing devices using the ops are destroyed. With nested devices this may lead to a use-after-free despite the use of for_each_netdev_safe() in case the upper device is next in the device list and is destroyed by the NETDEV_UNREGISTER notifier.
The easy fix is to restart scanning the device list after removing a device. Alternatively we could add new devices to the front of the list to avoid having dependant devices follow the device they depend on. A third option would be to only restart scanning if dev->iflink of the next device matches dev->ifindex of the current one. For now this seems like the safest solution.
With this patch, the veth rtnl_link_ops unregistration can use rtnl_link_unregister() directly since it now also handles destruction of multiple devices at once.
drivers/net/veth.c +1 -13
@@ -459,19 +459,7 @@ static __init int veth_init(void) static __exit void veth_exit(void) { -struct veth_priv *priv, *next; - -rtnl_lock (); -/* -* cannot trust __rtnl_link_unregister() to unregister all -* devices, as each ->dellink call will remove two devices -* from the list at once. -*/ -list_for_each_entry_safe (priv, next, &veth_list, list) -veth_dellink (priv->dev); - -__rtnl_link_unregister (&veth_link_ops); -rtnl_unlock (); +rtnl_link_unregister (&veth_link_ops); }module_init (veth_init);
net/core/rtnetlink.c +4 -1
@@ -308,9 +308,12 @@ void __rtnl_link_unregister(struct rtnl_link_ops *ops)struct net *net;for_each_net (net) { +restart:for_each_netdev_safe (net, dev, n) { -if (dev->rtnl_link_ops == ops) +if (dev->rtnl_link_ops == ops) { ops->dellink (dev); + goto restart; + } } }list_del (&ops->list);
From: Patrick McHardy <[email protected]>
Date: Sun, 20 Jan 2008 18:21:27 +0100
Quoted 19 lines
commit
6e470bd53fb50632fe1878bb74bb8531a21b6731Author: Patrick McHardy <[email protected]> Date: Sun Jan 20 18:19:15 2008 +0100[NET]:
rtnl_link: fix use-after-freeWhen unregistering the
rtnl_link_ops, all existing devices using the ops are destroyed. With nested devices this may lead to a use-after-free despite the use offor_each_netdev_safe()in case the upper device is next in the device list and is destroyed by theNETDEV_UNREGISTERnotifier.The easy fix is to restart scanning the device list after removing a device. Alternatively we could add new devices to the front of the list to avoid having dependant devices follow the device they depend on. A third option would be to only restart scanning if
dev->iflinkof the next device matchesdev->ifindexof the current one. For now this seems like the safest solution.
Quoted 5 lines
With this patch, the veth
rtnl_link_opsunregistration can usertnl_link_unregister()directly since it now also handles destruction of multiple devices at once.Signed-off-by Patrick McHardy <[email protected]>
Applied, thanks.