[Devel] [PATCH RH9 5/7] ve/net: allow to rename devices in non-ve namespaces

Pavel Tikhomirov ptikhomirov at virtuozzo.com
Tue Oct 5 15:55:51 MSK 2021


From: Kirill Tkhai <ktkhai at odin.com>

Porting patch diff-ve-net-allow-to-rename-devices-in-non-ve-namespaces
from 2.6.32.

https://jira.sw.ru/browse/PSBM-29810
https://jira.sw.ru/browse/PSBM-33645

Signed-off-by: Andrew Vagin <avagin at openvz.org>
Signed-off-by: Kirill Tkhai <ktkhai at odin.com>
Signed-off-by: Dmitry Safonov <dsafonov at virtuozzo.com>
Signed-off-by: Stanislav Kinsburskiy <skinsbursky at virtuozzo.com>

+++
ve/net: don't use RCU read lock in ve_dev_can_rename()

rcu_read_lock()/unlock won't help here anyway:
"can" value can change right after rcu lock is dropped.

mFixes: 13bed5e31b7c ("ve/net: allow to rename devices in non-ve
namespaces")
https://jira.sw.ru/browse/PSBM-93640

Signed-off-by: Konstantin Khorenko <khorenko at virtuozzo.com>

vz9 changes:
- fix crash by checking ve->ve_ns is not zero and is not freed under us,
meaning that we still need RCU here, let's add ve_get_net_ns helper to access
ve netns right
- add proper CONFIG_VE ifdefs

(cherry picked from vz8 commit 0460650a21fa865b072bd672ff8f829921d30e54)
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
---
 include/linux/ve.h |  2 ++
 kernel/ve/ve.c     | 15 +++++++++++++++
 net/core/dev.c     | 22 ++++++++++++++++++++++
 3 files changed, 39 insertions(+)

diff --git a/include/linux/ve.h b/include/linux/ve.h
index 6e3975ed2cf6..c2bdadb487f1 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -189,6 +189,8 @@ extern int vz_security_protocol_check(struct net *net, int protocol);
 
 int ve_net_hide_sysctl(struct net *net);
 
+extern struct net *ve_get_net_ns(struct ve_struct* ve);
+
 #else	/* CONFIG_VE */
 #define get_ve(ve)	(NULL)
 #define put_ve(ve)	do { } while (0)
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index 21eec9973a9a..1adb875dffc9 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -25,6 +25,7 @@
 #include <linux/nsproxy.h>
 #include <linux/fs_struct.h>
 #include <linux/time_namespace.h>
+#include <net/net_namespace.h>
 #include <linux/genhd.h>
 
 #include <uapi/linux/vzcalluser.h>
@@ -243,6 +244,20 @@ int ve_net_hide_sysctl(struct net *net)
 }
 EXPORT_SYMBOL(ve_net_hide_sysctl);
 
+struct net *ve_get_net_ns(struct ve_struct* ve)
+{
+	struct nsproxy *ve_ns;
+	struct net *net_ns;
+
+	rcu_read_lock();
+	ve_ns = rcu_dereference(ve->ve_ns);
+	net_ns = ve_ns ? get_net(ve_ns->net_ns) : NULL;
+	rcu_read_unlock();
+
+	return net_ns;
+}
+EXPORT_SYMBOL(ve_get_net_ns);
+
 int nr_threads_ve(struct ve_struct *ve)
 {
         return cgroup_task_count(ve->css.cgroup);
diff --git a/net/core/dev.c b/net/core/dev.c
index e66ccebe190a..d257a67adb88 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1324,6 +1324,20 @@ static int dev_get_valid_name(struct net *net, struct net_device *dev,
 	return 0;
 }
 
+#ifdef CONFIG_VE
+static bool ve_dev_can_rename(struct net_device *dev)
+{
+	struct net *net;
+	bool can;
+
+	net = ve_get_net_ns(dev_net(dev)->owner_ve);
+	can = !net || net == dev_net(dev);
+	if (net)
+		put_net(net);
+	return can;
+}
+#endif
+
 /**
  *	dev_change_name - change name of a device
  *	@dev: device
@@ -1383,6 +1397,11 @@ int dev_change_name(struct net_device *dev, const char *newname)
 	dev->name_assign_type = NET_NAME_RENAMED;
 
 rollback:
+#ifdef CONFIG_VE
+	if (!ve_dev_can_rename(dev))
+		goto skip_rename;
+#endif
+
 	ret = device_rename(&dev->dev, dev->name);
 	if (ret) {
 		memcpy(dev->name, oldname, IFNAMSIZ);
@@ -1391,6 +1410,9 @@ int dev_change_name(struct net_device *dev, const char *newname)
 		return ret;
 	}
 
+#ifdef CONFIG_VE
+skip_rename:
+#endif
 	up_write(&devnet_rename_sem);
 
 	netdev_adjacent_rename_links(dev, oldname);
-- 
2.31.1



More information about the Devel mailing list