From: Ido Schimmel idosch@nvidia.com
mainline inclusion from mainline-v6.8-rc1 commit cd4d7263d58ab98fd4dee876776e4da6c328faa3 category: bugfix bugzilla: https://gitee.com/openeuler/kernel/issues/I9K8D1
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
------------------------------------------------------
As explained in commit e03781879a0d ("drop_monitor: Require 'CAP_SYS_ADMIN' when joining "events" group"), the "flags" field in the multicast group structure reuses uAPI flags despite the field not being exposed to user space. This makes it impossible to extend its use without adding new uAPI flags, which is inappropriate for internal kernel checks.
Solve this by adding internal flags (i.e., "GENL_MCAST_*") and convert the existing users to use them instead of the uAPI flags.
Tested using the reproducers in commit 44ec98ea5ea9 ("psample: Require 'CAP_NET_ADMIN' when joining "packets" group") and commit e03781879a0d ("drop_monitor: Require 'CAP_SYS_ADMIN' when joining "events" group").
No functional changes intended.
Signed-off-by: Ido Schimmel idosch@nvidia.com Reviewed-by: Mat Martineau martineau@kernel.org Reviewed-by: Andy Shevchenko andriy.shevchenko@linux.intel.com Signed-off-by: David S. Miller davem@davemloft.net
Conflicts: include/net/genetlink.h net/psample/psample.c
Signed-off-by: Zhengchao Shao shaozhengchao@huawei.com --- include/net/genetlink.h | 8 ++++++-- net/core/drop_monitor.c | 2 +- net/netlink/genetlink.c | 4 ++-- net/psample/psample.c | 3 ++- 4 files changed, 11 insertions(+), 6 deletions(-)
diff --git a/include/net/genetlink.h b/include/net/genetlink.h index 9c3f613da881..ce3e670a7458 100644 --- a/include/net/genetlink.h +++ b/include/net/genetlink.h @@ -9,15 +9,19 @@
#define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN)
+/* Binding to multicast group requires %CAP_NET_ADMIN */ +#define GENL_MCAST_CAP_NET_ADMIN BIT(0) +/* Binding to multicast group requires %CAP_SYS_ADMIN */ +#define GENL_MCAST_CAP_SYS_ADMIN BIT(1) + /** * struct genl_multicast_group - generic netlink multicast group * @name: name of the multicast group, names are per-family - * @cap_sys_admin: whether %CAP_SYS_ADMIN is required for binding + * @flags: GENL_MCAST_* flags */ struct genl_multicast_group { char name[GENL_NAMSIZ]; u8 flags; - u8 cap_sys_admin:1; };
struct genl_ops; diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 7742ee689141..8bdebb4e15f4 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -183,7 +183,7 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) }
static const struct genl_multicast_group dropmon_mcgrps[] = { - { .name = "events", .cap_sys_admin = 1 }, + { .name = "events", .flags = GENL_MCAST_CAP_SYS_ADMIN, }, };
static void send_dm_alert(struct work_struct *work) diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c index e9035de65546..508c954a3747 100644 --- a/net/netlink/genetlink.c +++ b/net/netlink/genetlink.c @@ -1384,10 +1384,10 @@ static int genl_bind(struct net *net, int group) continue;
grp = &family->mcgrps[i]; - if ((grp->flags & GENL_UNS_ADMIN_PERM) && + if ((grp->flags & GENL_MCAST_CAP_NET_ADMIN) && !ns_capable(net->user_ns, CAP_NET_ADMIN)) ret = -EPERM; - if (grp->cap_sys_admin && + if ((grp->flags & GENL_MCAST_CAP_SYS_ADMIN) && !ns_capable(net->user_ns, CAP_SYS_ADMIN)) ret = -EPERM;
diff --git a/net/psample/psample.c b/net/psample/psample.c index 482c07f2766b..8fa4aad44737 100644 --- a/net/psample/psample.c +++ b/net/psample/psample.c @@ -30,7 +30,8 @@ enum psample_nl_multicast_groups {
static const struct genl_multicast_group psample_nl_mcgrps[] = { [PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME }, - [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME }, + [PSAMPLE_NL_MCGRP_SAMPLE] = { .name = PSAMPLE_NL_MCGRP_SAMPLE_NAME, + .flags = GENL_MCAST_CAP_NET_ADMIN,}, };
static struct genl_family psample_nl_family __ro_after_init;