In the Linux kernel, the following vulnerability has been resolved:
mm/swap: fix race when skipping swapcache
When skipping swapcache for SWP_SYNCHRONOUS_IO, if two or more threads swapin the same entry at the same time, they get different pages (A, B). Before one thread (T0) finishes the swapin and installs page (A) to the PTE, another thread (T1) could finish swapin of page (B), swap_free the entry, then swap out the possibly modified page reusing the same entry. It breaks the pte_same check in (T0) because PTE value is unchanged, causing ABA problem. Thread (T0) will install a stalled page (A) into the PTE and cause data corruption.
One possible callstack is like this:
CPU0 CPU1 ---- ---- do_swap_page() do_swap_page() with same entry <direct swapin path> <direct swapin path> <alloc page A> <alloc page B> swap_read_folio() <- read to page A swap_read_folio() <- read to page B <slow on later locks or interrupt> <finished swapin first> ... set_pte_at() swap_free() <- entry is free <write to page B, now page A stalled> <swap out page B to same swap entry> pte_same() <- Check pass, PTE seems unchanged, but page A is stalled! swap_free() <- page B content lost! set_pte_at() <- staled page A installed!
And besides, for ZRAM, swap_free() allows the swap device to discard the entry content, so even if page (B) is not modified, if swap_read_folio() on CPU0 happens later than swap_free() on CPU1, it may also cause data loss.
To fix this, reuse swapcache_prepare which will pin the swap entry using the cache flag, and allow only one thread to swap it in, also prevent any parallel code from putting the entry in the cache. Release the pin after PT unlocked.
Racers just loop and wait since it's a rare and very short event. A schedule_timeout_uninterruptible(1) call is added to avoid repeated page faults wasting too much CPU, causing livelock or adding too much noise to perf statistics. A similar livelock issue was described in commit 029c4628b2eb ("mm: swap: get rid of livelock in swapin readahead")
Reproducer:
This race issue can be triggered easily using a well constructed reproducer and patched brd (with a delay in read path) [1]:
With latest 6.8 mainline, race caused data loss can be observed easily: $ gcc -g -lpthread test-thread-swap-race.c && ./a.out Polulating 32MB of memory region... Keep swapping out... Starting round 0... Spawning 65536 workers... 32746 workers spawned, wait for done... Round 0: Error on 0x5aa00, expected 32746, got 32743, 3 data loss! Round 0: Error on 0x395200, expected 32746, got 32743, 3 data loss! Round 0: Error on 0x3fd000, expected 32746, got 32737, 9 data loss! Round 0 Failed, 15 data loss!
This reproducer spawns multiple threads sharing the same memory region using a small swap device. Every two threads updates mapped pages one by one in opposite direction trying to create a race, with one dedicated thread keep swapping out the data out using madvise.
The reproducer created a reproduce rate of about once every 5 minutes, so the race should be totally possible in production.
After this patch, I ran the reproducer for over a few hundred rounds and no data loss observed.
Performance overhead is minimal, microbenchmark swapin 10G from 32G zram:
Before: 10934698 us After: 11157121 us Cached: 13155355 us (Dropping SWP_SYNCHRONOUS_IO flag)
[[email protected]: v4]
| Product | Vendor Advisory | Solution File | Added | Published |
|---|---|---|---|---|
| Alma_linux | — | Upgrade kernel-debugUpgrade kernel-zfcpdump-modules-extraUpgrade kernel-debug-coreUpgrade kernel-docUpgrade kernel-modules-extraUpgrade kernel-modulesUpgrade kernel-rt-modulesUpgrade kernel-rtUpgrade perfUpgrade python3-perfUpgrade kernel-zfcpdump-develUpgrade kernel-rt-debug-modules-extraUpgrade kernel-zfcpdump-coreUpgrade kernel-develUpgrade kernel-zfcpdumpUpgrade kernel-rt-debug-kvmUpgrade kernel-coreUpgrade kernel-rt-debug-modulesUpgrade kernel-toolsUpgrade kernel-rt-debug-develUpgrade kernel-tools-libs-develUpgrade bpftoolUpgrade kernel-tools-libsUpgrade kernel-cross-headersUpgrade kernel-headersUpgrade kernel-rt-modules-extraUpgrade kernel-debug-modules-extraUpgrade kernel-rt-debugUpgrade kernel-zfcpdump-modulesUpgrade kernel-rt-coreUpgrade kernel-rt-debug-coreUpgrade kernel-rt-kvmUpgrade kernel-abi-stablelistsUpgrade kernel-debug-develUpgrade kernelUpgrade kernel-rt-develUpgrade kernel-debug-modules | Jul 3, 2024 | Apr 3, 2024 |
| Amazon_linux_2023 | — | Upgrade kernel-libbpf-develUpgrade kernel-debuginfo-common-x86_64Upgrade kernel-livepatch-6.1.82-99.168Upgrade kernel-headersUpgrade bpftool-debuginfoUpgrade kernelUpgrade kernel-libbpf-staticUpgrade kernel-modules-extra-commonUpgrade kernel-debuginfo-common-aarch64Upgrade kernel-toolsUpgrade perfUpgrade python3-perf-debuginfoUpgrade kernel-debuginfoUpgrade kernel-tools-develUpgrade kernel-libbpfUpgrade kernel-tools-debuginfoUpgrade bpftoolUpgrade python3-perfUpgrade perf-debuginfoUpgrade kernel-modules-extraUpgrade kernel-devel | Feb 17, 2025 | Apr 3, 2024 |
| Debian | — | Upgrade linux | Jul 30, 2024 | Apr 3, 2024 |
| Huawei Euleros 2_0_sp10 | — | Upgrade kernel-toolsUpgrade kernel-abi-stablelistsUpgrade python3-perfUpgrade kernel-tools-libsUpgrade kernel | Jul 16, 2024 | Apr 3, 2024 |
| Huawei Euleros 2_0_sp11 | — | Upgrade kernel-toolsUpgrade bpftoolUpgrade kernelUpgrade python3-perfUpgrade kernel-tools-libsUpgrade kernel-abi-stablelists | Jun 26, 2024 | Apr 3, 2024 |
| Huawei Euleros 2_0_sp12 | — | Upgrade kernel-abi-stablelistsUpgrade bpftoolUpgrade kernel-tools-libsUpgrade kernelUpgrade python3-perfUpgrade kernel-tools | Oct 8, 2024 | Apr 3, 2024 |
| Huawei Euleros 2_0_sp8 | — | Upgrade kernelUpgrade kernel-headersUpgrade kernel-tools-libsUpgrade bpftoolUpgrade python3-perfUpgrade perfUpgrade kernel-develUpgrade python-perfUpgrade kernel-tools | Jul 23, 2024 | Apr 3, 2024 |
| Huawei Euleros 2_0_sp9 | — | Upgrade kernel-toolsUpgrade kernelUpgrade kernel-tools-libsUpgrade python3-perf | Jul 17, 2024 | Apr 3, 2024 |
| Oracle_linux | — | Upgrade kernel | Jul 3, 2024 | Apr 3, 2024 |
| Redhat_linux | — | No solution existsUpgrade kernelUpgrade kernel-rt | Jul 3, 2024 | Apr 3, 2024 |
| Rocky_linux | — | Upgrade kernel-rt-debug-modules-extraUpgrade kernel-tools-libs-develUpgrade kernel-rt-debug-modulesUpgrade kernel-rt-kvmUpgrade python3-perf-debuginfoUpgrade kernel-debug-debuginfoUpgrade kernel-develUpgrade kernel-rt-debugUpgrade kernel-rt-develUpgrade kernel-rt-modulesUpgrade bpftoolUpgrade kernel-rtUpgrade perf-debuginfoUpgrade kernel-rt-debuginfoUpgrade bpftool-debuginfoUpgrade perfUpgrade kernel-toolsUpgrade kernelUpgrade kernel-debug-modules-extraUpgrade kernel-debug-modulesUpgrade kernel-tools-libsUpgrade kernel-tools-debuginfoUpgrade kernel-debuginfoUpgrade kernel-headersUpgrade kernel-debugUpgrade kernel-modules-extraUpgrade kernel-debug-coreUpgrade kernel-coreUpgrade kernel-rt-coreUpgrade kernel-rt-debug-coreUpgrade kernel-rt-debuginfo-common-x86_64Upgrade kernel-rt-debug-kvmUpgrade kernel-debuginfo-common-x86_64Upgrade kernel-modulesUpgrade kernel-rt-debug-develUpgrade kernel-rt-modules-extraUpgrade kernel-rt-debug-debuginfoUpgrade kernel-debug-develUpgrade kernel-cross-headersUpgrade python3-perf | Jul 16, 2024 | Apr 3, 2024 |
| Suse | — | Upgrade kernel-azure-optionalUpgrade kernel-debug-vdsoUpgrade kernel-kvmsmallUpgrade gfs2-kmp-rtUpgrade reiserfs-kmp-64kbUpgrade kernel-devel-azureUpgrade gfs2-kmp-azureUpgrade kernel-64kbUpgrade kselftests-kmp-azureUpgrade dtb-xilinxUpgrade cluster-md-kmp-rtUpgrade kernel-rt-livepatchUpgrade dtb-exynosUpgrade gfs2-kmp-64kbUpgrade kernel-source-rtUpgrade kernel-rt_debug-develUpgrade dtb-alteraUpgrade kernel-default-livepatchUpgrade dtb-caviumUpgrade kernel-64kb-optionalUpgrade kernel-azureUpgrade kernel-64kb-develUpgrade kernel-symsUpgrade kernel-default-base-rebuildUpgrade kernel-rt-develUpgrade ocfs2-kmp-64kbUpgrade kernel-kvmsmall-develUpgrade dtb-broadcomUpgrade kernel-rt-optionalUpgrade kernel-zfcpdumpUpgrade dtb-lgUpgrade kernel-develUpgrade kernel-azure-livepatch-develUpgrade kernel-default-vdsoUpgrade dlm-kmp-64kbUpgrade dtb-freescaleUpgrade kselftests-kmp-64kbUpgrade ocfs2-kmp-defaultUpgrade cluster-md-kmp-azureUpgrade kernel-kvmsmall-livepatch-develUpgrade kernel-64kb-livepatch-develUpgrade kernel-syms-azureUpgrade dtb-allwinnerUpgrade kernel-devel-rtUpgrade kernel-source-azureUpgrade dtb-amazonUpgrade kernel-rtUpgrade kernel-default-develUpgrade kernel-sourceUpgrade kernel-azure-develUpgrade kernel-source-vanillaUpgrade ocfs2-kmp-rtUpgrade dtb-qcomUpgrade kernel-default-optionalUpgrade ocfs2-kmp-azureUpgrade kernel-rt-vdsoUpgrade dtb-rockchipUpgrade kselftests-kmp-defaultUpgrade dtb-socionextUpgrade cluster-md-kmp-64kbUpgrade kernel-azure-extraUpgrade kernel-syms-rtUpgrade dtb-mediatekUpgrade dtb-amlogicUpgrade kernel-azure-vdsoUpgrade dtb-armUpgrade kernel-debug-develUpgrade dtb-apmUpgrade kernel-rt_debugUpgrade dtb-hisiliconUpgrade kernel-docs-htmlUpgrade kernel-docsUpgrade dtb-nvidiaUpgrade dlm-kmp-defaultUpgrade cluster-md-kmp-defaultUpgrade kernel-macrosUpgrade kernel-debugUpgrade dtb-amdUpgrade kernel-kvmsmall-vdsoUpgrade dtb-sprdUpgrade kernel-rt-livepatch-develUpgrade kernel-rt-extraUpgrade kernel-obs-buildUpgrade kernel-default-extraUpgrade dtb-renesasUpgrade reiserfs-kmp-rtUpgrade reiserfs-kmp-defaultUpgrade kernel-rt_debug-livepatch-develUpgrade kernel-obs-qaUpgrade kernel-default-livepatch-develUpgrade dtb-appleUpgrade dlm-kmp-rtUpgrade reiserfs-kmp-azureUpgrade kernel-rt_debug-vdsoUpgrade dlm-kmp-azureUpgrade kernel-debug-livepatch-develUpgrade kernel-64kb-extraUpgrade kselftests-kmp-rtUpgrade kernel-defaultUpgrade gfs2-kmp-defaultUpgrade dtb-marvellUpgrade kernel-default-base | Dec 5, 2025 | Oct 8, 2024 |
| Ubuntu | — | Upgrade linux-raspi-realtime | Feb 11, 2025 | Apr 3, 2024 |
| Vmware Photon_os | — | Use 'tdnf update' to upgrade all packages to the latest version. | Oct 14, 2025 | Apr 3, 2024 |
With curated Threat Intelligence, you can see which vulnerabilities truly put you at risk, prioritize what matters most, and act before attackers do.
Explore Intelligence Hub