mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: netdev-bot+sashiko@kernel.org
To: anilkaushikwireless@gmail.com
Cc: netdev@vger.kernel.org, davem@davemloft.net, edumazet@kernel.org,
	kuba@kernel.org, pabeni@redhat.com, horms@kernel.org,
	idosch@nvidia.com, nicolas.dichtel@6wind.com,
	jacob.e.keller@intel.com, jiri@resnulli.us, fw@strlen.de,
	martineau@kernel.org, v3rdant.xiang@gmail.com,
	aliceryhl@google.com, linux-kernel@vger.kernel.org
Subject: Re: [PATCH net v4 1/2] genetlink: Reject joining multicast groups no family owns
Date: Tue, 03 Nov 2026 16:00:42 +0000	[thread overview]
Message-ID: <179372164269.488856.17448970060747076034@kernel.org> (raw)
In-Reply-To: <20261102155819.4100930-2-anilkaushikwireless@gmail.com>

Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.

Critical: 0 · High: 0 · Medium: 1 (1) · Low: 0

If you believe none of the issues are legitimate, please reply to each
issue of Medium severity or higher and explain why the AI is wrong.
If any of them are legitimate and you plan to respin, please let patchwork
know by including "pw-bot: cr" as a separate line at the end of your reply
(one such reply per series is enough).

- [Medium] In net/netlink/af_netlink.c, netlink_bind() lets one failing
  group abort the whole bind().

Pre-existing issues:
- [Medium] Kept only because requires_validation=true.

--

genetlink: Reject joining multicast groups no family owns

genl_bind() now returns -ENOENT when no registered family owns the
requested multicast group ID. Before this change such joins succeeded.
The socket also stayed a member if a family with privileged-only groups
later got the same ID.

Link: https://lore.kernel.org/netdev/179324692107.3134.14443689892607921337@kernel.org/

> diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
> index 5cc1037d4917e..f038f04ef4ead 100644
> --- a/net/netlink/genetlink.c
> +++ b/net/netlink/genetlink.c
> @@ -1825,7 +1825,7 @@ static int genl_bind(struct net *net, int group)
>  {
>  	const struct genl_family *family;
>  	unsigned int id;
> -	int ret = 0;
> +	int ret = -ENOENT;

[Severity: Medium]
Can a bind() with an nl_groups mask now fail as a whole when only one
bit in the mask has no owner?

netlink_bind() in net/netlink/af_netlink.c calls the bind hook once for
each set bit. On the first error it undoes the groups it already added
and returns:

net/netlink/af_netlink.c:netlink_bind() {
    ...
		for (group = 0; group < BITS_PER_TYPE(u32); group++) {
			if (!test_bit(group, &groups))
				continue;
			err = nlk->netlink_bind(net, group + 1);
			if (!err)
				continue;
			netlink_undo_bind(group, groups, sk);
			return err;
		}
    ...
}

Generic netlink group IDs are sparse. mc_group_start reserves only a few
bits:

static unsigned long mc_group_start = 0x3 | BIT(GENL_ID_CTRL) |
				      BIT(GENL_ID_VFS_DQUOT) |
				      BIT(GENL_ID_PMCRAID);

Other IDs are given out only when a family registers. So on a typical
system most IDs in 1..32 have no owner. genl's nlk->ngroups is at least
32, so the masking at the top of netlink_bind() does not remove these
bits.

Before this patch, a bind() on a NETLINK_GENERIC socket with a mask that
mixed owned and unowned IDs (for example nl_groups = ~0) returned 0 and
joined the owned groups.

With this patch, will that call return -ENOENT and join none of the
requested groups, including the valid owned ones?

The netlink core also still treats every ID below ngroups as valid in
netlink_setsockopt():

		if (!val || val - 1 >= nlk->ngroups)
			return -EINVAL;

genl_bind() now rejects many of those IDs, so the two layers disagree.

The commit message argues that joining an unowned group has no use, and
its test counts single-group joins. It does not mention the bind() mask
case.

The later commit "netlink: Check a group again if it was released while
joining it" keeps both the -ENOENT return and the all-or-nothing loop.
So this behaviour change is still there at the end of the series.

Should the bind() mask path skip unowned IDs instead of failing? If not,
should the commit message mention this uAPI change?

[ ... ]

> @@ -1841,6 +1841,7 @@ static int genl_bind(struct net *net, int group)
>  			continue;
>  
>  		grp = &family->mcgrps[i];
> +		ret = 0;
>  		if ((grp->flags & GENL_MCAST_CAP_NET_ADMIN) &&
>  		    !ns_capable(net->user_ns, CAP_NET_ADMIN))
>  			ret = -EPERM;

[Severity: Medium]
This isn't a bug introduced by this patch, but is there still a window
where a socket can become a member of a group ID that was just freed?

genl_bind() checks ownership and the CAP flags under down_read(&cb_lock).
It drops cb_lock before returning. The caller adds the membership later,
under netlink_table_grab():

net/netlink/af_netlink.c:netlink_setsockopt() {
    ...
		if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) {
			err = nlk->netlink_bind(sock_net(sk), val);
			if (err)
				return err;
		}
		netlink_table_grab();
		netlink_update_socket_mc(nlk, val,
					 optname == NETLINK_ADD_MEMBERSHIP);
    ...
}

