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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.