Wind River Support Network

HomeDefectsLIN1022-17984
Acknowledged

LIN1022-17984 : Security Advisory - linux - CVE-2025-39844

Created: Sep 21, 2025    Updated: Sep 23, 2025
Found In Version: 10.22.33.1
Severity: Standard
Applicable for: Wind River Linux LTS 22
Component/s: Kernel

Description

In the Linux kernel, the following vulnerability has been resolved:[EOL][EOL]mm: move page table sync declarations to linux/pgtable.h[EOL][EOL]During our internal testing, we started observing intermittent boot[EOL]failures when the machine uses 4-level paging and has a large amount of[EOL]persistent memory:[EOL][EOL]  BUG: unable to handle page fault for address: ffffe70000000034[EOL]  #PF: supervisor write access in kernel mode[EOL]  #PF: error_code(0x0002) - not-present page[EOL]  PGD 0 P4D 0 [EOL]  Oops: 0002 [#1] SMP NOPTI[EOL]  RIP: 0010:__init_single_page+0x9/0x6d[EOL]  Call Trace:[EOL]   <TASK>[EOL]   __init_zone_device_page+0x17/0x5d[EOL]   memmap_init_zone_device+0x154/0x1bb[EOL]   pagemap_range+0x2e0/0x40f[EOL]   memremap_pages+0x10b/0x2f0[EOL]   devm_memremap_pages+0x1e/0x60[EOL]   dev_dax_probe+0xce/0x2ec [device_dax][EOL]   dax_bus_probe+0x6d/0xc9[EOL]   [... snip ...][EOL]   </TASK>[EOL][EOL]It turns out that the kernel panics while initializing vmemmap (struct[EOL]page array) when the vmemmap region spans two PGD entries, because the new[EOL]PGD entry is only installed in init_mm.pgd, but not in the page tables of[EOL]other tasks.[EOL][EOL]And looking at __populate_section_memmap():[EOL]  if (vmemmap_can_optimize(altmap, pgmap))                                [EOL]          // does not sync top level page tables[EOL]          r = vmemmap_populate_compound_pages(pfn, start, end, nid, pgmap);[EOL]  else                                                                    [EOL]          // sync top level page tables in x86[EOL]          r = vmemmap_populate(start, end, nid, altmap);[EOL][EOL]In the normal path, vmemmap_populate() in arch/x86/mm/init_64.c[EOL]synchronizes the top level page table (See commit 9b861528a801 ("x86-64,[EOL]mem: Update all PGDs for direct mapping and vmemmap mapping changes")) so[EOL]that all tasks in the system can see the new vmemmap area.[EOL][EOL]However, when vmemmap_can_optimize() returns true, the optimized path[EOL]skips synchronization of top-level page tables.  This is because[EOL]vmemmap_populate_compound_pages() is implemented in core MM code, which[EOL]does not handle synchronization of the top-level page tables.  Instead,[EOL]the core MM has historically relied on each architecture to perform this[EOL]synchronization manually.[EOL][EOL]We're not the first party to encounter a crash caused by not-sync'd top[EOL]level page tables: earlier this year, Gwan-gyeong Mun attempted to address[EOL]the issue [1] [2] after hitting a kernel panic when x86 code accessed the[EOL]vmemmap area before the corresponding top-level entries were synced.  At[EOL]that time, the issue was believed to be triggered only when struct page[EOL]was enlarged for debugging purposes, and the patch did not get further[EOL]updates.[EOL][EOL]It turns out that current approach of relying on each arch to handle the[EOL]page table sync manually is fragile because 1) it's easy to forget to sync[EOL]the top level page table, and 2) it's also easy to overlook that the[EOL]kernel should not access the vmemmap and direct mapping areas before the[EOL]sync.[EOL][EOL]# The solution: Make page table sync more code robust and harder to miss[EOL][EOL]To address this, Dave Hansen suggested [3] [4] introducing[EOL]{pgd,p4d}_populate_kernel() for updating kernel portion of the page tables[EOL]and allow each architecture to explicitly perform synchronization when[EOL]installing top-level entries.  With this approach, we no longer need to[EOL]worry about missing the sync step, reducing the risk of future[EOL]regressions.[EOL][EOL]The new interface reuses existing ARCH_PAGE_TABLE_SYNC_MASK,[EOL]PGTBL_P*D_MODIFIED and arch_sync_kernel_mappings() facility used by[EOL]vmalloc and ioremap to synchronize page tables.[EOL][EOL]pgd_populate_kernel() looks like this:[EOL]static inline void pgd_populate_kernel(unsigned long addr, pgd_t *pgd,[EOL]                                       p4d_t *p4d)[EOL]{[EOL]        pgd_populate(&init_mm, pgd, p4d);[EOL]        if (ARCH_PAGE_TABLE_SYNC_MASK & PGTBL_PGD_MODIFIED)[EOL]                arch_sync_kernel_mappings(addr, addr);[EOL]}[EOL][EOL]It is worth noting that vmalloc() and apply_to_range() carefully[EOL]synchronizes page tables by calling p*d_alloc_track() and[EOL]arch_sync_kernel_mappings(), and thus they are not affected by[EOL]---truncated---
Live chat
Online