netlink_bind() splits the check and the update in the same way for the
nl_groups mask.

Suppose genl_unregister_family() runs in that gap:

CPU1                                  CPU2
setsockopt(NETLINK_ADD_MEMBERSHIP)
  genl_bind() returns 0
  (cb_lock dropped)
                                      genl_unregister_family()
                                        genl_unregister_mc_groups()
                                          __netlink_clear_multicast_users()
                                          clear_bit(grp_id, mc_groups)
  netlink_table_grab()
  netlink_update_socket_mc()

__netlink_clear_multicast_users() clears only the sockets that are
members at that moment.

Would the socket on CPU1 then be added to the now-free ID?

A family registered later could get that ID, including one whose groups
have GENL_MCAST_CAP_NET_ADMIN or GENL_MCAST_CAP_SYS_ADMIN. It would then
deliver to the socket through do_one_broadcast(), and nothing checks the
membership again.

The commit message says:

  "A family registered later can get that ID, and the socket stays a
  member: nothing checks it again."

This patch alone does not close that window. The window is narrow,
because a family has to be unregistered during it, for example by rmmod
or by a module init that fails after registration.

The next commit in the series, "netlink: Check a group again if it was
released while joining it", appears to fix this:

- It adds a per-group generation counter, nl_table[].mc_gen, which
  __netlink_clear_multicast_users() increments.
- netlink_setsockopt() and netlink_bind() compare the counter again
  under netlink_table_grab() and retry if the group was released.
- On retry, genl_bind() returns -ENOENT for the freed ID.

-- 
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261102155819.4100930-1-anilkaushikwireless%40gmail.com

  reply	other threads:[~2026-11-03 16:00 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-11-02 15:58 [PATCH net v4 0/2] genetlink: fix " Anil Kaushik
2026-11-02 15:58 ` [PATCH net v4 1/2] genetlink: Reject " Anil Kaushik
2026-11-03 16:00   ` netdev-bot+sashiko [this message]
2026-11-03 16:12     ` Anil Kaushik
2026-11-03 17:54       ` Nicolas Dichtel
2026-11-03 21:07         ` Jacob Keller
2026-11-02 15:58 ` [PATCH net v4 2/2] netlink: Check a group again if it was released while joining it Anil Kaushik
2026-11-03 16:00   ` netdev-bot+sashiko
2026-11-03 16:13     ` Anil Kaushik

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=179372164269.488856.17448970060747076034@kernel.org \
    --to=netdev-bot+sashiko@kernel.org \
    --cc=aliceryhl@google.com \
    --cc=anilkaushikwireless@gmail.com \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=fw@strlen.de \
    --cc=horms@kernel.org \
    --cc=idosch@nvidia.com \
    --cc=jacob.e.keller@intel.com \
    --cc=jiri@resnulli.us \
    --cc=kuba@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=martineau@kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=nicolas.dichtel@6wind.com \
    --cc=pabeni@redhat.com \
    --cc=v3rdant.xiang@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®