mirror of
https://github.com/torvalds/linux.git
synced 2026-11-06 21:58:01 +01:00
9p/xen: drain response work after unbinding IRQ
commitea4f100940("9p/xen : Fix use after free bug in xen_9pfs_front_remove due to race condition") added cancel_work_sync() to keep xen_9pfs_front_free() from freeing a ring while p9_xen_response() is still running. The work is currently drained before the event channel IRQ is unbound. That leaves a race window where xen_9pfs_front_event_handler() can run after cancel_work_sync() returns and queue p9_xen_response() again. The following unbind_from_irqhandler() synchronizes with the IRQ handler, but it does not cancel work that the handler already queued. The teardown can then free the ring and private data while the response work remains pending, and the worker later dereferences ring->priv and priv->client. Unbind the event channel IRQ before draining the work. Once the IRQ is unbound, no new response work can be queued by the backend event channel, and cancel_work_sync() waits for any work that was queued before or during the unbind. It is then safe to release the ring resources. Fixes:ea4f100940("9p/xen : Fix use after free bug in xen_9pfs_front_remove due to race condition") Cc: stable@vger.kernel.org Reported-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn> Reported-by: Yuxiang Yang <yangyx22@mails.tsinghua.edu.cn> Reported-by: Ao Wang <wangao@seu.edu.cn> Reported-by: Xuewei Feng <fengxw06@126.com> Reported-by: Qi Li <qli01@tsinghua.edu.cn> Reported-by: Ke Xu <xuke@tsinghua.edu.cn> Assisted-by: GLM:GLM-5.1 Signed-off-by: Yizhou Zhao <zhaoyz24@mails.tsinghua.edu.cn> Message-ID: <20260609155202.1706-1-zhaoyz24@mails.tsinghua.edu.cn> Signed-off-by: Dominique Martinet <asmadeus@codewreck.org>
This commit is contained in:
parent
b3d07d6483
commit
7b6f2e3c29
|
|
@ -282,14 +282,14 @@ static void xen_9pfs_front_free(struct xen_9pfs_front_priv *priv)
|
|||
for (i = 0; i < XEN_9PFS_NUM_RINGS; i++) {
|
||||
struct xen_9pfs_dataring *ring = &priv->rings[i];
|
||||
|
||||
cancel_work_sync(&ring->work);
|
||||
|
||||
if (!ring->intf)
|
||||
break;
|
||||
if (ring->irq >= 0) {
|
||||
unbind_from_irqhandler(ring->irq, ring);
|
||||
ring->irq = -1;
|
||||
}
|
||||
cancel_work_sync(&ring->work);
|
||||
|
||||
if (ring->data.in) {
|
||||
for (j = 0; j < (1 << ring->intf->ring_order); j++) {
|
||||
grant_ref_t ref;
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user