The commit is pushed to "branch-rh9-5.14.vz9.1.x-ovz" and will appear at https://src.openvz.org/scm/ovz/vzkernel.git after ark-5.14 ------> commit 33ca56eeb5e4ef23fe26dce16b79906a8c55a4c7 Author: Pavel Tikhomirov <ptikhomi...@virtuozzo.com> Date: Fri Sep 24 15:48:50 2021 +0300
ve/netlink: allow IPVS netlink messages to CT init userns 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 <ptikhomi...@virtuozzo.com> Reviewed-by: Andrew Vagin <ava...@virtuozzo.com> (cherry picked from vz8 commit 6d144c048eccb23985262222e94f8f22aad1cdc0) Signed-off-by: Andrey Zhadchenko <andrey.zhadche...@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 61b1c7fcc401..49b319dff9b4 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 d83f214b4134..11b09675d62c 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 c25097092a06..14e26a7e55c5 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -3897,98 +3897,98 @@ static const struct genl_small_ops ip_vs_genl_ops[] = { { .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 380f95aacdec..e8cece873e06 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 2d6fdf40df66..0449dcc54a64 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; _______________________________________________ Devel mailing list Devel@openvz.org https://lists.openvz.org/mailman/listinfo/devel