{"id":"CVE-2026-98918","kind":"vulnerability","aliases":["CVE-2026-98918"],"related":[],"title":"Linux kernel DAMON on arm64 can write past a page table page","description":"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 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.","summary":"DAMON's access sampling on arm64 passes an unaligned address into a contiguous-PTE helper, so the walk can clear access bits in page table entries beyond the sampled block. The overrun can cause a kernel crash or silent corruption of whatever memory follows the page table page.","severity":"unknown","cvss":null,"epss":0.00198,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["arm64","linux-kernel","runtime","self-hosted"],"not_affected_if":["damon-disabled","x86-64-only-fleet"],"how_to_check":"- Run `uname -r` and compare against the kernel release that contains the upstream fix for CVE-2026-98918 (unknown from the sources)\n- Check whether DAMON is in use with `grep -r CONFIG_DAMON /boot/config-$(uname -r)` (unknown whether this is required)","fix":"- Update the Linux kernel to a release that includes the upstream commit titled 'mm/damon/ops-common: use a page-aligned address in damon_ptep_mkold()' (exact version unknown from the sources)","status":"open","published_at":"2026-10-23T13:17:12+00:00","first_seen_at":"2026-10-23T21:57:33+00:00","triaged_at":"2026-10-25T04:58:24+00:00","updated_at":"2026-10-25T12:38:50+00:00","category":"runtime","confidence":0.6,"triage":{"at":"2026-10-25T04:58:24Z","model":"claude-haiku-5-5","output":{"fix":"- Update the Linux kernel to a release that includes the upstream commit titled 'mm/damon/ops-common: use a page-aligned address in damon_ptep_mkold()' (exact version unknown from the sources)","reach":"local","title":"Linux kernel DAMON on arm64 can write past a page table page","impact":"medium","summary":"DAMON's access sampling on arm64 passes an unaligned address into a contiguous-PTE helper, so the walk can clear access bits in page table entries beyond the sampled block. The overrun can cause a kernel crash or silent corruption of whatever memory follows the page table page.","category":"runtime","nicknames":[],"who_cares":["linux-kernel","arm64","self-hosted"],"confidence":0.6,"needs_auth":"unknown","worst_case":"kernel crashes or memory past a page table page is silently corrupted","analyst_note":"Find the fixed kernel versions and stable backport list from the NVD entry (https://nvd.nist.gov/vuln/detail/CVE-2026-98918) and the upstream kernel commit to fill in how_to_check and fix.","how_to_check":"- Run `uname -r` and compare against the kernel release that contains the upstream fix for CVE-2026-98918 (unknown from the sources)\n- Check whether DAMON is in use with `grep -r CONFIG_DAMON /boot/config-$(uname -r)` (unknown whether this is required)","needs_analyst":true,"not_affected_if":["x86-64-only-fleet","damon-disabled"],"who_is_affected":"Systems running Linux kernels on arm64 with DAMON enabled, where the sampling path reaches the contpte helper. The sources do not say whether DAMON is built or enabled by default in distribution kernels, so teams on x86 or without DAMON in use can likely skip it.","user_interaction":"no","needs_special_setup":"yes","severity_if_unknown":"unknown"},"cost_usd":0.000798,"input_tokens":4645,"output_tokens":668,"severity_before":"unknown"},"analyst_status":null,"analyst_note":null,"search":"'+0':455C,461C,471C,478C,483C,488C,493C,498C,505C,511C,518C,525C,529C,532C,537C '-2026':14A,17A '-98918':15A,18A '/7.2':357C '0':248C,433C,437C,439C,443C '0x0f':427C '1':157C,435C '10':441C '3':429C '3487':445C '6f0e1142173a':189C '7.1':356C 'access':29B,48B,100C,523C 'addr':116C,148C,155C,156C,167C,174C,181C,182C,220C,239C,242C,254C,265C,268C,616C 'address':36B,92C,106C,136C,424C,579C,612C 'af':316C,546C 'align':91C,213C,236C,240C,578C,611C 'aligned-down':212C 'arm64':5A,19B,32B,186C,190C,362C 'backtrac':565C 'batch':193C 'beyond':54B,321C 'bit':49B 'block':57B,288C,299C,309C,324C,328C 'bookkeep':627C 'boundari':300C 'byte':105C 'c/m6g.4xlarge':364C 'call':463C,587C 'caus':61B 'check':101C,524C 'clear':47B,171C,178C,194C,314C,452C,468C,547C,585C,603C 'cm':432C 'comm':446C 'commit':188C 'cont':207C,243C,250C,275C,318C 'contigu':40B 'contiguous-pt':39B 'contpt':203C,235C,287C,449C,465C,600C 'corrupt':67B 'cpu':440C 'crash':64B,368C 'cve':13A,16A 'damag':552C 'damon':3A,27B,94C,97C,117C,131C,142C,149C,158C,162C,374C,458C,474C,513C,520C,569C,589C,597C 'depend':380C 'deriv':263C 'differ':571C 'ec2':363C 'els':608C 'end':267C,295C,339C 'entri':53B,161C,209C,227C,320C,335C,477C 'exact':206C 'fault':406C,431C 'ffff0003c5d2d000':425C 'flag':198C 'fn':528C 'folio':201C 'follow':71B,81C,351C,387C 'fork':536C 'fsc':426C 'full':355C 'hand':128C 'handl':414C 'happen':385C,558C 'harmless':233C 'helper':42B,204C 'host':26B 'instead':266C 'kdamond':527C 'kdamond.2':447C 'kernel':2A,22B,63B,79C,358C,366C,415C 'kthread':531C 'land':306C 'larg':200C 'last':283C,327C 'later':555C 'left':619C 'level':428C 'linux':1A,21B,78C 'linux-kernel':20B 'lr':457C 'memori':70B,421C 'mkold':96C,119C,133C,144C,159C,164C,460C,475C,591C 'mm':145C,154C,180C,191C 'mm/damon/ops-common':86C 'mmu':176C 'noth':607C 'notifi':177C 'nr':269C 'offset':293C 'otherwis':539C 'overrun':59B,378C 'p':473C 'page':10A,12A,51B,73B,75B,90C,124C,139C,152C,183C,215C,255C,270C,284C,292C,331C,333C,342C,349C,383C,389C,399C,496C,501C,508C,516C,541C,562C,577C 'page-align':89C,576C 'pass':33B,120C,223C,574C 'past':8A,297C,337C 'path':410C 'pc':448C 'permiss':430C 'pgd':491C 'pick':102C 'pid':444C 'place':596C 'pmd':160C,476C,481C 'pointer':217C 'prepar':99C,522C 'pte':41B,165C,175C,244C,276C,315C,545C 'ptep':95C,132C,163C,168C,234C,238C,253C,459C,582C,590C 'ptes':208C,251C,319C,454C,470C,605C 'pud':486C 'put':294C 'r':114C,146C,614C 'random':104C 'rang':153C,259C,482C,487C,492C,497C,502C,509C,517C 'reach':599C 'read':402C,419C 'read-on':401C,418C 'region':109C,626C 'resolv':85C 'ret':534C 'round':272C,304C 'round-up':303C 'run':573C 'runtim':23B 'sampl':30B,56B,115C,141C,147C,280C,323C,409C,615C,624C 'see':609C 'self':25B 'self-host':24B 'selftest':359C 'semant':628C 'short':371C 'signatur':396C 'silent':66B,549C 'singl':395C 'size':184C,245C,256C,271C,277C 'sometim':367C 'store':111C 'sub':291C 'sub-pag':290C 'succeed':548C 'suit':360C 'support':192C 'surfac':554C 'tabl':11A,52B,74B,125C,216C,332C,390C 'tagaccess':438C 'test':169C,375C,450C,466C,583C,601C 'tnd':436C 'trace':464C 'trigger':352C 'uid':442C 'unabl':412C 'unalign':35B,230C 'unchang':630C 'unrel':567C 'unsaf':504C 'use':87C,219C 'va':98C,118C,143C,150C,514C,521C 'valu':231C 'virtual':423C 'vma':166C,173C,503C,510C 'vulner':82C 'walk':45B,126C,151C,205C,261C,313C,345C,480C,485C,490C,495C,500C,507C,515C 'whatev':69B,557C 'whole':308C 'within':107C 'wnr':434C 'writabl':543C 'write':7A,346C,405C,416C 'x10/0x20':538C 'x10c/0x208':489C 'x110/0x2b0':484C 'x114/0x2b8':519C 'x128/0x138':533C 'x134/0x258':494C 'x150/0x170':479C 'x1e8/0x1f8':462C 'x28/0x40':512C 'x534/0x770':530C 'x70/0xc0':456C,472C 'x90/0x148':506C 'x98/0x1b0':499C 'xec/0x1a8':526C 'young':172C,179C,197C,453C,469C,586C,604C","nicknames":[],"mitigations":[],"who_affected":"Systems running Linux kernels on arm64 with DAMON enabled, where the sampling path reaches the contpte helper. The sources do not say whether DAMON is built or enabled by default in distribution kernels, so teams on x86 or without DAMON in use can likely skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"first_public_at":"2026-10-23T13:17:12+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-98918","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-98918","severity":null,"published_at":"2026-10-23T13:17:12+00:00","modified_at":"2026-10-23T13:17:12+00:00","first_seen_at":"2026-10-23T21:57:33+00:00","fetched_at":"2026-10-23T22:29:03+00:00","note":null},{"source":"epss","external_id":"CVE-2026-98918","url":"https://api.first.org/data/v1/epss?cve=CVE-2026-98918","severity":null,"published_at":null,"modified_at":null,"first_seen_at":"2026-10-25T12:38:50+00:00","fetched_at":"2026-10-25T12:38:50+00:00","note":null}],"documents":[],"notice":"Free to read at a human pace. An API with keys and an MCP server are in preparation; early access: hello@infrastack.ai"}