Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 220815a9 authored by Johannes Berg's avatar Johannes Berg Committed by David S. Miller
Browse files

genetlink: fix genlmsg_multicast() bug



Unfortunately, I introduced a tremendously stupid bug into
genlmsg_multicast() when doing all those multicast group
changes: it adjusts the group number, but then passes it
to genlmsg_multicast_netns() which does that again.

Somehow, my tests failed to catch this, so add a warning
into genlmsg_multicast_netns() and remove the offending
group ID adjustment.

Also add a warning to the similar code in other functions
so people who misuse them are more loudly warned.

Signed-off-by: default avatarJohannes Berg <johannes.berg@intel.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent e40526cb
Loading
Loading
Loading
Loading
+1 −4
Original line number Diff line number Diff line
@@ -265,7 +265,7 @@ static inline int genlmsg_multicast_netns(struct genl_family *family,
					  struct net *net, struct sk_buff *skb,
					  u32 portid, unsigned int group, gfp_t flags)
{
	if (group >= family->n_mcgrps)
	if (WARN_ON_ONCE(group >= family->n_mcgrps))
		return -EINVAL;
	group = family->mcgrp_offset + group;
	return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
@@ -283,9 +283,6 @@ static inline int genlmsg_multicast(struct genl_family *family,
				    struct sk_buff *skb, u32 portid,
				    unsigned int group, gfp_t flags)
{
	if (group >= family->n_mcgrps)
		return -EINVAL;
	group = family->mcgrp_offset + group;
	return genlmsg_multicast_netns(family, &init_net, skb,
				       portid, group, flags);
}
+2 −2
Original line number Diff line number Diff line
@@ -1045,7 +1045,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group,
int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb,
			    u32 portid, unsigned int group, gfp_t flags)
{
	if (group >= family->n_mcgrps)
	if (WARN_ON_ONCE(group >= family->n_mcgrps))
		return -EINVAL;
	group = family->mcgrp_offset + group;
	return genlmsg_mcast(skb, portid, group, flags);
@@ -1062,7 +1062,7 @@ void genl_notify(struct genl_family *family,
	if (nlh)
		report = nlmsg_report(nlh);

	if (group >= family->n_mcgrps)
	if (WARN_ON_ONCE(group >= family->n_mcgrps))
		return;
	group = family->mcgrp_offset + group;
	nlmsg_notify(sk, skb, portid, group, report, flags);