lists.openwall.net | lists / announce owl-users owl-dev john-users john-dev passwdqc-users yescrypt popa3d-users / oss-security kernel-hardening musl sabotage tlsify passwords / crypt-dev xvendor / Bugtraq Full-Disclosure linux-kernel linux-netdev linux-ext4 linux-hardening PHC | |
Open Source and information security mailing list archives
| ||
|
Date: Thu, 21 Aug 2014 17:29:41 +0200 From: Veaceslav Falico <vfalico@...hat.com> To: "Alexander Y. Fomichev" <git.user@...il.com> Cc: netdev@...r.kernel.org Subject: Re: Is it normal to have cross namespace symlinks? On Thu, Aug 21, 2014 at 07:13:16PM +0400, Alexander Y. Fomichev wrote: >On Thu, 21 Aug 2014 14:12:05 +0200 >Veaceslav Falico <vfalico@...hat.com> wrote: > >> On Thu, Aug 21, 2014 at 02:38:16PM +0400, Alexander Y. Fomichev wrote: >> >Hello guys! >> > >> >Recently i switched to 3.14.x stable branch and i've got a bunch of >> >warnings: >> > >> >[ 44.717746] ------------[ cut here ]------------ >> >[ 44.717750] WARNING: CPU: 1 PID: 7007 at fs/sysfs/dir.c:52 >> >sysfs_warn_dup+0x86/0xa0() [ 44.717751] sysfs: cannot create >> >duplicate filename >> >'/devices/pci0000:00/0000:00:1c.4/0000:05:00.0/net/eth1/upper_eth1' >> > >> >[ 37.759856] ------------[ cut here ]------------ >> >[ 37.759863] WARNING: CPU: 1 PID: 3822 at fs/sysfs/dir.c:52 >> >sysfs_warn_dup+0x86/0xa0() [ 37.759864] sysfs: cannot create >> >duplicate filename '/devices/virtual/net/bond0/upper_eth0' >> >.... >> > >> >It was triggered by renaming of macvlan interfaces in a freshly >> >created network namespaces. Just start two lxc containers one by one >> >with macvlans on the same lowerdev and rename devices inside >> >containers (with the same name) and voila. >> >v >> >I investigated problem a bit and i see that code in net/core/dev.c >> >which working with sysfs symlinks upper_dev / lower_dev is absolutely >> >unaware of namespaces. I mean code which uses functions >> >netdev_adjacent_sysfs_del,netdev_adjacent_sysfs_add >> >netdev_adjacent_rename_links,dev_change_name >> >just not takes into account that dev and adj_dev could be in a >> >different namespaces. >> >> That's indeed so. When I've implemented it, I indeed didn't take into >> account net_ns, my bad. >> >> Before the code, though, I'm not sure on how exactly to fix this. The >> only idea which comes to mind is to prohibit inter-net_ns symlinks >> (which can be done without much hassle) - i.e. to remove/add them on >> net_ns change, and to prohibit creating them on adding an inter-ns >> upper links. > >uh.. seems like this is a first and only what come to mind. At least i >have something similar in my local tree. Though it looks pretty ugly and >required two ad-hoc functions traversing both adj_list(s). Though >again it works as expected in both directions so i attached it just in >case. It doesn't really matter in this case, as adj_lists are small, and the renaming happens once per reboot. Anyway, feel free to post it. Even if it doesn't get accepted, it'll be a good starting point. > >> However, as I definitely lack experience using net_ns, maybe there are >> other, better way, to fix this? > >I can not say with confidence.. Someone of namespace guys better be >here. as far as i can see the most notable thing in this context, >netdev belongs to only one net_ns at any one time and a little sense to >have a symlink on non-existent device. Yep, agreed. Thank you! > >-- > >Best regards. > Alexander Y. Fomichev <Aleksandr.Fomichev@...ru> > +7-495-662-88-88 ext. 11346 >diff --git a/net/core/dev.c b/net/core/dev.c >index b65a505..683cedf 100644 >--- a/net/core/dev.c >+++ b/net/core/dev.c >@@ -4889,7 +4889,8 @@ static 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)) >+ if (netdev_adjacent_is_neigh_list(dev, dev_list) && >+ net_eq(dev_net(dev),dev_net(adj_dev))) > netdev_adjacent_sysfs_del(dev, adj_dev->name, dev_list); > > list_del_rcu(&adj->list); >@@ -5159,11 +5160,65 @@ void netdev_upper_dev_unlink(struct net_device *dev, > } > EXPORT_SYMBOL(netdev_upper_dev_unlink); > >+void netdev_adjacent_add_links(struct net_device *dev) >+{ >+ struct netdev_adjacent *iter; >+ >+ struct net *net = dev_net(dev); >+ >+ list_for_each_entry(iter, &dev->adj_list.upper, list) { >+ if (!net_eq(net,dev_net(iter->dev))) >+ continue; >+ netdev_adjacent_sysfs_add(iter->dev, dev, >+ &iter->dev->adj_list.lower); >+ netdev_adjacent_sysfs_add(dev, iter->dev, >+ &dev->adj_list.upper); >+ } >+ >+ list_for_each_entry(iter, &dev->adj_list.lower, list) { >+ if (!net_eq(net,dev_net(iter->dev))) >+ continue; >+ netdev_adjacent_sysfs_add(iter->dev, dev, >+ &iter->dev->adj_list.upper); >+ netdev_adjacent_sysfs_add(dev, iter->dev, >+ &dev->adj_list.lower); >+ } >+} >+ >+void netdev_adjacent_del_links(struct net_device *dev) >+{ >+ struct netdev_adjacent *iter; >+ >+ struct net *net = dev_net(dev); >+ >+ list_for_each_entry(iter, &dev->adj_list.upper, list) { >+ if (!net_eq(net,dev_net(iter->dev))) >+ continue; >+ netdev_adjacent_sysfs_del(iter->dev, dev->name, >+ &iter->dev->adj_list.lower); >+ netdev_adjacent_sysfs_del(dev, iter->dev->name, >+ &dev->adj_list.upper); >+ } >+ >+ list_for_each_entry(iter, &dev->adj_list.lower, list) { >+ if (!net_eq(net,dev_net(iter->dev))) >+ continue; >+ netdev_adjacent_sysfs_del(iter->dev, dev->name, >+ &iter->dev->adj_list.upper); >+ netdev_adjacent_sysfs_del(dev, iter->dev->name, >+ &dev->adj_list.lower); >+ } >+} >+ > void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) > { > struct netdev_adjacent *iter; > >+ struct net *net = dev_net(dev); >+ > list_for_each_entry(iter, &dev->adj_list.upper, list) { >+ if (!net_eq(net,dev_net(iter->dev))) >+ continue; > netdev_adjacent_sysfs_del(iter->dev, oldname, > &iter->dev->adj_list.lower); > netdev_adjacent_sysfs_add(iter->dev, dev, >@@ -5171,6 +5226,8 @@ void netdev_adjacent_rename_links(struct net_device *dev, char *oldname) > } > > list_for_each_entry(iter, &dev->adj_list.lower, list) { >+ if (!net_eq(net,dev_net(iter->dev))) >+ continue; > netdev_adjacent_sysfs_del(iter->dev, oldname, > &iter->dev->adj_list.upper); > netdev_adjacent_sysfs_add(iter->dev, dev, >@@ -6771,8 +6828,10 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char > dev_uc_flush(dev); > dev_mc_flush(dev); > >+ > /* Send a netdev-removed uevent to the old namespace */ > kobject_uevent(&dev->dev.kobj, KOBJ_REMOVE); >+ netdev_adjacent_del_links(dev); > > /* Actually switch the network namespace */ > dev_net_set(dev, net); >@@ -6787,6 +6846,7 @@ int dev_change_net_namespace(struct net_device *dev, struct net *net, const char > > /* Send a netdev-add uevent to the new namespace */ > kobject_uevent(&dev->dev.kobj, KOBJ_ADD); >+ netdev_adjacent_add_links(dev); > > /* Fixup kobjects */ > err = device_rename(&dev->dev, dev->name); -- To unsubscribe from this list: send the line "unsubscribe netdev" in the body of a message to majordomo@...r.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Powered by blists - more mailing lists