{"id":"CVE-2026-98918","title":"mm/damon/ops-common: use a page-aligned address in damon_ptep_mkold()","summary":"In the Linux kernel, the following vulnerability has been resolved:\n\nmm/damon/ops-common: use a page-aligned address in damon_ptep_mkold()\n\n__damon_va_prepare_access_check() picks a random byte address within the\nregion and stores it in …","severity":"none","vendor":"Linux","product":"Linux","affected":["Linux >= 6f0e1142173a54b8a18c59fc3cbae3b31ee423d9 < d5208de0799c506d3315b6f96d034c38e4509dbb","Linux >= 6f0e1142173a54b8a18c59fc3cbae3b31ee423d9 < f166586f74dd5d9cbadaabf86ef81c8ddf6cafa7","Linux 7.0"],"published":"2026-10-23","updated":"2026-10-23","sourceUpdated":"2026-10-23T12:05:05.149Z","source":"CVEORG","sourceUrl":"https://www.cve.org/CVERecord?id=CVE-2026-98918","references":[{"url":"https://git.kernel.org/stable/c/d5208de0799c506d3315b6f96d034c38e4509dbb"},{"url":"https://git.kernel.org/stable/c/f166586f74dd5d9cbadaabf86ef81c8ddf6cafa7"}],"tags":["cve.org"],"ingestedAt":"2026-10-23T13:24:55.568Z","slug":"CVE-2026-98918","body":"## Overview\n\nIn the Linux kernel, the following vulnerability has been resolved:\n\nmm/damon/ops-common: use a page-aligned address in damon_ptep_mkold()\n\n__damon_va_prepare_access_check() picks a random byte address within the\nregion and stores it in r->sampling_addr.  damon_va_mkold() passes it into\na page table walk, which hands it to damon_ptep_mkold() as the address of\nthe page to sample:\n\n  damon_va_mkold(mm, r->sampling_addr)\n    damon_va_walk_page_range(mm, addr, addr + 1)\n      damon_mkold_pmd_entry()\n        damon_ptep_mkold(pte, vma, addr)\n          ptep_test_and_clear_young(vma, addr, pte)\n          mmu_notifier_clear_young(mm, addr, addr + PAGE_SIZE)\n\nFor arm64, before commit 6f0e1142173a (\"arm64: mm: support batch clearing\nof the young flag for large folios\"), the contpte helper walked exactly\nCONT_PTES entries from the aligned-down page table pointer and used @addr\nonly to pass down to each entry, so an unaligned value was harmless:\n\n        ptep = contpte_align_down(ptep);\n        addr = ALIGN_DOWN(addr, CONT_PTE_SIZE);\n        for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE)\n\nNow the range to walk is derived from @addr instead: end = addr + nr *\nPAGE_SIZE, rounded up to CONT_PTE_SIZE.  For a sample in the last page of\na contpte block, the sub-page offset puts end just past the block\nboundary, so the round-up lands a whole block further and the walk clears\nPTE_AF in CONT_PTES entries beyond the sampled block.  For the last block\nin a page table page, those entries are past the end of that page, so the\nwalk writes into the page that follows.\n\nTriggered by the full 7.1/7.2 kernel selftest suite on arm64 (EC2\nc/m6g.4xlarge).  The kernel sometimes crashes at or shortly after the\nDAMON test.\n\nWhat the overrun does depends on the page that happens to follow the page\ntable, so there is no single signature.  If that page is read-only, the\nwrite faults in the sampling path itself:\n\n  Unable to handle kernel write to read-only memory at virtual address ffff0003c5d2d000\n    FSC = 0x0f: level 3 permission fault\n    CM = 0, WnR = 1, TnD = 0, TagAccess = 0\n  CPU: 10 UID: 0 PID: 3487 Comm: kdamond.2\n  pc : contpte_test_and_clear_young_ptes+0x70/0xc0\n  lr : damon_ptep_mkold+0x1e8/0x1f8\n  Call trace:\n   contpte_test_and_clear_young_ptes+0x70/0xc0 (P)\n   damon_mkold_pmd_entry+0x150/0x170\n   walk_pmd_range+0x110/0x2b0\n   walk_pud_range+0x10c/0x208\n   walk_pgd_range+0x134/0x258\n   __walk_page_range+0x98/0x1b0\n   walk_page_range_vma_unsafe+0x90/0x148\n   walk_page_range_vma+0x28/0x40\n   damon_va_walk_page_range+0x114/0x2b8\n   damon_va_prepare_access_checks+0xec/0x1a8\n   kdamond_fn+0x534/0x770\n   kthread+0x128/0x138\n   ret_from_fork+0x10/0x20\n\nOtherwise the page is writable, the PTE_AF clearing succeeds silently and\nthe damage only surfaces later, in whatever happened to own the page, so\nthe backtrace is unrelated to DAMON and differs between runs.\n\nPass a page-aligned address to the ptep_test_and_clear_young() call in\ndamon_ptep_mkold(), which is the only place DAMON can reach\ncontpte_test_and_clear_young_ptes() from.  Nothing else sees the aligned\naddress, and r->sampling_addr itself is left as is, so the sampling and\nregion bookkeeping semantics are unchanged.\n\n## Affected\n\n- `Linux >= 6f0e1142173a54b8a18c59fc3cbae3b31ee423d9 < d5208de0799c506d3315b6f96d034c38e4509dbb`\n- `Linux >= 6f0e1142173a54b8a18c59fc3cbae3b31ee423d9 < f166586f74dd5d9cbadaabf86ef81c8ddf6cafa7`\n- `Linux 7.0`\n\n## Remediation\n\nRefer to the linked advisories for vendor-supplied fixes and affected version ranges.","depth":"sunlit","depthScore":3,"depthScoreParts":{"impact":2.8,"likelihood":0,"exploitation":0,"ransomware":0},"changes":[]}