From: JP Kobryn <inwardvessel@gmail.com>
To: Qu Wenruo <wqu@suse.com>, boris@bur.io, clm@fb.com, dsterba@suse.com
Cc: linux-btrfs@vger.kernel.org, stable@vger.kernel.org,
linux-kernel@vger.kernel.org, kernel-team@meta.com
Subject: Re: [PATCH 6.12] btrfs: prevent use-after-free prealloc_file_extent_cluster()
Date: Sat, 31 Jan 2026 15:23:06 -0800 [thread overview]
Message-ID: <fe31cf8b-ac19-4bb4-9cce-d6f2b2996246@gmail.com> (raw)
In-Reply-To: <4c37d4e1-e656-48e3-ac80-83c09fe92625@suse.com>
On 1/31/26 1:08 PM, Qu Wenruo wrote:
>
>
> 在 2026/2/1 05:23, JP Kobryn 写道:
>> Users of filemap_lock_folio() need to guard against the situation where
>> release_folio() has been invoked during reclaim but the folio was
>> ultimately not removed from the page cache. This patch covers one
>> location
>> that was overlooked. Affected code has changed as of 6.17, so this
>> patch is
>> only targeting stable trees prior.
>>
>> After acquiring the folio, use set_folio_extent_mapped() to ensure the
>> folio private state is valid. This is especially important in the subpage
>> case, where the private field is an allocated struct containing bitmap
>> and
>> lock data.
>>
>> Without this protection, the race below is possible:
>>
>> [mm] page cache reclaim path [fs] relocation in subpage mode
>> shrink_folio_list()
>> folio_trylock() /* lock acquired */
>> filemap_release_folio()
>> mapping->a_ops->release_folio()
>> btrfs_release_folio()
>> __btrfs_release_folio()
>> clear_folio_extent_mapped()
>> btrfs_detach_folio_state()
>> bfs = folio_detach_private(folio)
>> btrfs_free_folio_state(folio)
>> kfree(bfs) /* point A */
>>
>> prealloc_file_extent_cluster()
>> filemap_lock_folio()
>> folio_try_get() /* inc
>> refcount */
>> folio_lock() /* wait for lock */
>>
>> if (...)
>> ...
>> else if (!mapping || !__remove_mapping(..))
>> /*
>> * __remove_mapping() returns zero when
>> * folio_ref_freeze(folio, refcount) fails /* point B */
>> */
>> goto keep_locked /* folio remains in cache */
>>
>> keep_locked:
>> folio_unlock(folio) /* lock released */
>>
>> /* lock acquired */
>> btrfs_subpage_clear_updodate()
>> bfs = folio->priv /* use-after-
>> free */
>
> This patch itself and the root cause look good to me.
>
> Reviewed-by: Qu Wenruo <wqu@suse.com>
>
Much appreciated :)
>>
>> This patch is intended as a minimal fix for backporting to affected
>> kernels. As of 6.17, a commit [0] replaced the vulnerable
>> filemap_lock_folio() + btrfs_subpage_clear_uptodate() sequence with
>> filemap_invalidate_inode() avoiding the race entirely. That commit was
>> part
>> of a series with a different goal of preparing for large folio support so
>> backporting may not be straight forward.
>
> However I'm not sure if stable tree even accepts non-upstreamed patches.
>
> Thus the stable maintainer may ask you the same question as I did
> before, why not backport the upstream commit 4e346baee95f?
That commit relies on filemap_invalidate_folio() which was introduced in
6.10 so it would not apply to earlier stable branches.
We need to fix as far back as 5.15 so I can send one additional patch to
cover stable trees 5.15 to 6.6. The patch would be almost identical,
with the only change being using the page API instead of the folio API
(set_folio_extent_mapped() -> set_page_extent_mapped()). Let me know if
you're in agreement and I can send the extra patch.
>
> If it's lacking the reason why it's a bug fix, I believe you can modify
> the commit message to include the analyze and the fixes tag.
>
>
> I'm also curious to learn the proper way for such situation.
It's new to me as well. For reference, there are some commits on the
list that have language like this: "This is a stable-only fix".
next prev parent reply other threads:[~2026-01-31 23:23 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-01-31 18:53 JP Kobryn
2026-01-31 21:08 ` Qu Wenruo
2026-01-31 23:23 ` JP Kobryn [this message]
2026-01-31 23:32 ` Qu Wenruo
2026-02-01 4:33 ` JP Kobryn
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=fe31cf8b-ac19-4bb4-9cce-d6f2b2996246@gmail.com \
--to=inwardvessel@gmail.com \
--cc=boris@bur.io \
--cc=clm@fb.com \
--cc=dsterba@suse.com \
--cc=kernel-team@meta.com \
--cc=linux-btrfs@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
--cc=wqu@suse.com \
/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®