genetlink: Use internal flags for multicast groups
As explained in commite03781879a
("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 commit44ec98ea5e
("psample: Require 'CAP_NET_ADMIN' when joining "packets" group") and commite03781879a
("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>
This commit is contained in:
parent
f732ba4ac9
commit
cd4d7263d5
|
@ -8,16 +8,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
|
||||
* @flags: GENL_* flags (%GENL_ADMIN_PERM or %GENL_UNS_ADMIN_PERM)
|
||||
* @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_split_ops;
|
||||
|
|
|
@ -183,7 +183,7 @@ out:
|
|||
}
|
||||
|
||||
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)
|
||||
|
|
|
@ -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[] = {
|
||||
[MPTCP_PM_CMD_GRP_OFFSET] = { .name = MPTCP_PM_CMD_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)
|
|||
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;
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@ 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,
|
||||
.flags = GENL_UNS_ADMIN_PERM },
|
||||
.flags = GENL_MCAST_CAP_NET_ADMIN, },
|
||||
};
|
||||
|
||||
static struct genl_family psample_nl_family __ro_after_init;
|
||||
|
|
Loading…
Reference in New Issue