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
next prev parent 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®