Commit cd4d7263 authored by Ido Schimmel's avatar Ido Schimmel Committed by David S. Miller

genetlink: Use internal flags for multicast groups

As explained in commit e0378187 ("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 44ec98ea ("psample: Require
'CAP_NET_ADMIN' when joining "packets" group") and commit e0378187
("drop_monitor: Require 'CAP_SYS_ADMIN' when joining "events" group").

No functional changes intended.
Signed-off-by: default avatarIdo Schimmel <idosch@nvidia.com>
Reviewed-by: default avatarMat Martineau <martineau@kernel.org>
Reviewed-by: default avatarAndy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent f732ba4a
...@@ -8,16 +8,19 @@ ...@@ -8,16 +8,19 @@
#define GENLMSG_DEFAULT_SIZE (NLMSG_DEFAULT_SIZE - GENL_HDRLEN) #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 * struct genl_multicast_group - generic netlink multicast group
* @name: name of the multicast group, names are per-family * @name: name of the multicast group, names are per-family
* @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM) * @flags: GENL_MCAST_* flags
* @cap_sys_admin: whether %CAP_SYS_ADMIN is required for binding
*/ */
struct genl_multicast_group { struct genl_multicast_group {
char name[GENL_NAMSIZ]; char name[GENL_NAMSIZ];
u8 flags; u8 flags;
u8 cap_sys_admin:1;
}; };
struct genl_split_ops; struct genl_split_ops;
......
...@@ -183,7 +183,7 @@ static struct sk_buff *reset_per_cpu_data(struct per_cpu_dm_data *data) ...@@ -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[] = { 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) static void send_dm_alert(struct work_struct *work)
......
...@@ -1100,7 +1100,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc ...@@ -1100,7 +1100,7 @@ int mptcp_pm_nl_get_local_id(struct mptcp_sock *msk, struct mptcp_addr_info *skc
static const struct genl_multicast_group mptcp_pm_mcgrps[] = { static const struct genl_multicast_group mptcp_pm_mcgrps[] = {
[MPTCP_PM_CMD_GRP_OFFSET] = { .name = MPTCP_PM_CMD_GRP_NAME, }, [MPTCP_PM_CMD_GRP_OFFSET] = { .name = MPTCP_PM_CMD_GRP_NAME, },
[MPTCP_PM_EV_GRP_OFFSET] = { .name = MPTCP_PM_EV_GRP_NAME, [MPTCP_PM_EV_GRP_OFFSET] = { .name = MPTCP_PM_EV_GRP_NAME,
.flags = GENL_UNS_ADMIN_PERM, .flags = GENL_MCAST_CAP_NET_ADMIN,
}, },
}; };
......
...@@ -1829,10 +1829,10 @@ static int genl_bind(struct net *net, int group) ...@@ -1829,10 +1829,10 @@ static int genl_bind(struct net *net, int group)
continue; continue;
grp = &family->mcgrps[i]; 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)) !ns_capable(net->user_ns, CAP_NET_ADMIN))
ret = -EPERM; ret = -EPERM;
if (grp->cap_sys_admin && if ((grp->flags & GENL_MCAST_CAP_SYS_ADMIN) &&
!ns_capable(net->user_ns, CAP_SYS_ADMIN)) !ns_capable(net->user_ns, CAP_SYS_ADMIN))
ret = -EPERM; ret = -EPERM;
......
...@@ -32,7 +32,7 @@ enum psample_nl_multicast_groups { ...@@ -32,7 +32,7 @@ enum psample_nl_multicast_groups {
static const struct genl_multicast_group psample_nl_mcgrps[] = { static const struct genl_multicast_group psample_nl_mcgrps[] = {
[PSAMPLE_NL_MCGRP_CONFIG] = { .name = PSAMPLE_NL_MCGRP_CONFIG_NAME }, [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_UNS_ADMIN_PERM }, .flags = GENL_MCAST_CAP_NET_ADMIN, },
}; };
static struct genl_family psample_nl_family __ro_after_init; static struct genl_family psample_nl_family __ro_after_init;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment