From: netdev-bot+sashiko@kernel.org
To: lian@is.s.u-tokyo.ac.jp
Cc: ericvh@kernel.org, lucho@ionkov.net, asmadeus@codewreck.org,
davem@davemloft.net, edumazet@kernel.org, kuba@kernel.org,
pabeni@redhat.com, linux_oss@crudebyte.com, horms@kernel.org,
viro@zeniv.linux.org.uk, tomasbortoli@gmail.com,
chirantan@chromium.org, groug@kaod.org,
aneesh.kumar@linux.vnet.ibm.com, v9fs@lists.linux.dev,
netdev@vger.kernel.org, linux-kernel@vger.kernel.org,
shina@is.s.u-tokyo.ac.jp, stable@vger.kernel.org
Subject: Re: [PATCH 5/5] 9p/virtio: keep zero-copy buffers until the device returns them
Date: Thu, 12 Nov 2026 07:53:13 +0000 [thread overview]
Message-ID: <179446999308.2199510.11222629754827394625@kernel.org> (raw)
In-Reply-To: <20261109105251.2545764-6-lian@is.s.u-tokyo.ac.jp>
Thank you for your contribution! Sashiko AI review found 1 potential
issue(s) to consider.
Critical: 0 · High: 1 · Medium: 0 · 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).
- [High] The patch adds an unconditional `wait_event_idle(req->wq,
!smp_load_acquire(&req->zc_pages))` to p9_client_zc_rpc()…
--
9p/virtio: keep zero-copy buffers until the device returns them
This patch fixes a use-after-free. If a fatal signal ends the wait in
p9_virtio_zc_request() while the device still holds the request, a
misbehaving device can later write into zero-copy buffers that have
already been freed. Freeing of the pinned pages moves to req_done() via
a per-request struct p9_zc_pages, and p9_client_zc_rpc() now waits until
the device returns the request.
> diff --git a/net/9p/client.c b/net/9p/client.c
> index 15bb939087165..34be0d2652d4e 100644
> --- a/net/9p/client.c
> +++ b/net/9p/client.c
[ ... ]
> @@ -707,6 +708,8 @@ static struct p9_req_t *p9_client_zc_rpc(struct p9_client *c, int8_t type,
> * into rc only while it waits.
> */
> }
> + /* The caller may reuse the payload once the transport releases it */
> + wait_event_idle(req->wq, !smp_load_acquire(&req->zc_pages));
[Severity: High]
Can this wait leave a killed task stuck forever?
wait_event_idle() sleeps in TASK_IDLE and has no timeout, so SIGKILL
cannot end it. khungtaskd also skips TASK_NOLOAD tasks, so the hang
would never be reported.
The only code that clears req->zc_pages and wakes req->wq is in
req_done(). It runs only after virtqueue_get_buf() returns this exact
request:
net/9p/trans_virtio.c:req_done() {
...
while ((req = virtqueue_get_buf(chan->vq, &len)) != NULL) {
...
if (req->zc_pages) {
if (req->zc_pages->held)
p9_zc_release(req->zc_pages);
smp_store_release(&req->zc_pages, NULL);
wake_up(&req->wq);
}
...
}
On a fatal signal, p9_virtio_zc_request() hands the pages to req_done()
and returns with req->zc_pages still set:
held = req->zc_pages;
if (held)
zc->held = true;
spin_unlock_irqrestore(&chan->lock, flags);
if (held)
return err;
p9_client_zc_rpc() sends a TFLUSH only when c->status == Connected.
There are two cases where no flush is sent but the new wait still runs:
- after umount -f, via
v9fs_session_begin_cancel()->p9_client_begin_disconnect()
- after an earlier -EIO has set Disconnected
If a flush is sent, p9_client_rpc(TFLUSH) can itself return early on the
fatal signal. In every case the wait above runs.
If the device never returns the original descriptor, nothing else clears
zc_pages. That can happen in several ways:
- virtqueue_kick() fails and sets vq->broken. Its return value is
ignored right after req->zc_pages = zc in p9_virtio_zc_request().
- surprise PCI removal. virtio_pci_remove() calls
virtio_break_device(), and vring_interrupt() then stops calling the
callback.
- a hung backend, or a device that answers the TFLUSH but keeps the
original descriptor. This is the misbehaving-device case the commit
message describes.
Before this patch, a killed task always left this path.
Once stuck, the task keeps any VFS locks its caller holds and cannot
finish exiting or coredumping. Its pinned pages stay counted in
vp_pinned, which throttles p9_get_mapped_pages() on other mounts. It
also keeps the mount busy, so p9_virtio_close() never runs and
chan->inuse stays true. p9_virtio_remove() then loops here and never
reaches virtio_reset_device()/del_vqs():
while (chan->inuse) {
mutex_unlock(&virtio_9p_lock);
msleep(250);
That is a circular wait. Remove waits for umount, umount waits for the
task, and the task waits for a req_done() that never runs for this
request.
For pinned user pages (need_drop == 1), the zc->held hand-off already
keeps the pages alive until req_done(), so the unconditional wait seems
to be needed only for kvec buffers. Could the wait be limited to that
case, or bounded or made killable? Alternatively, could the transport
clear zc_pages and wake waiters when the vq is broken or torn down?
The commit message also does not mention that killed tasks can now
block on the device with no time limit. Should it?
> recalc_sigpending:
> if (sigpending) {
> spin_lock_irqsave(¤t->sighand->siglock, flags);
[ ... ]
--
Sashiko AI review · https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20261109105251.2545764-1-lian%40is.s.u-tokyo.ac.jp
prev parent reply other threads:[~2026-11-12 7:53 UTC|newest]
Thread overview: 10+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-09 10:52 [PATCH 0/5] 9p: bound zero-copy error replies and keep flushed requests until the device returns them Lianjie Wang
2026-11-09 10:52 ` [PATCH 1/5] 9p/virtio: clamp the reply size of a zero-copy request Lianjie Wang
2026-11-12 7:53 ` netdev-bot+sashiko
2026-11-09 10:52 ` [PATCH 2/5] 9p: ignore a zero-copy reply that arrives after a fatal signal Lianjie Wang
2026-11-12 7:53 ` netdev-bot+sashiko
2026-11-09 10:52 ` [PATCH 3/5] 9p/virtio: keep a request until the device returns it Lianjie Wang
2026-11-12 7:53 ` netdev-bot+sashiko
2026-11-09 10:52 ` [PATCH 4/5] 9p: take the tag of a flushed request from the request Lianjie Wang
2026-11-09 10:52 ` [PATCH 5/5] 9p/virtio: keep zero-copy buffers until the device returns them Lianjie Wang
2026-11-12 7:53 ` netdev-bot+sashiko [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=179446999308.2199510.11222629754827394625@kernel.org \
--to=netdev-bot+sashiko@kernel.org \
--cc=aneesh.kumar@linux.vnet.ibm.com \
--cc=asmadeus@codewreck.org \
--cc=chirantan@chromium.org \
--cc=davem@davemloft.net \
--cc=edumazet@kernel.org \
--cc=ericvh@kernel.org \
--cc=groug@kaod.org \
--cc=horms@kernel.org \
--cc=kuba@kernel.org \
--cc=lian@is.s.u-tokyo.ac.jp \
--cc=linux-kernel@vger.kernel.org \
--cc=linux_oss@crudebyte.com \
--cc=lucho@ionkov.net \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shina@is.s.u-tokyo.ac.jp \
--cc=stable@vger.kernel.org \
--cc=tomasbortoli@gmail.com \
--cc=v9fs@lists.linux.dev \
--cc=viro@zeniv.linux.org.uk \
/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