[Devel,RHEL7,COMMIT] ms/net: fix creation adjacent device symlinks

Submitted by Konstantin Khorenko on Jan. 11, 2017, 4:19 p.m.

Details

Message ID 201701111619.v0BGJa0a012227@finist_cl7.x64_64.work.ct
State New
Series "macvlan: fix crash on list_del_rcu in macvlan_dellink"
Headers show

Commit Message

Konstantin Khorenko Jan. 11, 2017, 4:19 p.m.
The commit is pushed to "branch-rh7-3.10.0-514.vz7.27.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git
after rh7-3.10.0-514.vz7.27.9
------>
commit 86ebd49b6913ee3e9e4e66220e350b6982c985e5
Author: Alexander Y. Fomichev <git.user@gmail.com>
Date:   Wed Jan 11 20:19:36 2017 +0400

    ms/net: fix creation adjacent device symlinks
    
    __netdev_adjacent_dev_insert may add adjust device of different net
    namespace, without proper check it leads to emergence of broken
    sysfs links from/to devices in another namespace.
    Fix: rewrite netdev_adjacent_is_neigh_list macro as a function,
         move net_eq check into netdev_adjacent_is_neigh_list.
         (thanks David)
         related to: 4c75431ac3520631f1d9e74aa88407e6374dbbc4
    
    Signed-off-by: Alexander Fomichev <git.user@gmail.com>
    Signed-off-by: David S. Miller <davem@davemloft.net>
    
    ms commit: 7ce64c7 ("net: fix creation adjacent device symlinks")
    https://jira.sw.ru/browse/PSBM-58300
    
    Signed-off-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
    Acked-by: Andrew Vagin <avagin@virtuozzo.com>
---
 net/core/dev.c | 18 +++++++++++-------
 1 file changed, 11 insertions(+), 7 deletions(-)

Patch hide | download patch | download mbox

diff --git a/net/core/dev.c b/net/core/dev.c
index b1a183d..65f68fd 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -5182,9 +5182,14 @@  void netdev_adjacent_sysfs_del(struct net_device *dev,
 	sysfs_remove_link(&(dev->dev.kobj), linkname);
 }
 
-#define netdev_adjacent_is_neigh_list(dev, dev_list) \
-		(dev_list == &dev->adj_list.upper || \
-		 dev_list == &dev->adj_list.lower)
+static inline bool netdev_adjacent_is_neigh_list(struct net_device *dev,
+						 struct net_device *adj_dev,
+						 struct list_head *dev_list)
+{
+	return (dev_list == &dev->adj_list.upper ||
+		dev_list == &dev->adj_list.lower) &&
+		net_eq(dev_net(dev), dev_net(adj_dev));
+}
 
 static int __netdev_adjacent_dev_insert(struct net_device *dev,
 					struct net_device *adj_dev,
@@ -5214,7 +5219,7 @@  static int __netdev_adjacent_dev_insert(struct net_device *dev,
 	pr_debug("dev_hold for %s, because of link added from %s to %s\n",
 		 adj_dev->name, dev->name, adj_dev->name);
 
-	if (netdev_adjacent_is_neigh_list(dev, dev_list)) {
+	if (netdev_adjacent_is_neigh_list(dev, adj_dev, dev_list)) {
 		ret = netdev_adjacent_sysfs_add(dev, adj_dev, dev_list);
 		if (ret)
 			goto free_adj;
@@ -5235,7 +5240,7 @@  static int __netdev_adjacent_dev_insert(struct net_device *dev,
 	return 0;
 
 remove_symlinks:
-	if (netdev_adjacent_is_neigh_list(dev, dev_list))
+	if (netdev_adjacent_is_neigh_list(dev, adj_dev, dev_list))
 		netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list);
 free_adj:
 	kfree(adj);
@@ -5267,8 +5272,7 @@  void __netdev_adjacent_dev_remove(struct net_device *dev,
 	if (adj->master)
 		sysfs_remove_link(&(dev->dev.kobj), "master");
 
-	if (netdev_adjacent_is_neigh_list(dev, dev_list) &&
-	    net_eq(dev_net(dev),dev_net(adj_dev)))
+	if (netdev_adjacent_is_neigh_list(dev, adj_dev, dev_list))
 		netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list);
 
 	list_del_rcu(&adj->list);