Skip to content

Commit 17637d8

Browse files
committed
genetlink: free the skb on 'group >= family->n_mcgrps'
These methods generally consume ownership of the provided skb, so even if an error path is encountered, the skb is freed. This is because the very first thing they do after some initial setup is to unconditionally consume the skb via consume_skb(skb). Any subsequent errors lead to the core netlink layer freeing the skb. However, there is one check that occurs before ownership is passed, which is the check for the group index. So if this error condition is encountered, then the skb is leaked. This error condition is generally considered a violation of the netlink API, so it's not expected to occur under normal circumstances. For the same reason, no callers check for this error condition, and no callers need to be adjusted. However, we should still follow the same ownership semantics of the rest of the function. Thus, free the skb in this codepath. Assisted-by: Antigravity:gemini Suggested-by: Andrew Lunn <[email protected]> Suggested-by: Matthew Maurer <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Alice Ryhl <[email protected]>
1 parent 3293723 commit 17637d8

2 files changed

Lines changed: 9 additions & 3 deletions

File tree

include/net/genetlink.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -489,8 +489,10 @@ genlmsg_multicast_netns_filtered(const struct genl_family *family,
489489
netlink_filter_fn filter,
490490
void *filter_data)
491491
{
492-
if (WARN_ON_ONCE(group >= family->n_mcgrps))
492+
if (WARN_ON_ONCE(group >= family->n_mcgrps)) {
493+
nlmsg_free(skb);
493494
return -EINVAL;
495+
}
494496
group = family->mcgrp_offset + group;
495497
return nlmsg_multicast_filtered(net->genl_sock, skb, portid, group,
496498
flags, filter, filter_data);

net/netlink/genetlink.c

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,8 +1972,10 @@ int genlmsg_multicast_allns(const struct genl_family *family,
19721972
struct sk_buff *skb, u32 portid,
19731973
unsigned int group)
19741974
{
1975-
if (WARN_ON_ONCE(group >= family->n_mcgrps))
1975+
if (WARN_ON_ONCE(group >= family->n_mcgrps)) {
1976+
kfree_skb(skb);
19761977
return -EINVAL;
1978+
}
19771979

19781980
group = family->mcgrp_offset + group;
19791981
return genlmsg_mcast(skb, portid, group);
@@ -1986,8 +1988,10 @@ void genl_notify(const struct genl_family *family, struct sk_buff *skb,
19861988
struct net *net = genl_info_net(info);
19871989
struct sock *sk = net->genl_sock;
19881990

1989-
if (WARN_ON_ONCE(group >= family->n_mcgrps))
1991+
if (WARN_ON_ONCE(group >= family->n_mcgrps)) {
1992+
kfree_skb(skb);
19901993
return;
1994+
}
19911995

19921996
group = family->mcgrp_offset + group;
19931997
nlmsg_notify(sk, skb, info->snd_portid, group,

0 commit comments

Comments
 (0)