From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mail-pj1-f42.google.com (mail-pj1-f42.google.com [209.85.216.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 84B40377EC6 for ; Fri, 14 Aug 2026 09:57:25 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.216.42 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786701451; cv=none; b=tHvXPKzcfG8r0FRGLTCFoOWJINSYBWlDhBH5lQPAboDqA8FBBMqGtbo4tWpFAyQ45wClLL+gfsvnK/tBwpATyR0UZhsGJxuD8/L+UI1J6qpHMG0u3KUhyGNKDyCMLFx2V0RyK9uEz/JGXMEpkz75uZmWdEYJV+DEJYCAJBk9ILo= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786701451; c=relaxed/simple; bh=534CagOdQ35DzD17xlcuafXbatIB2JIffyCe7kh9eOE=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=VY0Fx3DCpiapVhoDwnq+vP7rtoOT6615OqDu1b2UBZwbt4KlPLcKlnI2CFp7Csa77H3ffEqaTgKs+OGhGwEiyRmNzCCbbMIea6FMJ1pplDhgTXfFyxYzoHa1qVC85E/3KMXbNhpF7LoF0u6W1ea3YbOv0eDBTAMkiXe8X29/cTs= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=qrpUuAbf; arc=none smtp.client-ip=209.85.216.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="qrpUuAbf" Received: by mail-pj1-f42.google.com with SMTP id 98e67ed59e1d1-38dc4553f62so1089323a91.0 for ; Fri, 14 Aug 2026 02:57:24 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786701443; x=1787306243; darn=vger.kernel.org; h=content-transfer-encoding:content-type:in-reply-to:from :content-language:references:cc:to:subject:user-agent:mime-version :date:message-id:from:to:cc:subject:date:message-id:reply-to :content-type; bh=oqq/eesd6KpkKbZO5cDYLRl1ZtXvrm9zL+ZkU4ZzFdE=; b=qrpUuAbfgp3YKv4gFfJmathDmGWEc4NV+wc6m19FIjwYYcoelM/8Oio2C10A4iIKFo JWytLDhqhvR2FsbzvmkaxZkf7sIi2g+oENlKDuBQR47WaXcopvkxRgrlK+gstT/EQoIo eCs9+fTthWQKarrgJnQFpbr3XNS1UvdcZ9JyYvSOATc5erdDoJTq0GhYK4f4D2s+QHqw H36aq2/fVlEscCnxIe3u2usH4F2CYY1I7+tfzce6r369rkxDbYMk0OO847Qop3dF6dMf MiLa49sx1W0KU8i/kAplkfIYpNocmo/BDePOq2/BEl0NrejYSnsJkEPlubarhRdRGYyc uziA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786701443; x=1787306243; h=content-transfer-encoding:content-type:in-reply-to:from :content-language:references:cc:to:subject:user-agent:mime-version :date:message-id:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to:content-type; bh=oqq/eesd6KpkKbZO5cDYLRl1ZtXvrm9zL+ZkU4ZzFdE=; b=Ktl7+DthN9xFWUJgSdg9YbfrJpn6HvMr+UQrDmDu/s2OWMoJh7SPePrS5hHmJSwTvt OQPDn61avMXHtx1at2/D68KSJ5LvQDFS++45E2lLrceGHER/dD6YXx0EkQFLNhCe51jw mjmkRvMlL5/tCnQnEpTWbxezKRx69qJ21n7fND2wypb4Nrve3eTYl+FR4sm2RmaXXj3V wzsxdu2PGvqfCY+sq5R6Rb4cKZl0saVGJSDZChqxevr5ngnhvicfZEBW0/WTLKxuAsPf TRdVxT3bnAe279llKZkfUWmJzq1hqJeFIRTbmSPutHSBGuTiR5UvGv5tlrogVhEK4E82 7RZQ== X-Forwarded-Encrypted: i=1; AHgh+RpXRz1y2fDJ/0q/5yXtt7tJMAQ6mHJjUbqKss9TZ4CSrbT2RMl5j2djhvi2FSw8ocUL7bQO0r9RUbXIczs=@vger.kernel.org X-Gm-Message-State: AOJu0YzKS8pGQGoZA51IPTGNz5ODbeOolcU8vA6Et2jegsxbmVsLfx4B NU2NGGYeBnQ52l6htsa1K8W26KkTxAKZyhIZtz5CMF7mNWFr2wz5Wa/D X-Gm-Gg: AR+sD11ptHe6OL2pjAbwUYgU6iqU81JnDSYKM5bfz9uvThBkXFicBbxmX8VccE5usAo K+CczbvmzLuyaTch64k719kAYfeBWJ9iYWsGFv28xoCqtE4R22taWTAfUpC+VVIW07DYRyNC8aF YozsYgmwBFWCUveFkMXfKb32yF7QxWDpdvwrayntf2N3T+PLRyu+hKk0TPwK1Bv05fkZxMod0j+ z7gm8mML2vNq369B6N2YbCQwUh0sWJnEF6TGlZ89TpULHHf788AG83GOGra0gnBzGsUYemE0/1v NmNl55uIH+4iewYz/LwcgcCHN/S9M5XtBS7mNpqMb7+IsvoXmvQYYZ/jkLTS9pHM2rN2vqujM4w BoO6U44eHTOeyhTOOJzsvhTPaIQ2cj0bUMYHxHOubJNYohZYWzGWZHl0iNJ8jz8XMFBS9Utt2qc 2CJh0rO6HgEr5uh9d9KXBm92C25LL+t6GHHdNfLuyH+igNY7NW3eES+s7dRblKb8WaDquFCKpnV y8Iwl6KOoHU6MGyCmhr9A== X-Received: by 2002:a17:90b:1c83:b0:392:ca3b:370a with SMTP id 98e67ed59e1d1-3933b77c3f9mr4752626a91.2.1786701443357; Fri, 14 Aug 2026 02:57:23 -0700 (PDT) Received: from [10.22.68.200] ([118.201.124.118]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-39339b1d20dsm1115327a91.0.2026.08.14.02.57.20 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 14 Aug 2026 02:57:22 -0700 (PDT) Message-ID: <7489ab68-9da6-4c47-8dcd-3bfa1690fbd5@gmail.com> Date: Fri, 14 Aug 2026 17:57:18 +0800 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] fuse: clear stale intr_entry in fuse_remove_pending_req() To: Baokun Li , fuse-devel@lists.linux.dev, Jun Yang , Jun Yang Cc: miklos@szeredi.hu, jefflexu@linux.alibaba.com, winters.zc@antgroup.com, stable@vger.kernel.org, linux-kernel@vger.kernel.org, TencentOS Corvus AI References: <20260728031641.2497811-1-libaokun@linux.alibaba.com> Content-Language: en-US From: Tang Yizhou In-Reply-To: <20260728031641.2497811-1-libaokun@linux.alibaba.com> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit On 28/7/26 11:16 am, Baokun Li wrote: > Commit f8fce75fedf7 ("fuse: clear intr_entry in fuse_resend and > fuse_remove_pending_req") removes stale interrupt entries in > fuse_chan_resend() when requests are moved back to fiq->pending. > However, that cleanup only covers interrupt entries that are already > linked at scan time. It can race with a concurrent queue_interrupt() > from the request holder: > > CPU 0 (holder thread) CPU 1 (resend) > --------------------- -------------- > > req in processing (FR_SENT=1) > > signal arrives > set_bit(FR_INTERRUPTED) > test_bit(FR_SENT) -> true > queue_interrupt(): > spins on fiq->lock ... > fuse_chan_resend(): > set_bit(FR_PENDING) > clear_bit(FR_SENT) > spin_lock(&fiq->lock) > cleanup scan: > intr_entry not linked yet > -> list_del_init is a no-op > list_splice -> fiq->pending > spin_unlock(&fiq->lock) > ... acquires fiq->lock > list_empty(&req->intr_entry) -> true > FR_FINISHED not set > -> intr_entry added to fiq->interrupts > AFTER the cleanup already ran > > fatal signal arrives > fuse_remove_pending_req(): > test_bit(FR_PENDING) -> true > list_del(&req->list) > __fuse_put_request > fuse_put_request (refcount -> 0) > -> req freed, intr_entry dangling > on fiq->interrupts > > fuse_dev_queue_interrupt() only checks list_empty() and FR_FINISHED > before linking intr_entry -- it does not check FR_PENDING, so a > request already spliced back to fiq->pending can still be added to > fiq->interrupts. The lock contention itself produces the bad > ordering: while the resend holds fiq->lock to scan the queued > requests, the holder spins in queue_interrupt() and links intr_entry > right after the scan finishes. > > The dangling entry then causes the same use-after-free that the > above commit describes: fuse_read_interrupt() writes to the freed > slab object via list_del_init() and leaks req->in.h.unique to > userspace. Once the freed memory is reused, INIT_LIST_HEAD() turns > the entry into a self-loop and list_empty(&fiq->interrupts) returns > false forever, so the daemon reads the same phantom FUSE_INTERRUPT > in an infinite loop and never consumes fiq->pending. > > Close the race in fuse_remove_pending_req(), which is the common > bail-out path for both the legacy and the io_uring transport: after > the request is removed from the pending queue, also unlink intr_entry > under fiq->lock before the reference is dropped. fiq->lock must be > taken explicitly since the lock argument is the ring queue lock in > the io_uring case, while fiq->interrupts is always protected by > fiq->lock. This runs on the holder thread after any > queue_interrupt() it issued, and no other path can re-link the entry > once the request is off the queues (re-queueing an interrupt from > FUSE_INTERRUPT's -EAGAIN reply requires finding the request in the > processing queue first). > > Fixes: 760eac73f9f6 ("fuse: Introduce a new notification type for resend pending requests") > Cc: stable@vger.kernel.org # 6.9 > Signed-off-by: Baokun Li > --- > fs/fuse/dev.c | 14 ++++++++++++++ > 1 file changed, 14 insertions(+) > > diff --git a/fs/fuse/dev.c b/fs/fuse/dev.c > index 5763a7cd3b37..87891162985c 100644 > --- a/fs/fuse/dev.c > +++ b/fs/fuse/dev.c > @@ -678,6 +678,8 @@ static int queue_interrupt(struct fuse_req *req) > > bool fuse_remove_pending_req(struct fuse_req *req, spinlock_t *lock) > { > + struct fuse_iqueue *fiq = &req->chan->iq; > + > spin_lock(lock); > if (test_bit(FR_PENDING, &req->flags)) { > /* > @@ -686,6 +688,18 @@ bool fuse_remove_pending_req(struct fuse_req *req, spinlock_t *lock) > */ > list_del(&req->list); > spin_unlock(lock); > + > + /* > + * Remove stale intr_entry queued by queue_interrupt() before > + * the request was requeued, which would otherwise dangle on > + * fiq->interrupts once the request is freed. > + */ > + if (test_bit(FR_INTERRUPTED, &req->flags)) { > + spin_lock(&fiq->lock); > + list_del_init(&req->intr_entry); > + spin_unlock(&fiq->lock); > + } > + > __fuse_put_request(req); > req->out.h.error = -EINTR; > return true; Hi Baokun, I just read Jun’s solution, and it seems his fix is more comprehensive. If you don’t mind, I hope you can take some time to read it. https://lore.kernel.org/all/20260804091757.503476-3-junvyyang@tencent.com/T/#mf9bb60e63dbd4ef0ab5cf826e97ad67037ccd3ff To be frank, Jun doesn’t seem to have a deep understanding of the issue. His patchset appears to have been written by AI, and the problem description is a complete mess. However, his approach to solving the problem seems viable. I’m not sure whether Jun is able to rewrite his patchset that Miklos would accept. If not, I’d be happy to help, since we encountered the same issue in our stability testing. -- Best Regards, Yi