From: sashiko-bot@kernel.org
To: "Liao Xuan" <liaoxuan@open-hieco.net>
Cc: linux-pci@vger.kernel.org
Subject: Re: [PATCH 3/3] nvme: Expose link rate switching tunables via sysfs
Date: Thu, 24 Sep 2026 06:29:10 +0000 [thread overview]
Message-ID: <20260924062911.03C4D1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <be224cd8385a5c28a20db65d635000a7be4da91a.1790222172.git.liaoxuan@hygon.cn>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] nvme: Use-After-Free in timer teardown due to missing timer_shutdown_sync()
- [High] nvme: Use-After-Free on per-CPU stats due to lack of synchronization during teardown
- [Medium] nvme: sysfs teardown race allows resurrecting feature state and causing UAF
- [Medium] nvme: torn read-modify-write data race on per-CPU I/O statistics
--
commit 923c7df43c12b9f8956632abc24a17d7d85b2d2f
Author: Liao Xuan <liaoxuan@open-hieco.net>
nvme: Expose link rate switching tunables via sysfs
This commit adds a speed attribute group under /sys/class/nvme/nvmeX/ to
expose adaptive link rate switching parameters for runtime tuning. The
attributes are read/write and are removed when the controller is torn down.
> diff --git a/drivers/nvme/host/speed_switch.c b/drivers/nvme/host/speed_switch.c
> index 22f180c8119b2..fce4268459a0c 100644
> --- a/drivers/nvme/host/speed_switch.c
> +++ b/drivers/nvme/host/speed_switch.c
[ ... ]
> @@ -405,6 +417,7 @@ void nvme_speed_switch_exit(struct nvme_ctrl *ctrl)
> WRITE_ONCE(sw->enabled, false);
> timer_delete_sync(&sw->timer);
[Severity: High]
Is it safe to use timer_delete_sync() for the teardown path?
If a concurrent I/O thread in nvme_update_io_stats() is preempted, could it
wait for timer_delete_sync() to complete and then re-arm the timer after
the cancellation completes?
nvme_update_io_stats()
mod_timer(&sw->timer, jiffies + msecs_to_jiffies(READ_ONCE(sw->monitor_interval)));
When the parent nvme_ctrl is later freed, the timer will execute and access
freed memory. Should this use timer_shutdown_sync() instead?
> cancel_work_sync(&sw->work);
> + sysfs_remove_group(&ctrl->device->kobj, &nvme_speed_attr_group);
[Severity: Medium]
Is this sysfs group removed too late, leaving a race window during teardown?
Since WRITE_ONCE(sw->enabled, false) and timer_delete_sync() are called
before sysfs_remove_group(), could a concurrent sysfs write to the enable
attribute execute WRITE_ONCE(sw->enabled, val) and set it back to true?
Because sysfs_remove_group() blocks until active writes finish, it will
proceed to free sw->stats while sw->enabled remains true, guaranteeing that
subsequent I/Os will bypass the guard and access freed memory.
>
> free_percpu(sw->stats);
[Severity: High]
Can this cause a use-after-free when dereferencing sw->stats?
Since there is no synchronization (such as an RCU grace period or queue
freeze) before freeing the memory, could a concurrent I/O thread executing
nvme_update_io_stats() that has already passed the lockless sw->enabled
check resume and call get_cpu_ptr(sw->stats)?
nvme_update_io_stats()
stat = get_cpu_ptr(sw->stats);
This would dereference the per-CPU pointer which may have just been freed by
this concurrent teardown.
[Severity: Medium]
Can this also cause a torn read-modify-write data race on the per-CPU I/O
statistics?
If nvme_check_io_and_decide_speed() iterates over all CPUs and clears their
counters with a remote, non-atomic write:
stat->read_bytes = 0;
stat->write_bytes = 0;
And concurrently, the I/O submission path nvme_update_io_stats() executes a
non-atomic read-modify-write on its local CPU:
stat->read_bytes += bytes;
Could the remote write of 0 occur between the local load and store, causing
the 0 to be overwritten by the local CPU's accumulated total, thereby double
counting the transferred bytes and artificially inflating throughput?
> sw->stats = NULL;
> }
> diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
> index abf8edaae371b..3918d9c3d3306 100644
> --- a/drivers/nvme/host/sysfs.c
> +++ b/drivers/nvme/host/sysfs.c
[ ... ]
> @@ -1310,3 +1310,146 @@ const struct attribute_group *nvme_subsys_attrs_groups[] = {
[ ... ]
> +static ssize_t nvme_speed_attr_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
[ ... ]
> + switch (sa->id) {
> + case NVME_SPEED_ATTR_ENABLE:
> + if (val > 1)
> + return -EINVAL;
> + if (!val && READ_ONCE(sw->enabled)) {
> + WRITE_ONCE(sw->enabled, false);
> + timer_delete_sync(&sw->timer);
> + cancel_work_sync(&sw->work);
> + atomic_set(&sw->timer_active, NVME_SPEED_TIMER_INACTIVE);
> + } else
> + WRITE_ONCE(sw->enabled, val);
[Severity: Medium]
Can this overwrite the teardown flag without a lock?
If this executes concurrently with nvme_speed_switch_exit() due to late
sysfs_remove_group() calling, it could silently reactivate lockless access
to memory that is about to be freed.
> + break;
> + case NVME_SPEED_ATTR_MONITOR_INTERVAL:
--
Sashiko AI review · https://sashiko.dev/#/patchset/cover.1790222172.git.liaoxuan@hygon.cn?part=3
prev parent reply other threads:[~2026-09-24 6:29 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-24 6:15 [PATCH 0/3] Add adaptive NVMe link rate switching function Liao Xuan
2026-09-24 6:15 ` [PATCH 1/3] nvme: Add adaptive PCIe " Liao Xuan
2026-09-24 6:29 ` sashiko-bot
2026-09-24 6:15 ` [PATCH 2/3] nvme: Add hysteresis and idle detection to link rate switching Liao Xuan
2026-09-24 6:27 ` sashiko-bot
2026-09-24 6:15 ` [PATCH 3/3] nvme: Expose link rate switching tunables via sysfs Liao Xuan
2026-09-24 6:29 ` sashiko-bot [this message]
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=20260924062911.03C4D1F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=liaoxuan@open-hieco.net \
--cc=linux-pci@vger.kernel.org \
--cc=sashiko-reviews@lists.linux.dev \
/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