genetlink: add CAP_NET_ADMIN test for multicast bind
This is a partial backport of upstream commit 4d54cc32112d ("mptcp: avoid lock_fast usage in accept path"). It is only a partial backport because the patch in the link below was erroneously squash-merged into upstream commit 4d54cc32112d ("mptcp: avoid lock_fast usage in accept path"). Below is the original patch description from Florian Westphal: " genetlink sets NL_CFG_F_NONROOT_RECV for its netlink socket so anyone can subscribe to multicast messages. rtnetlink doesn't allow this unconditionally, rtnetlink_bind() restricts bind requests to CAP_NET_ADMIN for a few groups. This allows to set GENL_UNS_ADMIN_PERM flag on genl mcast groups to mandate CAP_NET_ADMIN. This will be used by the upcoming mptcp netlink event facility which exposes the token (mptcp connection identifier) to userspace. " Link: https://lore.kernel.org/mptcp/20210213000001.379332-8-mathew.j.martineau@linux.intel.com/ Signed-off-by: Ido Schimmel <idosch@nvidia.com> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
parent
aa26899dd9
commit
284c1d76dd
2 changed files with 33 additions and 0 deletions
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
struct genl_multicast_group {
|
||||
char name[GENL_NAMSIZ];
|
||||
u8 flags;
|
||||
};
|
||||
|
||||
struct genl_ops;
|
||||
|
|
|
@ -1364,11 +1364,43 @@ static struct genl_family genl_ctrl __ro_after_init = {
|
|||
.netnsok = true,
|
||||
};
|
||||
|
||||
static int genl_bind(struct net *net, int group)
|
||||
{
|
||||
const struct genl_family *family;
|
||||
unsigned int id;
|
||||
int ret = 0;
|
||||
|
||||
genl_lock_all();
|
||||
|
||||
idr_for_each_entry(&genl_fam_idr, family, id) {
|
||||
const struct genl_multicast_group *grp;
|
||||
int i;
|
||||
|
||||
if (family->n_mcgrps == 0)
|
||||
continue;
|
||||
|
||||
i = group - family->mcgrp_offset;
|
||||
if (i < 0 || i >= family->n_mcgrps)
|
||||
continue;
|
||||
|
||||
grp = &family->mcgrps[i];
|
||||
if ((grp->flags & GENL_UNS_ADMIN_PERM) &&
|
||||
!ns_capable(net->user_ns, CAP_NET_ADMIN))
|
||||
ret = -EPERM;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
genl_unlock_all();
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int __net_init genl_pernet_init(struct net *net)
|
||||
{
|
||||
struct netlink_kernel_cfg cfg = {
|
||||
.input = genl_rcv,
|
||||
.flags = NL_CFG_F_NONROOT_RECV,
|
||||
.bind = genl_bind,
|
||||
};
|
||||
|
||||
/* we'll bump the group number right afterwards */
|
||||
|
|
Loading…
Reference in a new issue