From: Sasha Levin <sashal@kernel.org>
To: patches@lists.linux.dev, stable@vger.kernel.org
Cc: Deepakkumar Karn <dkarn@redhat.com>, Jan Kara <jack@suse.cz>,
Christian Brauner <brauner@kernel.org>,
Sasha Levin <sashal@kernel.org>,
viro@zeniv.linux.org.uk, linux-fsdevel@vger.kernel.org
Subject: [PATCH AUTOSEL 6.19-6.1] fs/buffer: add alert in try_to_free_buffers() for folios without buffers
Date: Tue, 10 Feb 2026 18:30:59 -0500 [thread overview]
Message-ID: <20260210233123.2905307-14-sashal@kernel.org> (raw)
In-Reply-To: <20260210233123.2905307-1-sashal@kernel.org>
From: Deepakkumar Karn <dkarn@redhat.com>
[ Upstream commit b68f91ef3b3fe82ad78c417de71b675699a8467c ]
try_to_free_buffers() can be called on folios with no buffers attached
when filemap_release_folio() is invoked on a folio belonging to a mapping
with AS_RELEASE_ALWAYS set but no release_folio operation defined.
In such cases, folio_needs_release() returns true because of the
AS_RELEASE_ALWAYS flag, but the folio has no private buffer data. This
causes try_to_free_buffers() to call drop_buffers() on a folio with no
buffers, leading to a null pointer dereference.
Adding a check in try_to_free_buffers() to return early if the folio has no
buffers attached, with WARN_ON_ONCE() to alert about the misconfiguration.
This provides defensive hardening.
Signed-off-by: Deepakkumar Karn <dkarn@redhat.com>
Link: https://patch.msgid.link/20251211131211.308021-1-dkarn@redhat.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
LLM Generated explanations, may be completely bogus:
`folio_buffers()` exists in all relevant stable trees. The patch uses
only `WARN_ON_ONCE` and `folio_buffers`, both of which are available
everywhere.
## Comprehensive Analysis
### 1. COMMIT MESSAGE ANALYSIS
The commit describes a clear bug: `try_to_free_buffers()` can be called
on folios with no buffer_heads attached when `filemap_release_folio()`
is invoked on a folio belonging to a mapping with `AS_RELEASE_ALWAYS`
set but no `release_folio` operation defined. This causes a **NULL
pointer dereference** in `drop_buffers()`.
The commit is authored by Deepakkumar Karn (Red Hat), reviewed by Jan
Kara (SUSE, a very well-respected VFS/filesystem developer), and signed
off by Christian Brauner (the VFS subsystem maintainer).
### 2. CODE CHANGE ANALYSIS
The fix adds exactly 3 lines (plus a comment) to
`try_to_free_buffers()`:
```c
/* Misconfigured folio check */
if (WARN_ON_ONCE(!folio_buffers(folio)))
return true;
```
This is inserted after the writeback check and before the `mapping ==
NULL` check. The logic is:
- If the folio has no buffers (`folio_buffers()` returns NULL), emit a
warning (once) and return `true` (success — there's nothing to free)
- This prevents the NULL deref in `drop_buffers()` where `head =
folio_buffers(folio)` returns NULL and then `buffer_busy(bh)`
dereferences it
### 3. THE BUG MECHANISM
The call chain is:
1. Memory reclaim (`shrink_folio_list`) or truncation calls
`filemap_release_folio()`
2. `folio_needs_release()` returns `true` because `AS_RELEASE_ALWAYS` is
set
3. `mapping->a_ops->release_folio` is NULL (e.g., `afs_dir_aops` doesn't
define it in v6.14+)
4. Falls through to `try_to_free_buffers(folio)`
5. `drop_buffers()` dereferences `folio_buffers(folio)` which is NULL
6. **NULL pointer dereference crash**
### 4. AFFECTED VERSIONS
The specific trigger (AFS symlinks/directories with `afs_dir_aops`
lacking `release_folio`) only exists from **v6.14-rc1** onward,
introduced by commit `6dd80936618c` ("afs: Use netfslib for
directories"). Before v6.14, all filesystems that set
`AS_RELEASE_ALWAYS` also define `release_folio`.
This means:
- **v6.6.y**: NOT affected (afs_dir_aops has release_folio)
- **v6.12.y**: NOT affected (afs_dir_aops has release_folio)
- **v6.13.y**: NOT affected (afs_dir_aops has release_folio)
- **v6.14.y**: AFFECTED (afs_dir_aops stripped down)
- **v6.15.y+**: AFFECTED
### 5. RISK ASSESSMENT
**Risk: Very Low**
- The patch adds 3 lines - a NULL check with WARN_ON_ONCE and early
return
- It's completely self-contained, no dependencies
- `folio_buffers()` and `WARN_ON_ONCE` are available in all stable trees
- Returning `true` is correct: no buffers = nothing to free = success
- Reviewed by Jan Kara and Christian Brauner (top VFS experts)
- Could be considered pure defensive hardening in older kernels where
the trigger doesn't exist
**Benefit in affected trees (6.14+): High**
- Prevents a NULL pointer dereference crash reachable from normal memory
reclaim
- AFS symlinks with fscache enabled hitting memory pressure would crash
**Benefit in unaffected trees (6.6, 6.12): Low**
- Defensive hardening only - the specific trigger doesn't exist
- Protects against potential future similar misconfigurations if other
patches are backported
### 6. STABLE BACKPORT SUITABILITY
For trees where the bug is actually triggerable (6.14+), this is clearly
a YES - it fixes a NULL pointer dereference crash in a core kernel path
(memory reclaim). However, for older stable trees (6.6, 6.12), the bug
isn't reachable with the current code because all filesystems that set
`AS_RELEASE_ALWAYS` also properly define `release_folio`.
The fix itself is trivially small (3 lines), obviously correct, has zero
regression risk, and is well-reviewed. Even as defensive hardening, it's
the kind of patch that makes stable kernels more robust.
For the broader question of "should this be backported to stable trees":
The answer depends on which tree. For 6.14.y and later, it's an
unambiguous yes - it fixes a real crash. For 6.6.y and 6.12.y, it's
defensive hardening that prevents a crash scenario that currently isn't
reachable but could become reachable if other patches are backported.
Given the negligible risk and the fact that it hardens a core kernel
function against NULL dereference, even the older trees benefit.
**YES**
fs/buffer.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/fs/buffer.c b/fs/buffer.c
index 838c0c5710229..28e4d53f17173 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -2948,6 +2948,10 @@ bool try_to_free_buffers(struct folio *folio)
if (folio_test_writeback(folio))
return false;
+ /* Misconfigured folio check */
+ if (WARN_ON_ONCE(!folio_buffers(folio)))
+ return true;
+
if (mapping == NULL) { /* can this still happen? */
ret = drop_buffers(folio, &buffers_to_free);
goto out;
--
2.51.0
next prev parent reply other threads:[~2026-02-10 23:31 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260210233123.2905307-1-sashal@kernel.org>
2026-02-10 23:30 ` [PATCH AUTOSEL 6.19-6.18] hfsplus: fix volume corruption issue for generic/480 Sasha Levin
2026-02-10 23:30 ` Sasha Levin [this message]
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-6.12] statmount: permission check should return EPERM Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.10] hfsplus: pretend special inodes as regular files Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-5.10] hfsplus: fix volume corruption issue for generic/498 Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19-6.18] netfs: when subreq is marked for retry, do not check if it faced an error Sasha Levin
2026-02-10 23:31 ` [PATCH AUTOSEL 6.19] hfs: Replace BUG_ON with error handling for CNID count checks Sasha Levin
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=20260210233123.2905307-14-sashal@kernel.org \
--to=sashal@kernel.org \
--cc=brauner@kernel.org \
--cc=dkarn@redhat.com \
--cc=jack@suse.cz \
--cc=linux-fsdevel@vger.kernel.org \
--cc=patches@lists.linux.dev \
--cc=stable@vger.kernel.org \
--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