* [PATCH RFC] fs/buffer: fix use-after-free when call bh_read() helper
@ 2025-08-11 14:18 Ye Bin
2025-08-11 15:21 ` Matthew Wilcox
2025-08-15 14:29 ` Christian Brauner
0 siblings, 2 replies; 3+ messages in thread
From: Ye Bin @ 2025-08-11 14:18 UTC (permalink / raw)
To: viro, brauner, jack, linux-fsdevel, yebin, yebin10
From: Ye Bin <yebin10@huawei.com>
There's issue as follows:
BUG: KASAN: stack-out-of-bounds in end_buffer_read_sync+0xe3/0x110
Read of size 8 at addr ffffc9000168f7f8 by task swapper/3/0
CPU: 3 UID: 0 PID: 0 Comm: swapper/3 Not tainted 6.16.0-862.14.0.6.x86_64
Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
Call Trace:
<IRQ>
dump_stack_lvl+0x55/0x70
print_address_description.constprop.0+0x2c/0x390
print_report+0xb4/0x270
kasan_report+0xb8/0xf0
end_buffer_read_sync+0xe3/0x110
end_bio_bh_io_sync+0x56/0x80
blk_update_request+0x30a/0x720
scsi_end_request+0x51/0x2b0
scsi_io_completion+0xe3/0x480
? scsi_device_unbusy+0x11e/0x160
blk_complete_reqs+0x7b/0x90
handle_softirqs+0xef/0x370
irq_exit_rcu+0xa5/0xd0
sysvec_apic_timer_interrupt+0x6e/0x90
</IRQ>
Above issue happens when do ntfs3 filesystem mount, issue may happens
as follows:
mount IRQ
ntfs_fill_super
read_cache_page
do_read_cache_folio
filemap_read_folio
mpage_read_folio
do_mpage_readpage
ntfs_get_block_vbo
bh_read
submit_bh
wait_on_buffer(bh);
blk_complete_reqs
scsi_io_completion
scsi_end_request
blk_update_request
end_bio_bh_io_sync
end_buffer_read_sync
__end_buffer_read_notouch
unlock_buffer
wait_on_buffer(bh);--> return will return to caller
put_bh
--> trigger stack-out-of-bounds
In the mpage_read_folio() function, the stack variable 'map_bh' is
passed to ntfs_get_block_vbo(). Once unlock_buffer() unlocks and
wait_on_buffer() returns to continue processing, the stack variable
is likely to be reclaimed. Consequently, during the end_buffer_read_sync()
process, calling put_bh() may result in stack overrun.
If it is not a stack variable, since the reference count of the
buffer_head is released after unlocking, it cannot be released during
drop_buffers. This poses a risk of buffer_head leakage.
To solve above issue first call put_bh() before unlock_buffer. This
should be safe because during the release, discard_buffer() will call
lock_buffer().
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Ye Bin <yebin10@huawei.com>
---
fs/buffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/buffer.c b/fs/buffer.c
index ead4dc85debd..6a8752f7bbed 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -157,8 +157,8 @@ static void __end_buffer_read_notouch(struct buffer_head *bh, int uptodate)
*/
void end_buffer_read_sync(struct buffer_head *bh, int uptodate)
{
- __end_buffer_read_notouch(bh, uptodate);
put_bh(bh);
+ __end_buffer_read_notouch(bh, uptodate);
}
EXPORT_SYMBOL(end_buffer_read_sync);
--
2.34.1
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH RFC] fs/buffer: fix use-after-free when call bh_read() helper
2025-08-11 14:18 [PATCH RFC] fs/buffer: fix use-after-free when call bh_read() helper Ye Bin
@ 2025-08-11 15:21 ` Matthew Wilcox
2025-08-15 14:29 ` Christian Brauner
1 sibling, 0 replies; 3+ messages in thread
From: Matthew Wilcox @ 2025-08-11 15:21 UTC (permalink / raw)
To: Ye Bin; +Cc: viro, brauner, jack, linux-fsdevel, yebin10
On Mon, Aug 11, 2025 at 10:18:30PM +0800, Ye Bin wrote:
> From: Ye Bin <yebin10@huawei.com>
>
> There's issue as follows:
> BUG: KASAN: stack-out-of-bounds in end_buffer_read_sync+0xe3/0x110
> Read of size 8 at addr ffffc9000168f7f8 by task swapper/3/0
> CPU: 3 UID: 0 PID: 0 Comm: swapper/3 Not tainted 6.16.0-862.14.0.6.x86_64
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
> Call Trace:
> <IRQ>
> dump_stack_lvl+0x55/0x70
> print_address_description.constprop.0+0x2c/0x390
> print_report+0xb4/0x270
> kasan_report+0xb8/0xf0
> end_buffer_read_sync+0xe3/0x110
> end_bio_bh_io_sync+0x56/0x80
> blk_update_request+0x30a/0x720
> scsi_end_request+0x51/0x2b0
> scsi_io_completion+0xe3/0x480
> ? scsi_device_unbusy+0x11e/0x160
> blk_complete_reqs+0x7b/0x90
> handle_softirqs+0xef/0x370
> irq_exit_rcu+0xa5/0xd0
> sysvec_apic_timer_interrupt+0x6e/0x90
> </IRQ>
>
> Above issue happens when do ntfs3 filesystem mount, issue may happens
> as follows:
> mount IRQ
> ntfs_fill_super
> read_cache_page
> do_read_cache_folio
> filemap_read_folio
> mpage_read_folio
> do_mpage_readpage
> ntfs_get_block_vbo
> bh_read
> submit_bh
> wait_on_buffer(bh);
> blk_complete_reqs
> scsi_io_completion
> scsi_end_request
> blk_update_request
> end_bio_bh_io_sync
> end_buffer_read_sync
> __end_buffer_read_notouch
> unlock_buffer
>
> wait_on_buffer(bh);--> return will return to caller
>
> put_bh
> --> trigger stack-out-of-bounds
> In the mpage_read_folio() function, the stack variable 'map_bh' is
> passed to ntfs_get_block_vbo(). Once unlock_buffer() unlocks and
> wait_on_buffer() returns to continue processing, the stack variable
> is likely to be reclaimed. Consequently, during the end_buffer_read_sync()
> process, calling put_bh() may result in stack overrun.
All good to here.
> If it is not a stack variable, since the reference count of the
> buffer_head is released after unlocking, it cannot be released during
> drop_buffers. This poses a risk of buffer_head leakage.
> To solve above issue first call put_bh() before unlock_buffer. This
> should be safe because during the release, discard_buffer() will call
> lock_buffer().
I find this part of the explanation hard to follow and I thought there
was a mistake here. However after tracing through what would happen in
gfs2_metapath_ra() and __ext4_sb_bread_gfp(), I don't see a problem.
So here's a replacement paragraph:
If the bh is not allocated on the stack, it belongs to a folio. Freeing a
buffer head which belongs to a folio is done by drop_buffers() which
will fail to free buffers which are still locked. So it is safe to call
put_bh() before __end_buffer_read_notouch().
Reviewed-by: Matthew Wilcox (Oracle) <willy@infradead.org>
I'll also note that we have a bunch of weird corruptions with ntfs3
and this might explain them. Also this isn't really an ntfs3 bug,
but ntfs3 might be the only in-tree filesystem which happens to use
map_bh like this. It's bad for performance to do it this way, but
if all you're trying to do is get a working filesystem, this is a
simple way to do things.
> Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> Signed-off-by: Ye Bin <yebin10@huawei.com>
> ---
> fs/buffer.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/fs/buffer.c b/fs/buffer.c
> index ead4dc85debd..6a8752f7bbed 100644
> --- a/fs/buffer.c
> +++ b/fs/buffer.c
> @@ -157,8 +157,8 @@ static void __end_buffer_read_notouch(struct buffer_head *bh, int uptodate)
> */
> void end_buffer_read_sync(struct buffer_head *bh, int uptodate)
> {
> - __end_buffer_read_notouch(bh, uptodate);
> put_bh(bh);
> + __end_buffer_read_notouch(bh, uptodate);
> }
> EXPORT_SYMBOL(end_buffer_read_sync);
>
> --
> 2.34.1
>
>
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH RFC] fs/buffer: fix use-after-free when call bh_read() helper
2025-08-11 14:18 [PATCH RFC] fs/buffer: fix use-after-free when call bh_read() helper Ye Bin
2025-08-11 15:21 ` Matthew Wilcox
@ 2025-08-15 14:29 ` Christian Brauner
1 sibling, 0 replies; 3+ messages in thread
From: Christian Brauner @ 2025-08-15 14:29 UTC (permalink / raw)
To: Ye Bin; +Cc: Christian Brauner, viro, jack, linux-fsdevel, yebin10
On Mon, 11 Aug 2025 22:18:30 +0800, Ye Bin wrote:
> There's issue as follows:
> BUG: KASAN: stack-out-of-bounds in end_buffer_read_sync+0xe3/0x110
> Read of size 8 at addr ffffc9000168f7f8 by task swapper/3/0
> CPU: 3 UID: 0 PID: 0 Comm: swapper/3 Not tainted 6.16.0-862.14.0.6.x86_64
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996)
> Call Trace:
> <IRQ>
> dump_stack_lvl+0x55/0x70
> print_address_description.constprop.0+0x2c/0x390
> print_report+0xb4/0x270
> kasan_report+0xb8/0xf0
> end_buffer_read_sync+0xe3/0x110
> end_bio_bh_io_sync+0x56/0x80
> blk_update_request+0x30a/0x720
> scsi_end_request+0x51/0x2b0
> scsi_io_completion+0xe3/0x480
> ? scsi_device_unbusy+0x11e/0x160
> blk_complete_reqs+0x7b/0x90
> handle_softirqs+0xef/0x370
> irq_exit_rcu+0xa5/0xd0
> sysvec_apic_timer_interrupt+0x6e/0x90
> </IRQ>
>
> [...]
Applied to the vfs.fixes branch of the vfs/vfs.git tree.
Patches in the vfs.fixes branch should appear in linux-next soon.
Please report any outstanding bugs that were missed during review in a
new review to the original patch series allowing us to drop it.
It's encouraged to provide Acked-bys and Reviewed-bys even though the
patch has now been applied. If possible patch trailers will be updated.
Note that commit hashes shown below are subject to change due to rebase,
trailer updates or similar. If in doubt, please check the listed branch.
tree: https://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs.git
branch: vfs.fixes
[1/1] fs/buffer: fix use-after-free when call bh_read() helper
https://git.kernel.org/vfs/vfs/c/fb6d0f63f46d
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2025-08-15 14:30 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-08-11 14:18 [PATCH RFC] fs/buffer: fix use-after-free when call bh_read() helper Ye Bin
2025-08-11 15:21 ` Matthew Wilcox
2025-08-15 14:29 ` Christian Brauner
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).