aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2014-06-06 09:44:03 -0400
committerDavid S. Miller <davem@davemloft.net>2014-06-08 17:15:14 -0400
commit87757a917b0b3c0787e0563c679762152be81312 (patch)
treeffc8bfa37fc3db09ac90bff273fbf13085e8d558
parentba6de0f5304ccdc45ae260e7e0feb6e0ef2dd558 (diff)
net: force a list_del() in unregister_netdevice_many()
unregister_netdevice_many() API is error prone and we had too many bugs because of dangling LIST_HEAD on stacks. See commit f87e6f47933e3e ("net: dont leave active on stack LIST_HEAD") In fact, instead of making sure no caller leaves an active list_head, just force a list_del() in the callee. No one seems to need to access the list after unregister_netdevice_many() Signed-off-by: Eric Dumazet <edumazet@google.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--drivers/net/macvlan.c1
-rw-r--r--net/core/dev.c5
-rw-r--r--net/core/rtnetlink.c1
-rw-r--r--net/mac80211/iface.c1
4 files changed, 4 insertions, 4 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index d53e299ae1d9..7eec598c5cb6 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -1036,7 +1036,6 @@ static int macvlan_device_event(struct notifier_block *unused,
1036 list_for_each_entry_safe(vlan, next, &port->vlans, list) 1036 list_for_each_entry_safe(vlan, next, &port->vlans, list)
1037 vlan->dev->rtnl_link_ops->dellink(vlan->dev, &list_kill); 1037 vlan->dev->rtnl_link_ops->dellink(vlan->dev, &list_kill);
1038 unregister_netdevice_many(&list_kill); 1038 unregister_netdevice_many(&list_kill);
1039 list_del(&list_kill);
1040 break; 1039 break;
1041 case NETDEV_PRE_TYPE_CHANGE: 1040 case NETDEV_PRE_TYPE_CHANGE:
1042 /* Forbid underlaying device to change its type. */ 1041 /* Forbid underlaying device to change its type. */
diff --git a/net/core/dev.c b/net/core/dev.c
index fb8b0546485b..a30bef1882f5 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -6613,6 +6613,9 @@ EXPORT_SYMBOL(unregister_netdevice_queue);
6613/** 6613/**
6614 * unregister_netdevice_many - unregister many devices 6614 * unregister_netdevice_many - unregister many devices
6615 * @head: list of devices 6615 * @head: list of devices
6616 *
6617 * Note: As most callers use a stack allocated list_head,
6618 * we force a list_del() to make sure stack wont be corrupted later.
6616 */ 6619 */
6617void unregister_netdevice_many(struct list_head *head) 6620void unregister_netdevice_many(struct list_head *head)
6618{ 6621{
@@ -6622,6 +6625,7 @@ void unregister_netdevice_many(struct list_head *head)
6622 rollback_registered_many(head); 6625 rollback_registered_many(head);
6623 list_for_each_entry(dev, head, unreg_list) 6626 list_for_each_entry(dev, head, unreg_list)
6624 net_set_todo(dev); 6627 net_set_todo(dev);
6628 list_del(head);
6625 } 6629 }
6626} 6630}
6627EXPORT_SYMBOL(unregister_netdevice_many); 6631EXPORT_SYMBOL(unregister_netdevice_many);
@@ -7077,7 +7081,6 @@ static void __net_exit default_device_exit_batch(struct list_head *net_list)
7077 } 7081 }
7078 } 7082 }
7079 unregister_netdevice_many(&dev_kill_list); 7083 unregister_netdevice_many(&dev_kill_list);
7080 list_del(&dev_kill_list);
7081 rtnl_unlock(); 7084 rtnl_unlock();
7082} 7085}
7083 7086
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index f4e9037f9a0c..fbdb1556b0db 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -1744,7 +1744,6 @@ static int rtnl_dellink(struct sk_buff *skb, struct nlmsghdr *nlh)
1744 1744
1745 ops->dellink(dev, &list_kill); 1745 ops->dellink(dev, &list_kill);
1746 unregister_netdevice_many(&list_kill); 1746 unregister_netdevice_many(&list_kill);
1747 list_del(&list_kill);
1748 return 0; 1747 return 0;
1749} 1748}
1750 1749
diff --git a/net/mac80211/iface.c b/net/mac80211/iface.c
index b8d331e7d883..34799e06ee01 100644
--- a/net/mac80211/iface.c
+++ b/net/mac80211/iface.c
@@ -1758,7 +1758,6 @@ void ieee80211_remove_interfaces(struct ieee80211_local *local)
1758 } 1758 }
1759 mutex_unlock(&local->iflist_mtx); 1759 mutex_unlock(&local->iflist_mtx);
1760 unregister_netdevice_many(&unreg_list); 1760 unregister_netdevice_many(&unreg_list);
1761 list_del(&unreg_list);
1762 1761
1763 list_for_each_entry_safe(sdata, tmp, &wdev_list, list) { 1762 list_for_each_entry_safe(sdata, tmp, &wdev_list, list) {
1764 list_del(&sdata->list); 1763 list_del(&sdata->list);