[BUG] Out-of-bounds write in iomap_set_range_uptodate/iomap_set_range_dirty
From: Nicholas Karwath
Date: Fri Jul 17 2026 - 06:13:57 EST
This issue was found on:
- Kernel: 7.1.3-201.fc44.x86_64 (Fedora 44)
- Arch: x86_64
- Trigger: `write(2)`
- CONFIG_FORTIFY_SOURCE: enabled
See attached kernel oops.
===========
Description
While running a test program ("ctest") that performs a small buffered write() to a file on an ntfs3-mounted NTFS volume, the kernel hit an invalid-opcode oops inside iomap_write_end(), called from the ntfs3 buffered write path:
ntfs_file_write_iter -> iomap_file_buffered_write -> iomap_write_iter -> iomap_write_end (BUG)
The write in question was very small (register state indicates count=4 bytes).
Cross testing with ntfs-3g and ntfs confirms this is ntfs3 issue, the two other drivers have no issue dealing with the write on the same disk.
========
Analysis
fs/iomap/buffered-io.c does not contain a literal BUG_ON() at this location in recent kernels; the `0f 0b` (ud2) instructions visible in the disassembly around `iomap_write_end`
are consistent with a `CONFIG_FORTIFY_SOURCE` runtime bounds-check trap (e.g. in `bitmap_set()` as called from `iomap_set_range_uptodate()`/`iomap_set_range_dirty()` while updating a folio's `iomap_folio_state` bitmap).
Fedora kernels build with `CONFIG_FORTIFY_SOURCE=y` by default, which would explain why this manifests as a hard "kernel BUG" (invalid opcode) rather than a WARN.
If it really is the trapping check, it implies the `struct iomap` returned by ntfs3's `iomap_begin` for this write described an offset/length that does not fit within
the bounds of the block-state bitmap allocated for the folio being written, i.e. `iomap->length` (or the resulting `off`/`nr_blks` computed from it) exceeds what the folio's per-block state was sized for.
The very small size of the write (4 bytes, per RDX/R12/R13/RBP holding 4) suggests this may be related to short/partial buffered writes, and/or resident (MFT-inline)
or near-EOF attribute handling in ntfs3's block-mapping (`ntfs_get_block`/iomap ops), where the mapped extent size and folio block-state bitmap size can disagree.
This appears to be the same issue as https://github.com/CachyOS/linux-cachyos/issues/841, reported independently on kernel 7.0.3-1-cachyos with an identical trace (kernel BUG at fs/iomap/buffered-io.c:1061 in iomap_write_end, same call chain through ntfs_file_write_iter).
Continues the discussion from:
https://bugzilla.kernel.org/show_bug.cgi?id=221725
(That report was filed on the kernel.org bugzilla and I was asked to move discussion to this list instead.)
[ 512.333427] ------------[ cut here ]------------[ 512.333431] kernel BUG at fs/iomap/buffered-io.c:1061!
[ 512.333439] Oops: invalid opcode: 0000 [#1] SMP NOPTI
[ 512.333444] CPU: 0 UID: 1001 PID: 7212 Comm: ctest Tainted: G OE 7.0.4-200.fc44.x86_64 #1 PREEMPT(lazy)
[ 512.333449] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[ 512.333450] Hardware name: Micro-Star International Co., Ltd. MS-7C92/MPG B550I GAMING EDGE WIFI (MS-7C92), BIOS 1.62 04/09/2021
[ 512.333453] RIP: 0010:iomap_write_end+0x1d3/0x1e0
[ 512.333459] Code: 8b 03 48 c1 e8 03 83 e0 01 74 10 e9 a7 fe ff ff 0f 0b eb 83 0f 0b e9 5e ff ff ff 4c 8b 74 24 28 e9 21 ff ff ff 4c 89 74 24 28 <0f> 0b 0f 0b 31 c0 e9 11 ff ff ff 66 90 90 90 90 90 90 90 90 90 90
[ 512.333462] RSP: 0018:ffffcdc49a6b3b80 EFLAGS: 00010297
[ 512.333465] RAX: 0000000000000040 RBX: ffffee24cedc66c0 RCX: ffffee24cedc66c0
[ 512.333467] RDX: 0000000000000fc0 RSI: 0000000000000004 RDI: ffff8a7091a72fc0
[ 512.333469] RBP: 0000000000000004 R08: ffffcdc49a6b3c40 R09: 00000000000000b4
[ 512.333471] R10: 0000000000000004 R11: 00000000000000b4 R12: 0000000000000004
[ 512.333473] R13: 0000000000000004 R14: 0000000000000000 R15: ffffcdc49a6b3c40
[ 512.333475] FS: 00007fd7d3359580(0000) GS:ffff8a77f829c000(0000) knlGS:0000000000000000
[ 512.333477] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 512.333479] CR2: 000000002ed84ff8 CR3: 000000044cd92000 CR4: 0000000000f50ef0
[ 512.333481] PKRU: 55555554
[ 512.333483] Call Trace:
[ 512.333486] <TASK>
[ 512.333489] iomap_write_iter+0x177/0x340
[ 512.333498] iomap_file_buffered_write+0xc7/0x130
[ 512.333504] ntfs_file_write_iter+0x26e/0x310 [ntfs3]
[ 512.333516] ? srso_alias_return_thunk+0x5/0xfbef5
[ 512.333522] vfs_write+0x281/0x570
[ 512.333529] ksys_write+0x7b/0x110
[ 512.333533] do_syscall_64+0x109/0x6e0
[ 512.333540] ? srso_alias_return_thunk+0x5/0xfbef5
[ 512.333543] ? handle_mm_fault+0x248/0x330
[ 512.333549] ? srso_alias_return_thunk+0x5/0xfbef5
[ 512.333552] ? do_user_addr_fault+0x2cd/0x830
[ 512.333557] ? srso_alias_return_thunk+0x5/0xfbef5
[ 512.333559] ? irqentry_exit+0x7b/0x560
[ 512.333563] ? exc_page_fault+0x90/0x1f0
[ 512.333566] ? srso_alias_return_thunk+0x5/0xfbef5
[ 512.333569] entry_SYSCALL_64_after_hwframe+0x76/0x7e
[ 512.333572] RIP: 0033:0x7fd7d33ca08e
[ 512.333594] Code: 4d 89 d8 e8 94 bd 00 00 4c 8b 5d f8 41 8b 93 08 03 00 00 59 5e 48 83 f8 fc 74 11 c9 c3 0f 1f 80 00 00 00 00 48 8b 45 10 0f 05 <c9> c3 83 e2 39 83 fa 08 75 e7 e8 03 ff ff ff 0f 1f 00 f3 0f 1e fa
[ 512.333597] RSP: 002b:00007ffed2e83d70 EFLAGS: 00000202 ORIG_RAX: 0000000000000001
[ 512.333600] RAX: ffffffffffffffda RBX: 0000000000000004 RCX: 00007fd7d33ca08e
[ 512.333602] RDX: 0000000000000004 RSI: 000000002edcee20 RDI: 000000000000000f
[ 512.333603] RBP: 00007ffed2e83d80 R08: 0000000000000000 R09: 0000000000000000
[ 512.333605] R10: 0000000000000000 R11: 0000000000000202 R12: 000000000000000f
[ 512.333607] R13: 0000000000000004 R14: 00007fd7d36b63f0 R15: 00007ffed2e84298
[ 512.333612] </TASK>
[ 512.333613] Modules linked in: overlay nvidia_uvm(OE) rfcomm snd_seq_dummy snd_hrtimer ovpn ip6_udp_tunnel udp_tunnel uhid xt_connmark xt_conntrack xt_MASQUERADE xt_mark tun nf_conntrack_netbios_ns nf_conntrack_broadcast nft_fib_inet nft_fib_ipv4 nft_fib_ipv6 nft_fib nft_ct ip6table_nat ip6table_mangle ip6table_r>
[ 512.333693] snd_pcm joydev r8169 drm_ttm_helper i2c_piix4 ttm pcspkr realtek i2c_smbus video k10temp snd_timer rfkill snd gpio_amdpt soundcore gpio_generic nft_reject_inet nf_reject_ipv4 nf_reject_ipv6 nft_reject nft_chain_nat nf_nat nf_conntrack nf_defrag_ipv6 nf_defrag_ipv4 nf_tables dm_multipath nfnetlink zra>
[ 512.333756] ---[ end trace 0000000000000000 ]---
[ 512.333759] RIP: 0010:iomap_write_end+0x1d3/0x1e0
[ 512.333762] Code: 8b 03 48 c1 e8 03 83 e0 01 74 10 e9 a7 fe ff ff 0f 0b eb 83 0f 0b e9 5e ff ff ff 4c 8b 74 24 28 e9 21 ff ff ff 4c 89 74 24 28 <0f> 0b 0f 0b 31 c0 e9 11 ff ff ff 66 90 90 90 90 90 90 90 90 90 90
[ 512.333764] RSP: 0018:ffffcdc49a6b3b80 EFLAGS: 00010297
[ 512.333767] RAX: 0000000000000040 RBX: ffffee24cedc66c0 RCX: ffffee24cedc66c0
[ 512.333769] RDX: 0000000000000fc0 RSI: 0000000000000004 RDI: ffff8a7091a72fc0
[ 512.333770] RBP: 0000000000000004 R08: ffffcdc49a6b3c40 R09: 00000000000000b4
[ 512.333772] R10: 0000000000000004 R11: 00000000000000b4 R12: 0000000000000004
[ 512.333774] R13: 0000000000000004 R14: 0000000000000000 R15: ffffcdc49a6b3c40
[ 512.333776] FS: 00007fd7d3359580(0000) GS:ffff8a77f829c000(0000) knlGS:0000000000000000
[ 512.333778] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 512.333780] CR2: 000000002ed84ff8 CR3: 000000044cd92000 CR4: 0000000000f50ef0
[ 512.333782] PKRU: 55555554
Attachment:
OpenPGP_signature.asc
Description: OpenPGP digital signature