mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
From: Jakub Kicinski <kuba@kernel.org>
To: Yingjie Wang <x-professor@outlook.com>
Cc: "netdev@vger.kernel.org" <netdev@vger.kernel.org>,
	"davem@davemloft.net" <davem@davemloft.net>,
	"edumazet@kernel.org" <edumazet@kernel.org>,
	"pabeni@redhat.com" <pabeni@redhat.com>,
	"horms@kernel.org" <horms@kernel.org>,
	"shuah@kernel.org" <shuah@kernel.org>,
	"phx0fer@gmail.com" <phx0fer@gmail.com>,
	"wang.zhan@smartx.com" <wang.zhan@smartx.com>,
	"kuniyu@google.com" <kuniyu@google.com>,
	"linux-kselftest@vger.kernel.org"
	<linux-kselftest@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>
Subject: Re: [PATCH net v2 1/2] net: preserve rps_default_mask on failed writes
Date: Fri, 30 Oct 2026 16:00:29 -0700	[thread overview]
Message-ID: <20261030160029.76ee6c7f@kernel.org> (raw)
In-Reply-To: <11f9052cba649eb1efec6e9e45eb9377d46e19d1.1793286626.git.x-professor@outlook.com>

On Thu, 29 Oct 2026 15:10:36 +0000 Yingjie Wang wrote:
> rps_default_mask_sysctl() passes the live per-netns mask to
> cpumask_parse(). bitmap_parse() stores chunks as it scans from right to
> left, so a later error can leave lower chunks changed.
> rps_cpumask_housekeeping() also intersects its input in place before
> returning -EINVAL when no housekeeping CPUs remain.
> 
> Consequently, a failed write changes both the value read from the sysctl
> and the default copied to RX queues created later. On a four-CPU VM,
> after setting the mask to 1, writing zz,00000003 failed with EOVERFLOW
> but changed the mask to 3. Writing a mask containing only isolated CPUs
> failed with EINVAL but changed it to 0. No kernel modification or error
> injection was needed to reproduce either case.
> 
> Parse and validate a temporary mask before taking the mutex. After both
> steps succeed, take the mutex and replace the live pointer. Readers
> access and consume the pointer while holding the same mutex, so the
> replaced mask can be freed after dropping the mutex.
> 
> The rps_default_mask selftest failed on the base kernel and passed with
> the fix. The fixed kernel also kept the mask at 1 for the overflow and
> housekeeping failure cases, while valid writes of 2 and 0 still
> succeeded.
> 
> The issue was found while fuzzing sysctl write error paths.
> 
> Fixes: 605cfa1b1090 ("net: introduce default_rps_mask netns attribute")
> Reviewed-by: Wang Zhan <wang.zhan@smartx.com>
> Tested-by: Wang Zhan <wang.zhan@smartx.com>
> Signed-off-by: Yingjie Wang <x-professor@outlook.com>

kzalloc(cpumask_size(), GFP_KERNEL) failure seems purely theoretical.
Please drop the Fixes tag and drop the selftest, and repost after the
merge window is over (https://netdev.bots.linux.dev/net-next.html)

> diff --git a/net/core/sysctl_net_core.c b/net/core/sysctl_net_core.c
> index 473c162736d69..f25281c709346 100644
> --- a/net/core/sysctl_net_core.c
> +++ b/net/core/sysctl_net_core.c
> @@ -105,34 +105,37 @@ static int rps_default_mask_sysctl(const struct ctl_table *table, int write,
>  				   void *buffer, size_t *lenp, loff_t *ppos)
>  {
>  	struct net *net = (struct net *)table->data;
> +	struct cpumask *new_mask = NULL;
>  	struct cpumask *mask;
>  	int err = 0;
>  
> -	mutex_lock(&rps_default_mask_mutex);
> -	mask = net->core.rps_default_mask;
>  	if (write) {
> -		if (!mask) {
> -			mask = kzalloc(cpumask_size(), GFP_KERNEL);
> -			net->core.rps_default_mask = mask;
> -		}
> -		err = -ENOMEM;
> -		if (!mask)
> -			goto done;
> +		new_mask = kzalloc(cpumask_size(), GFP_KERNEL);
> +		if (!new_mask)
> +			return -ENOMEM;
>  
> -		err = cpumask_parse(buffer, mask);
> +		err = cpumask_parse(buffer, new_mask);
>  		if (err)
> -			goto done;
> +			goto out;
>  
> -		err = rps_cpumask_housekeeping(mask);
> +		err = rps_cpumask_housekeeping(new_mask);
>  		if (err)
> -			goto done;
> +			goto out;
> +	}
> +
> +	mutex_lock(&rps_default_mask_mutex);
> +	mask = net->core.rps_default_mask;
> +	if (write) {
> +		net->core.rps_default_mask = new_mask;
> +		new_mask = mask;

nit: this could use

		swap(net->core.rps_default_mask, new_mask);

>  	} else {
>  		err = dump_cpumask(buffer, lenp, ppos,
>  				   mask ?: cpu_none_mask);
>  	}
>  
> -done:
>  	mutex_unlock(&rps_default_mask_mutex);
> +out:
> +	kfree(new_mask);
>  	return err;
>  }
>  
-- 
pw-bot: cr


  reply	other threads:[~2026-10-30 23:00 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-10-29 15:10 [PATCH net v2 0/2] " Yingjie Wang
2026-10-29 15:10 ` [PATCH net v2 1/2] " Yingjie Wang
2026-10-30 23:00   ` Jakub Kicinski [this message]
2026-10-29 15:10 ` [PATCH net v2 2/2] selftests: net: check failed rps_default_mask writes Yingjie Wang

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=20261030160029.76ee6c7f@kernel.org \
    --to=kuba@kernel.org \
    --cc=davem@davemloft.net \
    --cc=edumazet@kernel.org \
    --cc=horms@kernel.org \
    --cc=kuniyu@google.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-kselftest@vger.kernel.org \
    --cc=netdev@vger.kernel.org \
    --cc=pabeni@redhat.com \
    --cc=phx0fer@gmail.com \
    --cc=shuah@kernel.org \
    --cc=wang.zhan@smartx.com \
    --cc=x-professor@outlook.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®