[Devel] [PATCH 13/13] ve/netlink: allow messages with family PF_BRIDGE type RTM_xxxNEIGH in CT

Alexander Mikhalitsyn alexander.mikhalitsyn at virtuozzo.com
Tue May 18 20:54:27 MSK 2021


From: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>

While reproducing the problem mentioned in patch 1 I found that
we need it to be able to configure vxlan fdb (Forwarding Database entry).

https://jira.sw.ru/browse/PSBM-53629

Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Acked-by: Andrei Vagin <avagin at virtuozzo.com>
(cherry picked from commit da2b4bd3e7a5df3c9ed79b1d1cedbd4513651c21)

To_merge: 1f4a13e2a1d3 ("ve/net: introduce vz_security_*_check checks")

VZ 8 rebase part https://jira.sw.ru/browse/PSBM-127783

Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn at virtuozzo.com>
---
 include/linux/ve.h   |  4 +-
 kernel/ve/ve.c       | 98 ++++++++++++++++++++++++--------------------
 net/core/rtnetlink.c |  4 +-
 net/socket.c         |  2 +-
 4 files changed, 58 insertions(+), 50 deletions(-)

diff --git a/include/linux/ve.h b/include/linux/ve.h
index a0a81fc9c428..9c553ac96072 100644
--- a/include/linux/ve.h
+++ b/include/linux/ve.h
@@ -214,7 +214,7 @@ extern struct cgroup *cgroup_get_ve_root1(struct cgroup *cgrp);
 
 #define ve_uevent_seqnum       (get_exec_env()->_uevent_seqnum)
 
-extern int vz_security_family_check(struct net *net, int family);
+extern int vz_security_family_check(struct net *net, int family, int type);
 extern int vz_security_protocol_check(struct net *net, int protocol);
 
 int ve_net_hide_sysctl(struct net *net);
@@ -244,7 +244,7 @@ static inline struct cgroup *cgroup_get_ve_root1(struct cgroup *cgrp)
 }
 #define ve_uevent_seqnum uevent_seqnum
 
-static inline int vz_security_family_check(struct net *net, int family) { return 0; }
+static inline int vz_security_family_check(struct net *net, int family, int type) { return 0; }
 static inline int vz_security_protocol_check(struct net *net, int protocol) { return 0; }
 
 static inline void monotonic_abs_to_ve(clockid_t which_clock,
diff --git a/kernel/ve/ve.c b/kernel/ve/ve.c
index f164e2d426a6..c7f4cd2a377a 100644
--- a/kernel/ve/ve.c
+++ b/kernel/ve/ve.c
@@ -26,6 +26,7 @@
 #include <linux/nsproxy.h>
 #include <linux/fs_struct.h>
 #include <uapi/linux/vzcalluser.h>
+#include <net/rtnetlink.h>
 
 #include "../cgroup/cgroup-internal.h" /* For cgroup_task_count() */
 
@@ -165,6 +166,58 @@ struct ve_struct *get_ve_by_id(envid_t veid)
 }
 EXPORT_SYMBOL(get_ve_by_id);
 
