f2fs: fix to avoid mapping wrong physical block for swapfile
Key facts
- Attack vector
- Local
- Privileges required
- Low
- User interaction
- None
- Attack complexity
- Low
- Impact type
- Code execution
- Confidentiality · integrity · availability
- High · High · High
- Fix status
- Fixed
Attack profile from CVSS 3.1 · NVD. Fix status from CNA. Impact type from CWE-787 and the CVSS impact.
Summary
In the Linux kernel, the following vulnerability has been resolved: f2fs: fix to avoid mapping wrong physical block for swapfile Xiaolong Guo reported a f2fs bug in bugzilla [1] [1] https://bugzilla.kernel.org/show_bug.cgi?id=220951 Quoted: "When using stress-ng's swap stress test on F2FS filesystem with kernel 6.6+, the system experiences data corruption leading to either: 1 dm-verity corruption errors and device reboot 2 F2FS node corruption errors and boot hangs The issue occurs specifically when: 1 Using F2FS filesystem (ext4 is unaffected) 2 Swapfile size is less than F2FS section size (2MB) 3 Swapfile has fragmented physical layout (multiple non-contiguous extents) 4 Kernel version is 6.6+ (6.1 is unaffected) The root cause is in check_swap_activate() function in fs/f2fs/data.c. When the first extent of a small swapfile (< 2MB) is not aligned to section boundaries, the function incorrectly treats it as the last extent, failing to map subsequent extents. This results in incorrect swap_extent creation where only the first extent is mapped, causing subsequent swap writes to overwrite wrong physical locations (other files' data). Steps to Reproduce 1 Setup a device with F2FS-formatted userdata partition 2 Compile stress-ng from https://github.com/ColinIanKing/stress-ng 3 Run swap stress test: (Android devices) adb shell "cd /data/stressng; ./stress-ng-64 --metrics-brief --timeout 60 --swap 0" Log: 1 Ftrace shows in kernel 6.6, only first extent is mapped during second f2fs_map_blocks call in check_swap_activate(): stress-ng-swap-8990: f2fs_map_blocks: ino=11002, file offset=0, start blkaddr=0x43143, len=0x1 (Only 4KB mapped, not the full swapfile) 2 in kernel 6.1, both extents are correctly mapped: stress-ng-swap-5966: f2fs_map_blocks: ino=28011, file offset=0, start blkaddr=0x13cd4, len=0x1 stress-ng-swap-5966: f2fs_map_blocks: ino=28011, file offset=1, start blkaddr=0x60c84b, len=0xff The problematic code is in check_swap_activate(): if ((pblock - SM_I(sbi)->main_blkaddr) % blks_per_sec || nr_pblocks % blks_per_sec || !f2fs_valid_pinned_area(sbi, pblock)) { bool last_extent = false; not_aligned++; nr_pblocks = roundup(nr_pblocks, blks_per_sec); if (cur_lblock + nr_pblocks > sis->max) nr_pblocks -= blks_per_sec; /* this extent is last one */ if (!nr_pblocks) { nr_pblocks = last_lblock - cur_lblock; last_extent = true; } ret = f2fs_migrate_blocks(inode, cur_lblock, nr_pblocks); if (ret) { if (ret == -ENOENT) ret = -EINVAL; goto out; } if (!last_extent) goto retry; } When the first extent is unaligned and roundup(nr_pblocks, blks_per_sec) exceeds sis->max, we subtract blks_per_sec resulting in nr_pblocks = 0. The code then incorrectly assumes this is the last extent, sets nr_pblocks = last_lblock - cur_lblock (entire swapfile), and performs migration. After migration, it doesn't retry mapping, so subsequent extents are never processed. " In order to fix this issue, we need to lookup block mapping info after we migrate all blocks in the tail of swapfile.
Why it matters now
SSVC decision points
Not available: CISA has not published SSVC decision points for this record.
Affected products
| Vendor | Product | Affected versions | Fixed in | Status | Source |
|---|---|---|---|---|---|
| Linux | Linux | 6.6.33 to before 6.6.127 | 6.6.127 | Patch available | CNA |
| Linux | Linux | 6.9 and later | 6.6.127, 6.12.74, 6.18.13, 6.19.3, 7.0 | Patch available | CNA |
- Linux VendorLinux Affected 6.6.33 to before 6.6.127 Fixed in 6.6.127 Patch available CNA
- Linux VendorLinux Affected 6.9 and later Fixed in 6.6.127, 6.12.74, 6.18.13, 6.19.3, 7.0 Patch available CNA
CPE configurations NVD · 1
| CPE | Versions | Role | Vendor |
|---|---|---|---|
| cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* | 6.6.33 to before 6.6.127; 6.9 to before 6.12.74; 6.13 to before 6.18.13; 6.19 to before 6.19.3 | Vulnerable | Linux |
- cpe:2.3:o:linux:linux_kernel:*:*:*:*:*:*:*:* Versions 6.6.33 to before 6.6.127; 6.9 to before 6.12.74; 6.13 to before 6.18.13; 6.19 to before 6.19.3 Vulnerable ·Linux
Remediation
- Fix · CNA Linux (Linux) Fixed in 6.6.127
- Fix · CNA Linux (Linux) Fixed in 6.6.127, 6.12.74, 6.18.13, 6.19.3, 7.0
Vendor assessments
Red Hat
Not affected: 5 products
- Red Hat Enterprise Linux 10
- Red Hat Enterprise Linux 6
- Red Hat Enterprise Linux 7
- Red Hat Enterprise Linux 8
- Red Hat Enterprise Linux 9
Timeline
- 2026-10-02 Threatist record created from CVE-2026-23233
- 2026-10-03 Alias added: GHSA-p99w-mp33-jg8x
- 2026-11-07 Affected versions changed · Red Hat
References
Patch 5
- https://git.kernel.org/stable/c/d4534a7f6c92baaf7e12a45fc6e37332cafafc33
- https://git.kernel.org/stable/c/1ff415eef513bf12deb058fc50d57788c46c48e6
- https://git.kernel.org/stable/c/fee27b69dde1a05908b350eea42937af2387c4fe
- https://git.kernel.org/stable/c/607cb9d83838d2cd9f0406c2403ed61aadf0edff
- https://git.kernel.org/stable/c/5c145c03188bc9ba1c29e0bc4d527a5978fc47f9
More Linux Kernel vulnerabilities
- TI-2025-26358 tls: fix handling of zero-length records on the rx_list KEVCVSS 3.1CRITICAL 9.8
- TI-2026-38352 netfilter: bridge: make ebt_snat ARP rewrite writable KEVCVSS 3.1HIGH 8.8
- TI-2013-05264 The (1) get_user and (2) put_user API functions in the Linux kernel before 3.5.5 on the… KEVCVSS 3.1HIGH 8.8
- TI-2022-00125 Integer overflow in kernel KEVCVSS 3.1HIGH 8.4
- TI-2013-01864 The perf_swevent_init function in kernel/events/core.c in the Linux kernel before 3.8.9… KEVCVSS 3.1HIGH 8.4
- TI-2021-05514 Heap Out-Of-Bounds Write in Netfilter IP6T_SO_SET_REPLACE KEVCVSS 3.1HIGH 8.3
Sources
- CVE-2026-23233 · CVE Program
- CVE-2026-23233 · NVD
- FIRST EPSS
- GHSA-p99w-mp33-jg8x · GitHub Advisory Database · CC BY 4.0
- CVE-2026-23233 · Red Hat security data · CC BY 4.0
This product uses the NVD API but is not endorsed or certified by the NVD. Sources and licences