Netdev List
 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,
	v3rdant.xiang@gmail.com, aliceryhl@google.com,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH net v2 1/2] genetlink: Reject joining multicast groups no family owns
Date: Sun, 01 Nov 2026 06:38:38 +0000	[thread overview]
Message-ID: <179351511832.3131.17059702072211202236@kernel.org> (raw)
In-Reply-To: <20261031054632.3697295-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 · 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] genl_bind() checks ownership and GENL_MCAST_CAP_* under
  down_read(&cb_lock) and releases the lock before the caller adds the…

--

genetlink: Reject joining multicast groups no family owns

This commit makes genl_bind() return -ENOENT when no registered family
owns the requested multicast group ID. Before this, such joins succeeded.
The socket then stayed a member if a privileged family was later assigned
that 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;
>  
>  	down_read(&cb_lock);
>  
> @@ -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]
genl_bind() checks ownership and capabilities under down_read(&cb_lock),
but it drops cb_lock before the caller installs the membership. Can the
owner of the group change in between?

In netlink_setsockopt() the membership update is a separate critical
section:

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_table_ungrab();
    ...
}

The window in netlink_bind() is wider. netlink_lock_table() and the
insert/autobind step both run between the per-group genl_bind() calls
and the netlink_table_grab() that updates nlk->groups.

Consider this sequence:

CPU0
setsockopt(NETLINK_ADD_MEMBERSHIP, X)
  genl_bind()
    family A owns X with no GENL_MCAST_CAP_* flags, ret = 0
    up_read(&cb_lock)

CPU1
genl_unregister_family(A)
  genl_unregister_mc_groups(A)
    clears members of X (CPU0 is not a member yet)
    clear_bit(X, mc_groups)
  idr_remove(&genl_fam_idr, A->id)

CPU2
genl_register_family(B)   /* B has a GENL_MCAST_CAP_NET_ADMIN group */
  genl_allocate_reserve_groups()
    find_first_zero_bit() returns X

CPU0
netlink_table_grab()
netlink_update_socket_mc(nlk, X, 1)

Would the socket then belong to B's privileged group without passing a
capability check? Nothing seems to check that membership again later.

The follow-up commit "genetlink: Clear stale members when assigning
multicast group IDs" adds a genl_clear_mc_users() call to
genl_validate_assign_mc_groups(). That handles a stale membership that is
already installed when B registers. In the sequence above, though, the
clear runs before CPU0 installs the membership, so it finds no member.

The follow-up's commit message says:

  No socket can be a valid member at that point: cb_lock is held for
  writing, so genl_bind() cannot see the new family yet

Does that reasoning miss a socket whose genl_bind() already passed for
the previous owner, with its membership update still pending?

To trigger this, A has to be unregistered inside the window, for example
by rmmod, or by a module init that registers a family, then fails and
unregisters it. B also has to get the freed ID. An unprivileged user can
trigger B's registration through CTRL_CMD_GETFAMILY and request_module().

Would serializing the check with the membership update close this
completely? That could mean holding cb_lock across both, or re-checking
under netlink_table_grab().

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

  reply	other threads:[~2026-11-01  6:38 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-31  5:46 [PATCH net v2 0/2] genetlink: fix joining multicast groups no family owns Anil Kaushik
2026-10-31  5:46 ` [PATCH net v2 1/2] genetlink: Reject " Anil Kaushik
2026-11-01  6:38   ` netdev-bot+sashiko [this message]
2026-10-31  5:46 ` [PATCH net v2 2/2] genetlink: Clear stale members when assigning multicast group IDs Anil Kaushik
2026-11-01  6:38   ` netdev-bot+sashiko

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=179351511832.3131.17059702072211202236@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=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=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