+int vz_security_family_check(struct net *net, int family, int type)
+{
+	if (ve_is_super(net->owner_ve))
+		return 0;
+
+	switch (family) {
+	case PF_UNSPEC:
+	case PF_PACKET:
+	case PF_NETLINK:
+	case PF_UNIX:
+	case PF_INET:
+	case PF_INET6:
+	case PF_PPPOX:
+	case PF_KEY:
+		return 0;
+	case PF_BRIDGE:
+		if (type)
+			switch (type) {
+				case RTM_NEWNEIGH:
+				case RTM_DELNEIGH:
+				case RTM_GETNEIGH:
+					return 0;
+			}
+	default:
+		return -EAFNOSUPPORT;
+	}
+}
+EXPORT_SYMBOL_GPL(vz_security_family_check);
+
+int vz_security_protocol_check(struct net *net, int protocol)
+{
+	if (ve_is_super(net->owner_ve))
+		return 0;
+
+	switch (protocol) {
+	case  IPPROTO_IP:
+	case  IPPROTO_ICMP:
+	case  IPPROTO_TCP:
+	case  IPPROTO_UDP:
+	case  IPPROTO_RAW:
+	case  IPPROTO_DCCP:
+	case  IPPROTO_GRE:
+	case  IPPROTO_ESP:
+	case  IPPROTO_AH:
+	case  IPPROTO_SCTP:
+		return 0;
+	default:
+		return -EAFNOSUPPORT;
+	}
+}
+EXPORT_SYMBOL_GPL(vz_security_protocol_check);
+
 /* Check if current user_ns is initial for current ve */
 bool current_user_ns_initial(void)
 {
@@ -1599,51 +1652,6 @@ static int __init ve_subsys_init(void)
 }
 late_initcall(ve_subsys_init);
 
-int vz_security_family_check(struct net *net, int family)
-{
-	if (ve_is_super(net->owner_ve))
-		return 0;
-
-	switch (family) {
-	case PF_UNSPEC:
-	case PF_PACKET:
-	case PF_NETLINK:
-	case PF_UNIX:
-	case PF_INET:
-	case PF_INET6:
-	case PF_PPPOX:
-	case PF_KEY:
-		return 0;
-	default:
-		return -EAFNOSUPPORT;
-	}
-}
-EXPORT_SYMBOL_GPL(vz_security_family_check);
-
-int vz_security_protocol_check(struct net *net, int protocol)
-{
-	if (ve_is_super(net->owner_ve))
-		return 0;
-
-	switch (protocol) {
-	case  IPPROTO_IP:
-	case  IPPROTO_ICMP:
-	case  IPPROTO_ICMPV6:
-	case  IPPROTO_TCP:
-	case  IPPROTO_UDP:
-	case  IPPROTO_RAW:
-	case  IPPROTO_DCCP:
-	case  IPPROTO_GRE:
-	case  IPPROTO_ESP:
-	case  IPPROTO_AH:
-	case  IPPROTO_SCTP:
-		return 0;
-	default:
-		return -EPROTONOSUPPORT;
-	}
-}
-EXPORT_SYMBOL_GPL(vz_security_protocol_check);
-
 #ifdef CONFIG_CGROUP_SCHED
 int cpu_cgroup_proc_stat(struct cgroup_subsys_state *cpu_css,
 			 struct cgroup_subsys_state *cpuacct_css,
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 7d153d6fe8d5..8cbe678b4dbb 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -3524,7 +3524,7 @@ static int rtnl_dump_all(struct sk_buff *skb, struct netlink_callback *cb)
 		if (!dumpit)
 			continue;
 
-		if (vz_security_family_check(net, idx))
+		if (vz_security_family_check(net, idx, cb->nlh->nlmsg_type))
 			continue;
 
 		if (idx > s_idx) {
@@ -5234,7 +5234,7 @@ static int rtnetlink_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh,
 
 	family = ((struct rtgenmsg *)nlmsg_data(nlh))->rtgen_family;
 
-	if (vz_security_family_check(net, family))
+	if (vz_security_family_check(net, family, nlh->nlmsg_type))
 		return -EAFNOSUPPORT;
 
 	kind = type&3;
diff --git a/net/socket.c b/net/socket.c
index 577cd4e1feb3..fcd82cf86c0c 100644
--- a/net/socket.c
+++ b/net/socket.c
@@ -1350,7 +1350,7 @@ int __sock_create(struct net *net, int family, int type, int protocol,
 	}
 
 	/* VZ compatibility layer */
-	err = vz_security_family_check(net, family);
+	err = vz_security_family_check(net, family, 0);
 	if (err < 0)
 		return err;
 
-- 
2.28.0



More information about the Devel mailing list