linux/fs/gfs2
Deepanshu Kartikey 6d76febba0 gfs2: Fix use-after-free in iomap inline data write path
[ Upstream commit faddeb8483 ]

The inline data buffer head (dibh) is being released prematurely in
gfs2_iomap_begin() via release_metapath() while iomap->inline_data
still points to dibh->b_data. This causes a use-after-free when
iomap_write_end_inline() later attempts to write to the inline data
area.

The bug sequence:
1. gfs2_iomap_begin() calls gfs2_meta_inode_buffer() to read inode
   metadata into dibh
2. Sets iomap->inline_data = dibh->b_data + sizeof(struct gfs2_dinode)
3. Calls release_metapath() which calls brelse(dibh), dropping refcount
   to 0
4. kswapd reclaims the page (~39ms later in the syzbot report)
5. iomap_write_end_inline() tries to memcpy() to iomap->inline_data
6. KASAN detects use-after-free write to freed memory

Fix by storing dibh in iomap->private and incrementing its refcount
with get_bh() in gfs2_iomap_begin(). The buffer is then properly
released in gfs2_iomap_end() after the inline write completes,
ensuring the page stays alive for the entire iomap operation.

Note: A C reproducer is not available for this issue. The fix is based
on analysis of the KASAN report and code review showing the buffer head
is freed before use.

[agruenba: Take buffer head reference in gfs2_iomap_begin() to avoid
leaks in gfs2_iomap_get() and gfs2_iomap_alloc().]

Reported-by: syzbot+ea1cd4aa4d1e98458a55@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=ea1cd4aa4d1e98458a55
Fixes: d0a22a4b03 ("gfs2: Fix iomap write page reclaim deadlock")
Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
Signed-off-by: Andreas Gruenbacher <agruenba@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
History 2026-02-26 14:58:58 -08:00
..
acl.c gfs2: convert to ctime accessor functions 2023-07-24 10:29:59 +02:00
acl.h gfs2: No longer use 'extern' in function declarations 2023-11-06 01:51:26 +01:00
aops.c iomap: pass more arguments using the iomap writeback context 2025-07-14 10:51:31 +02:00
aops.h gfs2: Don't start unnecessary transactions during log flush 2025-05-22 09:12:27 +02:00
bmap.c gfs2: Fix use-after-free in iomap inline data write path 2026-02-26 14:58:58 -08:00
bmap.h iomap: replace iomap_folio_ops with iomap_write_ops 2025-07-14 10:51:33 +02:00
dentry.c gfs2_drevalidate(): use stable parent inode and name passed by caller 2025-01-27 19:25:24 -05:00
dir.c gfs2: Validate i_depth for exhash directories 2025-07-16 15:26:44 +02:00
dir.h gfs2: No longer use 'extern' in function declarations 2023-11-06 01:51:26 +01:00
export.c exportfs: Remove EXPORT_OP_ASYNC_LOCK 2024-10-01 17:01:08 +02:00
file.c gfs2: Add proper lockspace locking 2025-09-12 12:02:57 +02:00
gfs2.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 398 2019-06-05 17:37:12 +02:00
glock.c gfs2: Retries missing in gfs2_{rename,exchange} 2026-02-26 14:58:57 -08:00
glock.h gfs2: Retries missing in gfs2_{rename,exchange} 2026-02-26 14:58:57 -08:00
glops.c gfs2: fix remote evict for read-only filesystems 2026-01-02 12:56:42 +01:00
glops.h gfs2: No longer use 'extern' in function declarations 2023-11-06 01:51:26 +01:00
incore.h gfs2: Add proper lockspace locking 2025-09-12 12:02:57 +02:00
inode.c gfs2: Retries missing in gfs2_{rename,exchange} 2026-02-26 14:58:57 -08:00
inode.h gfs2: Prevent recursive memory reclaim 2025-12-18 14:03:20 +01:00
Kconfig lib/crc: remove CONFIG_LIBCRC32C 2025-04-04 11:31:42 -07:00
lock_dlm.c dlm for 6.18 2025-09-29 15:24:58 -07:00
log.c gfs2: Don't start unnecessary transactions during log flush 2025-05-22 09:12:27 +02:00
log.h gfs2: Move gfs2_log_pointers_init 2025-05-22 09:12:27 +02:00
lops.c Revert "gfs2: Fix use of bio_chain" 2026-01-23 11:21:12 +01:00
lops.h gfs2: No more gfs2_find_jhead caching 2025-05-22 09:12:27 +02:00
main.c fs: WQ_PERCPU added to alloc_workqueue users 2025-09-19 16:15:07 +02:00
Makefile License cleanup: add SPDX GPL-2.0 license identifier to files with no license 2017-11-02 11:10:55 +01:00
meta_io.c gfs2: Set .migrate_folio in gfs2_{rgrp,meta}_aops 2025-07-15 13:10:01 +02:00
meta_io.h gfs2: replace sd_aspace with sd_inode 2025-04-21 18:20:36 +02:00
ops_fstype.c gfs2: Prevent recursive memory reclaim 2025-12-18 14:03:20 +01:00
quota.c gfs2: Fix slab-use-after-free in qd_put 2026-02-26 14:58:58 -08:00
quota.h gfs2: reorder capability check last 2024-12-09 10:44:35 +01:00
recovery.c gfs2: No more gfs2_find_jhead caching 2025-05-22 09:12:27 +02:00
recovery.h gfs2: Simplify gfs2_log_pointers_init 2025-05-22 09:12:27 +02:00
rgrp.c gfs2: Use get_random_u32 in gfs2_orlov_skip 2024-11-05 12:39:29 +01:00
rgrp.h gfs2: No longer use 'extern' in function declarations 2023-11-06 01:51:26 +01:00
super.c gfs2: fix freeze error handling 2026-01-02 12:57:08 +01:00
super.h gfs2 fixes 2023-11-07 11:54:17 -08:00
sys.c gfs2: Don't clear sb->s_fs_info in gfs2_sys_fs_add 2025-05-30 19:20:20 +02:00
sys.h treewide: Replace GPLv2 boilerplate/reference with SPDX - rule 398 2019-06-05 17:37:12 +02:00
trace_gfs2.h gfs2: Get rid of GLF_INVALIDATE_IN_PROGRESS 2025-09-12 12:02:41 +02:00
trans.c gfs2: Move gfs2_trans_add_databufs 2025-05-22 09:12:27 +02:00
trans.h gfs2: Move gfs2_trans_add_databufs 2025-05-22 09:12:27 +02:00
util.c gfs2: Sanitize gfs2_meta_check, gfs2_metatype_check, gfs2_io_error 2025-09-12 12:02:15 +02:00
util.h gfs2: Sanitize gfs2_meta_check, gfs2_metatype_check, gfs2_io_error 2025-09-12 12:02:15 +02:00
xattr.c gfs2: Move GIF_ALLOC_FAILED check out of gfs2_ea_dealloc 2025-04-21 18:20:36 +02:00
xattr.h gfs2: Move GIF_ALLOC_FAILED check out of gfs2_ea_dealloc 2025-04-21 18:20:36 +02:00