From: Juergen Gross <jgross@suse.com>
To: Qihang <q.h.hack.winter@gmail.com>, xen-devel@lists.xenproject.org
Cc: Stefano Stabellini <sstabellini@kernel.org>,
Oleksandr Tyshchenko <oleksandr_tyshchenko@epam.com>,
Viresh Kumar <viresh.kumar@linaro.org>,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: Re: [PATCH] xen/privcmd: fix double free when an irqfd is shut down twice
Date: Mon, 9 Nov 2026 15:34:18 +0100 [thread overview]
Message-ID: <70378f23-69f3-4bb0-885e-54c29daa6ddf@suse.com> (raw)
In-Reply-To: <20261101163251.55099-1-q.h.hack.winter@gmail.com>
[-- Attachment #1.1: Type: text/plain, Size: 3054 bytes --]
On 01.11.26 17:32, Qihang wrote:
> irqfd_deactivate() takes the irqfd off irqfds_list and queues
> irqfd_shutdown(). queue_work() is not a once-only gate: it refuses to
> enqueue a work item only while WORK_STRUCT_PENDING is set, and
> process_one_work() clears that bit before it calls the work function. So
> nothing records that the shutdown work has already been queued, and
> nothing protects the window between the start of irqfd_shutdown() and the
> kfree() at its end.
>
> Two paths call irqfd_deactivate() for the same irqfd:
>
> - privcmd_irqfd_deassign(), from the PRIVCMD_IRQFD_FLAG_DEASSIGN ioctl;
>
> - irqfd_wakeup(), with EPOLLHUP set, when the last reference to the
> eventfd file goes away, which runs wake_up_poll(&ctx->wqh, EPOLLHUP)
> from eventfd_release().
>
> irqfds_lock serialises the two calls, but it does not make the second one
> a no-op, and eventfd_ctx_fdget() takes a reference to the eventfd_ctx,
> not to the struct file, so the last fd can still be closed while the
> ioctl is running:
>
> CPU0 CPU1
>
> eventfd_ctx_fdget()
> spin_lock(irqfds_lock)
> list_del_init(&kirqfd->list)
> queue_work(&kirqfd->shutdown) close(fd)
> eventfd_release()
> wake_up_poll(EPOLLHUP)
> irqfd_wakeup()
> spin_lock(irqfds_lock)
> irqfd_deactivate() again
>
> If the work item has already started by then, its pending bit has been
> cleared and the second queue_work() succeeds. irqfd_shutdown() then runs
> twice, so eventfd_ctx_remove_wait_queue(), eventfd_ctx_put() and kfree()
> each hit the same object a second time; and when the second queue_work()
> lands after the irqfd has been freed, the workqueue list operations write
> to freed memory.
>
> virt/kvm/eventfd.c has the same two callers and has had this guard since
> the original irqfd support (721eecbf4fe99): irqfd_wakeup() calls
> irqfd_deactivate() only if irqfd_is_active(). The comment there explains
> why that is enough: the other side deactivates the irqfd before it takes
> it off the waitqueue, and irqfd_shutdown() needs the waitqueue lock,
> which this callback holds, so the irqfd cannot be freed under it.
>
> Do the same here. list_del_init() leaves the list head empty and the
> irqfd stays off the list until kfree(), so it serves as a one-way
> "active" flag. The test is in irqfd_deactivate() rather than in
> irqfd_wakeup() because privcmd_irqfd_deassign() walks irqfds_list and can
> therefore never reach an inactive irqfd; only the wakeup path can, and a
> single test covers both callers.
>
> Fixes: f8941e6c4c712 ("xen: privcmd: Add support for irqfd")
> Cc: stable@vger.kernel.org
> Signed-off-by: Qihang <q.h.hack.winter@gmail.com>
Reviewed-by: Juergen Gross <jgross@suse.com>
Juergen
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 495 bytes --]
next prev parent reply other threads:[~2026-11-09 14:34 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-11-01 16:32 Qihang
2026-11-09 14:34 ` Juergen Gross [this message]
-- strict thread matches above, loose matches on Subject: below --
2026-11-01 16:31 Qihang
2026-11-01 16:31 ` Qihang
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=70378f23-69f3-4bb0-885e-54c29daa6ddf@suse.com \
--to=jgross@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=oleksandr_tyshchenko@epam.com \
--cc=q.h.hack.winter@gmail.com \
--cc=sstabellini@kernel.org \
--cc=stable@vger.kernel.org \
--cc=viresh.kumar@linaro.org \
--cc=xen-devel@lists.xenproject.org \
/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®