[Devel] [PATCH RH9 27/33] ve/netlink: allow IPVS netlink messages to CT init userns
Andrey Zhadchenko
andrey.zhadchenko at virtuozzo.com
Thu Sep 23 22:08:30 MSK 2021
From: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Docker swarm tries to setup IPVS via netlink, so let him do it.
It can be done through setsockopt as each IPVS_CMD_* had it's
IP_VS_SO_SET_* analogy.
https://jira.sw.ru/browse/PSBM-63883
Signed-off-by: Pavel Tikhomirov <ptikhomirov at virtuozzo.com>
Reviewed-by: Andrew Vagin <avagin at virtuozzo.com>
(cherry picked from vz8 commit 6d144c048eccb23985262222e94f8f22aad1cdc0)
Signed-off-by: Andrey Zhadchenko <andrey.zhadchenko at virtuozzo.com>
---
include/linux/netlink.h | 1 +
include/uapi/linux/genetlink.h | 1 +
net/netfilter/ipvs/ip_vs_ctl.c | 32 ++++++++++++++++----------------
net/netlink/af_netlink.c | 20 ++++++++++++++++++++
net/netlink/genetlink.c | 4 ++++
5 files changed, 42 insertions(+), 16 deletions(-)
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 61b1c7f..49b319d 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -271,6 +271,7 @@ bool __netlink_ns_capable(const struct netlink_skb_parms *nsp,
struct user_namespace *ns, int cap);
bool netlink_ns_capable(const struct sk_buff *skb,
struct user_namespace *ns, int cap);
+bool netlink_ve_capable(const struct sk_buff *skb, int cap);
bool netlink_capable(const struct sk_buff *skb, int cap);
bool netlink_net_capable(const struct sk_buff *skb, int cap);
diff --git a/include/uapi/linux/genetlink.h b/include/uapi/linux/genetlink.h
index d83f214..11b0967 100644
--- a/include/uapi/linux/genetlink.h
+++ b/include/uapi/linux/genetlink.h
@@ -23,6 +23,7 @@ struct genlmsghdr {
#define GENL_CMD_CAP_DUMP 0x04
#define GENL_CMD_CAP_HASPOL 0x08
#define GENL_UNS_ADMIN_PERM 0x10
+#define GENL_VE_ADMIN_PERM 0x80
/*
* List of reserved static generic netlink identifiers:
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index c250970..14e26a7 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -3897,98 +3897,98 @@ static int ip_vs_genl_get_cmd(struct sk_buff *skb, struct genl_info *info)
{
.cmd = IPVS_CMD_NEW_SERVICE,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_cmd,
},
{
.cmd = IPVS_CMD_SET_SERVICE,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_cmd,
},
{
.cmd = IPVS_CMD_DEL_SERVICE,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_cmd,
},
{
.cmd = IPVS_CMD_GET_SERVICE,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_get_cmd,
.dumpit = ip_vs_genl_dump_services,
},
{
.cmd = IPVS_CMD_NEW_DEST,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_cmd,
},
{
.cmd = IPVS_CMD_SET_DEST,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_cmd,
},
{
.cmd = IPVS_CMD_DEL_DEST,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_cmd,
},
{
.cmd = IPVS_CMD_GET_DEST,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.dumpit = ip_vs_genl_dump_dests,
},
{
.cmd = IPVS_CMD_NEW_DAEMON,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_daemon,
},
{
.cmd = IPVS_CMD_DEL_DAEMON,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_daemon,
},
{
.cmd = IPVS_CMD_GET_DAEMON,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.dumpit = ip_vs_genl_dump_daemons,
},
{
.cmd = IPVS_CMD_SET_CONFIG,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_cmd,
},
{
.cmd = IPVS_CMD_GET_CONFIG,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_get_cmd,
},
{
.cmd = IPVS_CMD_GET_INFO,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_get_cmd,
},
{
.cmd = IPVS_CMD_ZERO,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_cmd,
},
{
.cmd = IPVS_CMD_FLUSH,
.validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
- .flags = GENL_ADMIN_PERM,
+ .flags = GENL_VE_ADMIN_PERM,
.doit = ip_vs_genl_set_cmd,
},
};
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 380f95a..e8cece8 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -61,6 +61,7 @@
#include <linux/net_namespace.h>
#include <linux/nospec.h>
#include <linux/btf_ids.h>
+#include <linux/ve.h>
#include <net/net_namespace.h>
#include <net/netns/generic.h>
@@ -886,6 +887,25 @@ bool netlink_ns_capable(const struct sk_buff *skb,
}
EXPORT_SYMBOL(netlink_ns_capable);
+#ifdef CONFIG_VE
+bool netlink_ve_capable(const struct sk_buff *skb, int cap)
+{
+ struct cred *cred = get_exec_env()->init_cred;
+
+ if (cred == NULL) /* ve isn't running */
+ cred = ve0.init_cred;
+
+ return netlink_ns_capable(skb, cred->user_ns, cap);
+}
+#else
+bool netlink_ve_capable(const struct sk_buff *skb, int cap)
+{
+ return netlink_capable(skb, cap);
+}
+#endif
+
+EXPORT_SYMBOL(netlink_ve_capable);
+
/**
* netlink_capable - Netlink global message capability test
* @skb: socket buffer holding a netlink command from userspace
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 2d6fdf4..0449dcc 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -772,6 +772,10 @@ static int genl_family_rcv_msg(const struct genl_family *family,
!netlink_capable(skb, CAP_NET_ADMIN))
return -EPERM;
+ if ((op.flags & GENL_VE_ADMIN_PERM) &&
+ !netlink_ve_capable(skb, CAP_NET_ADMIN))
+ return -EPERM;
+
if ((op.flags & GENL_UNS_ADMIN_PERM) &&
!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN))
return -EPERM;
--
1.8.3.1
More information about the Devel
mailing list