linux/fs/ocfs2
Joseph Qi 7bc5da4842 ocfs2: fix out-of-bounds write in ocfs2_write_end_inline
KASAN reports a use-after-free write of 4086 bytes in
ocfs2_write_end_inline, called from ocfs2_write_end_nolock during a
copy_file_range splice fallback on a corrupted ocfs2 filesystem mounted on
a loop device.  The actual bug is an out-of-bounds write past the inode
block buffer, not a true use-after-free.  The write overflows into an
adjacent freed page, which KASAN reports as UAF.

The root cause is that ocfs2_try_to_write_inline_data trusts the on-disk
id_count field to determine whether a write fits in inline data.  On a
corrupted filesystem, id_count can exceed the physical maximum inline data
capacity, causing writes to overflow the inode block buffer.

Call trace (crash path):

   vfs_copy_file_range (fs/read_write.c:1634)
     do_splice_direct
       splice_direct_to_actor
         iter_file_splice_write
           ocfs2_file_write_iter
             generic_perform_write
               ocfs2_write_end
                 ocfs2_write_end_nolock (fs/ocfs2/aops.c:1949)
                   ocfs2_write_end_inline (fs/ocfs2/aops.c:1915)
                     memcpy_from_folio     <-- KASAN: write OOB

So add id_count upper bound check in ocfs2_validate_inode_block() to
alongside the existing i_size check to fix it.

Link: https://lkml.kernel.org/r/20260403063830.3662739-1-joseph.qi@linux.alibaba.com
Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
Reported-by: syzbot+62c1793956716ea8b28a@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=62c1793956716ea8b28a
Cc: Mark Fasheh <mark@fasheh.com>
Cc: Joel Becker <jlbec@evilplan.org>
Cc: Junxiao Bi <junxiao.bi@oracle.com>
Cc: Changwei Ge <gechangwei@live.cn>
Cc: Jun Piao <piaojun@huawei.com>
Cc: Heming Zhao <heming.zhao@suse.com>
Cc: <stable@vger.kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
2026-04-06 11:13:43 -07:00
..
cluster Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
dlm Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
dlmfs treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
acl.c fs: inline current_umask() and move it to fs_struct.h 2025-11-05 22:51:23 +01:00
acl.h
alloc.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
alloc.h ocfs2: convert ocfs2_map_and_dirty_page() to ocfs2_map_and_dirty_folio() 2025-01-12 20:21:13 -08:00
aops.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
aops.h ocfs2: remove ocfs2_start_walk_page_trans() prototype 2025-01-12 20:21:13 -08:00
blockcheck.c
blockcheck.h
buffer_head_io.c ocfs2: convert remaining read-only checks to ocfs2_emergency_state 2025-12-10 16:07:43 -08:00
buffer_head_io.h
dcache.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
dcache.h
dir.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
dir.h
dlmglue.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
dlmglue.h ocfs2: convert ocfs2_inode_lock_with_page() to ocfs2_inode_lock_with_folio() 2025-01-12 20:21:10 -08:00
export.c ocfs2: detect released suballocator BG for fh_to_[dentry|parent] 2026-01-20 19:44:16 -08:00
export.h
extent_map.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
extent_map.h
file.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
file.h ocfs2: store cookie in private data 2024-09-12 11:58:44 +02:00
filecheck.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
filecheck.h
heartbeat.c
heartbeat.h
inode.c ocfs2: fix out-of-bounds write in ocfs2_write_end_inline 2026-04-06 11:13:43 -07:00
inode.h ocfs2: retire ocfs2_drop_inode() and I_WILL_FREE usage 2025-10-20 20:22:25 +02:00
ioctl.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
ioctl.h tree-wide: s/struct fileattr/struct file_kattr/g 2025-07-04 16:14:39 +02:00
journal.c Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
journal.h ocfs2: stop quota recovery before disabling quotas 2025-05-07 23:39:40 -07:00
Kconfig
localalloc.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
localalloc.h
locks.c ocfs2: adapt to breakup of struct file_lock 2024-02-05 13:11:43 +01:00
locks.h
Makefile
mmap.c fs: replace mmap hook with .mmap_prepare for simple mappings 2025-06-19 13:56:59 +02:00
mmap.h fs: replace mmap hook with .mmap_prepare for simple mappings 2025-06-19 13:56:59 +02:00
move_extents.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
move_extents.h
namei.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
namei.h
ocfs1_fs_compat.h
ocfs2_fs.h ocfs2: annotate more flexible array members with __counted_by_le() 2026-01-20 19:44:18 -08:00
ocfs2_ioctl.h ocfs2: miscellaneous spelling fixes 2025-01-12 20:21:07 -08:00
ocfs2_lockid.h ocfs2: miscellaneous spelling fixes 2025-01-12 20:21:07 -08:00
ocfs2_lockingver.h
ocfs2_trace.h ocfs2: retire ocfs2_drop_inode() and I_WILL_FREE usage 2025-10-20 20:22:25 +02:00
ocfs2.h ocfs2: add ocfs2_emergency_state helper and apply to setattr 2025-12-10 16:07:43 -08:00
quota_global.c ocfs2: remove reference to bh->b_page 2025-03-16 23:24:13 -07:00
quota_local.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
quota.h ocfs2: remove unused declaration in header file 2024-11-05 17:12:26 -08:00
refcounttree.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
refcounttree.h
reservations.c ocfs2: correctly use ocfs2_find_next_zero_bit() 2024-04-25 21:07:01 -07:00
reservations.h ocfs2: miscellaneous spelling fixes 2025-01-12 20:21:07 -08:00
resize.c ocfs2: convert remaining read-only checks to ocfs2_emergency_state 2025-12-10 16:07:43 -08:00
resize.h
slot_map.c Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
slot_map.h
stack_o2cb.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
stack_user.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
stackglue.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
stackglue.h ocfs2: miscellaneous spelling fixes 2025-01-12 20:21:07 -08:00
suballoc.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
suballoc.h ocfs2: fix the issue with discontiguous allocation in the global_bitmap 2025-05-07 23:39:37 -07:00
super.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
super.h
symlink.c ocfs2: use a folio in ocfs2_fast_symlink_read_folio() 2025-01-12 20:21:13 -08:00
symlink.h
sysfile.c ocfs2: avoid extra calls to strlen() after ocfs2_sprintf_system_inode_name() 2025-09-22 20:11:00 -07:00
sysfile.h
uptodate.c
uptodate.h
xattr.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
xattr.h