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

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
...@@ -265,7 +265,7 @@ static inline int genlmsg_multicast_netns(struct genl_family *family, ...@@ -265,7 +265,7 @@ static inline int genlmsg_multicast_netns(struct genl_family *family,
struct net *net, struct sk_buff *skb, struct net *net, struct sk_buff *skb,
u32 portid, unsigned int group, gfp_t flags) u32 portid, unsigned int group, gfp_t flags)
{ {
if (group >= family->n_mcgrps) if (WARN_ON_ONCE(group >= family->n_mcgrps))
return -EINVAL; return -EINVAL;
group = family->mcgrp_offset + group; group = family->mcgrp_offset + group;
return nlmsg_multicast(net->genl_sock, skb, portid, group, flags); return nlmsg_multicast(net->genl_sock, skb, portid, group, flags);
...@@ -283,9 +283,6 @@ static inline int genlmsg_multicast(struct genl_family *family, ...@@ -283,9 +283,6 @@ static inline int genlmsg_multicast(struct genl_family *family,
struct sk_buff *skb, u32 portid, struct sk_buff *skb, u32 portid,
unsigned int group, gfp_t flags) 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, return genlmsg_multicast_netns(family, &init_net, skb,
portid, group, flags); portid, group, flags);
} }
......
...@@ -1045,7 +1045,7 @@ static int genlmsg_mcast(struct sk_buff *skb, u32 portid, unsigned long group, ...@@ -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, int genlmsg_multicast_allns(struct genl_family *family, struct sk_buff *skb,
u32 portid, unsigned int group, gfp_t flags) u32 portid, unsigned int group, gfp_t flags)
{ {
if (group >= family->n_mcgrps) if (WARN_ON_ONCE(group >= family->n_mcgrps))
return -EINVAL; return -EINVAL;
group = family->mcgrp_offset + group; group = family->mcgrp_offset + group;
return genlmsg_mcast(skb, portid, group, flags); return genlmsg_mcast(skb, portid, group, flags);
...@@ -1062,7 +1062,7 @@ void genl_notify(struct genl_family *family, ...@@ -1062,7 +1062,7 @@ void genl_notify(struct genl_family *family,
if (nlh) if (nlh)
report = nlmsg_report(nlh); report = nlmsg_report(nlh);
if (group >= family->n_mcgrps) if (WARN_ON_ONCE(group >= family->n_mcgrps))
return; return;
group = family->mcgrp_offset + group; group = family->mcgrp_offset + group;
nlmsg_notify(sk, skb, portid, group, report, flags); nlmsg_notify(sk, skb, portid, group, report, flags);
......
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