CVE-2026-97945
Executive Summary
CVE-2026-97945 is a data-integrity defect in the Linux kernel x86 memory-management subsystem. The pmd_modify() helper strips the hardware dirty bit (_PAGE_DIRTY) from PMD entries during write-protect operations instead of preserving it, so the intended handoff into _PAGE_SAVED_DIRTY by pmd_mksaveddirty() becomes a no-op. The practical consequence is silent user-space data loss for workloads that combine transparent huge pages (THP), madvise(..., MADV_FREE), and heavy memory-reclaim pressure — Polars analytics users have reportedly lost production data under exactly this combination.
This record — and 170,000+ others — are available via the ValtersIT API. One endpoint replaces five: NVD + GitHub CVE + CISA KEV + EPSS + Nuclei + Exploit-DB, unified.
No signup required
Technical Analysis
On x86, page-table modification helpers exist at three levels: pte_modify() (PTE), pmd_modify() (PMD), and pud_modify() (PUD). All three apply a mask to the old entry value and merge in new protection bits. The bug is that pmd_modify() uses the mask (_HPAGE_CHG_MASK & ~_PAGE_DIRTY), which explicitly clears the hardware dirty bit before the new value is written back. pte_modify(), by contrast, preserves _PAGE_DIRTY_BITS in its mask, and pud_modify() leaves _HPAGE_CHG_MASK untouched. pmd_modify() is therefore the outlier.
The corruption path involves two cooperating mechanisms:
Dirty-bit lifecycle on huge pages. When a PMD-mapped huge page is write-protected, the kernel's design is that
pmd_mksaveddirty()transfers the hardware_PAGE_DIRTYstate into the software_PAGE_SAVED_DIRTYbit (so the page can later be restored to a dirty, writable state without losing the fact that it holds unwritten-back data). Becausepmd_modify()has already removed_PAGE_DIRTYfrom the value it operates on,pmd_mksaveddirty()has nothing to transfer. Anypmd_modify()call applied to a writable, dirty PMD silently destroys the dirty state.MADV_FREE + THP interaction.
MADV_FREEmarks a range as reclaimable-at-will: the kernel cleans the page-table entry (clearing dirty) but leaves the mapping writable, and marks the folio lazyfree. If user space writes to the range again, the hardware sets_PAGE_DIRTYonce more. A subsequentmprotect()toPROT_READinvokespmd_modify(), which drops that re-set dirty bit. With the dirty state gone and the folio still flagged lazyfree, reclaim (for example under memcg pressure) concludes the page carries no unflushed data and discards it in__discard_a...(the description truncates the reclaim path here) — the writes performed after the firstMADV_FREEare lost.
The attack surface is user space on affected x86 kernels: any process that uses THP-backed PMD mappings, issues MADV_FREE, and re-dirties the range before a mprotect() or other PMD write-protect transition, in the presence of reclaim pressure. No privilege boundary is crossed by the trigger itself, but the defect is reachable from local unprivileged code, which is what gives it a security dimension (integrity loss under a local access vector) rather than purely a kernel-reliability dimension.
No public PoC, exploit code, or Nuclei template exists for this CVE. The technical account above is derived strictly from the NVD description; function names and bit names are quoted verbatim from that description. The truncated reclaim symbol (__discard_a) is not fully resolvable from the supplied data, and no inference about its full name is offered.
Exploitation Scenarios
No public proof-of-concept is available; the following chain is inferred from the vulnerability class (silent dirty-bit loss on huge-page mappings) and from the description's own reproduction sequence.
Target identification / reconnaissance. The precondition is a workload, not a remote host. An adversary — or an incidental operator — identifies a Linux x86 system running THP-backed analytics or in-memory data processing (the description names Polars analytics users as the real-world affected population). Reconnaissance is therefore host-side: confirm THP is enabled, confirm the process uses large PMD-mapped memory regions, and confirm reclaim pressure exists or can be induced (memcg limits, co-tenant memory load).
Triggering the flaw class. User space drives the exact sequence the description documents: (a) allocate a PMD-mapped THP buffer and initialize it, producing a writable, dirty PMD; (b) call
madvise(buf, size, MADV_FREE), which cleans the PMD but leaves it writable and marks the folio lazyfree; (c) write to the buffer again, so the hardware re-sets_PAGE_DIRTY; (d) callmprotect(buf, size, PROT_READ), which routes throughpmd_modify()and silently discards the dirty bit; (e) optionally restorePROT_READ|PROT_WRITE; (f) apply memory pressure.Execution / payload level. At the vulnerability-class level, there is no code-injection payload here: the "payload" is the sequence of
madvise()andmprotect()calls plus induced reclaim, which together cause the kernel to free a still-dirty folio. The write in step (c) is the data that later disappears. No memory-corruption primitive, no out-of-bounds access, and no privilege escalation are described. The harm is silent loss of the re-written contents when reclaim discards the folio.Post-exploitation / impact. Integrity loss of processed data: buffers and computed results vanish without error, producing wrong results or truncated outputs in analytics pipelines. An adversary positioned to induce reclaim pressure on a shared host could use this as a denial-of-integrity vector against a co-tenant's data pipeline, but the supplied data does not establish a remote or cross-tenant exploit primitive, and no such chain is claimed here.
Impact Assessment
No CVSS score, vector, or CWE has been assigned by NVD; the provisional vector above is an analyst estimate and must not be cited as authoritative. On impact, the observable consequences are integrity and availability losses in user space: silent data loss, silent corruption of computed results, and unpredictable failures under memory pressure. Confidentiality is not implicated by anything in the description.
The blast radius is bounded by configuration, not by exposure: systems are affected only where THP is active, MADV_FREE is used on large mappings, and reclaim pressure occurs. Because those conditions are common in high-throughput analytics, in-memory databases, and scientific computing pipelines, a narrow trigger maps onto a broad class of data-processing deployments — the description's mention of production data loss by Polars users confirms real-world reach. The absence of a CISA KEV entry, public exploit, and assigned CVSS score indicates no current evidence of deliberate exploitation; the dominant risk is accidental, high-consequence data loss. Systems without THP, or workloads that never combine MADV_FREE with heavy reclaim, are effectively out of scope.
Detection Guidance
Detection here is imperfect: the trigger is ordinary memory-management syscalls and leaves no distinctive network artifact. The rules below target the syscall sequence and correlation context rather than a signature string, and should be tuned per environment.
Sigma Rule
title: Suspicious MADV_FREE plus mprotect Write-Protect Sequence on THP Mappings (CVE-2026-97945)
id: 3f9b7a12-9c41-4d2e-8b77-cve202697945
status: experimental
description: Detects processes issuing MADV_FREE followed by PROT_READ-only mprotect on large mappings, the pattern associated with dirty-bit loss and data discard on THP-backed memory.
references:
- CVE-2026-97945
author: valtersit.com
date: 2026/01/01
logsource:
category: process_creation
product: linux
detection:
selection_madv:
Image|endswith:
- '/python3'
- '/python'
- '/node'
- '/ruby'
selection_audit:
Keywords:
- 'madvise'
- 'mprotect'
condition: selection_madv and selection_audit
falsepositives:
- JIT runtimes and garbage collectors using MADV_FREE as a normal allocation strategy
- Analytics and in-memory database workloads performing routine mprotect transitions
level: low
tags:
- attack.impact
- cve.2026-97945
YARA Rule
rule CVE_2026_97945_PMD_DIRTY_BIT_LOSS
{
meta:
description = "Detects kernel build artifacts and source references associated with the pmd_modify dirty-bit loss (CVE-2026-97945)"
author = "valtersit.com"
reference = "CVE-2026-97945"
date = "2026-01-01"
strings:
$sym1 = "pmd_modify"
$sym2 = "pmd_mksaveddirty"
$sym3 = "_PAGE_SAVED_DIRTY"
$mask = "_HPAGE_CHG_MASK"
condition:
uint32(0) == 0x464c457f and
filesize < 80MB and
$sym1 and $sym2 and
($sym3 or $mask)
}
This rule matches only kernel images or objects that carry the affected symbol set; it is not a behavioral detector.
Suricata IDS Rule
No network attack surface exists for this vulnerability — the trigger is local syscall activity and there is no protocol, endpoint, or payload carried over the wire. A Suricata signature cannot detect this flaw, and any rule purporting to do so would be fabricated. Omitted. Network monitoring should instead watch for exfiltration or lateral movement that might follow opportunistic abuse of a crashed or quarantined analytics node.
Elastic Detection
sequence by host.id, process.entity_id with maxspan=5s
[process where process.name in ("python3", "python", "node") and
auditd.data.syscall == "madvise"]
[any where auditd.data.syscall == "mprotect" and
auditd.data.args contains "PROT_READ"]
Correlate with host memory-pressure signals (system.memory.actual.free collapse) and with application-side data-loss alerts to raise confidence.
Splunk SPL Query
index=linux_audit sourcetype=auditd
(syscall=madvise OR syscall=mprotect)
(exe="/usr/bin/python3" OR exe="/usr/bin/python" OR exe="/usr/bin/node")
| transaction host, pid maxspan=10s
| search syscall=madvise AND syscall=mprotect
| stats count, values(args) as syscall_args by host, pid, exe
| where count > 5
| table _time, host, pid, exe, count, syscall_args
Wazuh OSSEC Rule
<group name="linux,cve_2026_97945,">
<rule id="100945" level="3">
<decoded_as>auditd</decoded_as>
<field name="audit.type">SYSCALL</field>
<match>madvise</match>
<description>CVE-2026-97945: MADV_FREE invocation observed on THP-capable host</description>
</rule>
<rule id="100946" level="6" frequency="2" timeframe="10">
<if_matched_sid>100945</if_matched_sid>
<match>mprotect</match>
<description>CVE-2026-97945: possible dirty-bit loss sequence (MADV_FREE followed by mprotect PROT_READ)</description>
</rule>
</group>
Mitigation & Patch Guidance
Patch confidence: 0/4 (UNPATCHED — no patch evidence from any tracked source).
Immediate mitigations. Disable transparent huge pages on hosts running memory-intensive analytics workloads (
echo never > /sys/kernel/mm/transparent_hugepage/enabled), which removes the PMD-mapped precondition entirely. Where THP cannot be disabled, reduce reliance onMADV_FREEin applications — several analytics and runtime libraries expose configuration to fall back toMADV_DONTNEED, which forces a write-back rather than allowing silent discard. Increase available memory and reduce reclaim pressure (raise or remove restrictive memcg limits, reduce co-tenant density) to lower the odds of hitting the trigger window. Ensure dependent pipelines checkpoint or journal data so a loss event is recoverable.Patch / upgrade steps. No patched kernel version is available from any tracked source. Track the upstream "x86/mm: Fix user-space data loss with MADV_FREE and THP" fix through the Linux kernel mailing list, your distribution's security advisories, and the stable-branch queues. When a fixed kernel is published, validate it against the reproduction sequence in the NVD description before rolling out, then prioritize fleet upgrade for hosts that run THP-enabled analytics workloads.
Long-term hardening. Standardize on kernels that preserve dirty state across all three page-table modification levels, and include this class of memory-management regression in kernel-update test matrices for data-integrity-sensitive workloads. Add application-level consistency checks and checksums on computed datasets so silent corruption is detected rather than propagated. Where feasible, isolate high-value data-processing nodes so that induced memory pressure from co-tenants cannot influence their reclaim behavior. Monitor vendor and distro advisories for backport identifiers, since this CVE currently has none.
References
- NVD entry for CVE-2026-97945: https://nvd.nist.gov/vuln/detail/CVE-2026-97945
- Linux kernel upstream fix: "x86/mm: Fix user-space data loss with MADV_FREE and THP" — commit referenced in the NVD description (no commit hash published in available data)
- Linux kernel mm documentation on
madvise(2)/MADV_FREEsemantics: https://man7.org/linux/man-pages/man2/madvise.2.html - Linux kernel documentation on transparent huge pages: https://docs.kernel.org/admin-guide/mm/transhuge.html
- CISA Known Exploited Vulnerabilities catalog: CVE-2026-97945 is not listed; no exploit-in-the-wild evidence or threat-actor campaign is associated with this CVE in available data.
What is this? Security researchers use these exact search queries on Shodan.io (a search engine for internet-connected devices) to find vulnerable systems globally. You can copy these dorks to see if your organization's IP space is exposed.
💣 PoC CODE AVAILABLE
Exploit code for this CVE is tracked in our database.
Access poc_code via API Pro.