CVE-2026-99093 in Linux
Summary
by MITRE • 10/26/2026
In the Linux kernel, the following vulnerability has been resolved:
mm: don't schedule deferred kernel page table freeing while booting
Booting with a boot-time function tracer and a filter, for example
ftrace=function ftrace_filter=pud_free_pmd_page
panics on 7.3-rc4 as soon as the tracer starts:
[ 23.531178] Starting tracer 'function'
[ 23.675800] Oops: general protection fault, probably for non-canonical address 0xdffffc0000000038: 0000 [#1] SMP KASAN NOPTI
[ 23.819917] KASAN: null-ptr-deref in range [0x00000000000001c0-0x00000000000001c7]
[ 23.964025] CPU: 0 UID: 0 PID: 0 Comm: swapper Not tainted 7.3.0-rc4-fe2ec83746e5-with-fixes-v2+ #195 PREEMPT(undef)
[ 24.252248] RIP: 0010:__queue_work+0xab/0xf00
[ 25.981629] Call Trace:
[ 26.125727] <TASK>
[ 26.413912] ? pagetable_free_kernel+0x20/0x120
[ 26.990283] queue_work_on+0x97/0xf0
[ 27.134382] __cpa_collapse_large_pages+0x501/0x6f0
[ 27.566662] cpa_flush+0x394/0x620
[ 27.998953] change_page_attr_set_clr+0x321/0x4a0
[ 29.151729] set_memory_rox+0xa2/0xf0
[ 29.584018] create_trampoline+0x431/0x6f0
... [ 44.343347] Kernel panic - not syncing: Attempted to kill the idle task!
The boot-time tracer is started from early_trace_init(), which runs before workqueue_init_early(). Making its trampoline read-only splits a large page, and CPA collapses it again right away. The split table has been a kernel page table since commit 9e4a3ec3411b ("x86/mm/pat: Allocate split page tables as kernel page tables"), so the collapse frees it through pagetable_free_kernel(), which queues work on system_percpu_wq - still NULL at that point. That commit is correct in itself; it only lets CPA reach pagetable_free_kernel() before the workqueue that function relies on exists.
Keep putting the table on the list, but don't schedule the work while the system is still booting. A core_initcall schedules it once to free whatever was queued by then.
If you want to get best quality of vulnerability data, you may have to visit VulDB.
Analysis
by VulDB Data Team • 10/26/2026
The Linux kernel vulnerability identified in this report involves a race condition during the early boot sequence that leads to a kernel panic when specific debugging and memory management features are enabled simultaneously. The root cause lies in the interaction between the function tracer, which is initialized very early via early_trace_init(), and the deferred page table freeing mechanism introduced by commit 9e4a3ec3411b. This earlier commit changed x86 memory allocation patterns to allocate split page tables as kernel page tables rather than using a separate structure. While this change was technically correct for standard operation, it inadvertently exposed a timing dependency issue where the code path responsible for freeing these page tables attempts to schedule work on a per-CPU workqueue that has not yet been initialized during the boot process.
When the system boots with a function tracer and a filter such as pud_free_pmd_page enabled, the tracing infrastructure triggers operations that modify memory attributes. Specifically, setting trampoline code to read-only causes the kernel's Change Page Attribute (CPA) mechanism to split large pages into smaller ones to manage permissions more granularly. Immediately following this split, CPA attempts to collapse any redundant or unnecessary page structures back together. Because the newly created split table is classified as a kernel page table under the updated allocation logic, the collapse operation invokes pagetable_free_kernel() to release it. This function relies on queuing a deferred work item onto system_percpu_wq for asynchronous cleanup. However, at this stage of booting, before workqueue_init_early() has executed, the per-CPU workqueues are still null pointers. Attempting to queue work on a NULL pointer results in an invalid memory access, manifesting as a general protection fault and ultimately causing a kernel panic that halts the system.
From a technical classification perspective, this vulnerability represents a use-after-free or improper initialization scenario where resources are accessed before they are fully established. It aligns with CWE-362, Concurrent Execution using Shared Resource with Improper Synchronization, as it involves accessing shared infrastructure (the workqueue) without ensuring its availability relative to the boot state. Furthermore, this issue can be mapped to MITRE ATT&CK technique T1059, Command and Scripting Interpreter, specifically in the context of early-boot script execution or tracing mechanisms that inadvertently trigger unstable code paths due to missing synchronization checks during system initialization. The flaw is not exploitable by an external attacker for remote code execution but poses a significant stability risk for systems relying on kernel debugging features like ftrace during startup.
The resolution implemented in this patch addresses the timing mismatch by introducing a conditional check within pagetable_free_kernel(). Instead of unconditionally scheduling deferred work, the function now verifies whether the system is still in the boot phase. If the system has not yet transitioned to full operational status, the page table structure remains on the internal list but no work item is scheduled immediately. This prevents the null pointer dereference by avoiding access to uninitialized workqueues. To ensure that these deferred items are eventually processed and memory is properly reclaimed, a core_initcall function is registered to run later in the boot sequence. Once this initialization call executes, it triggers a single pass through the list of queued page tables, scheduling them for freeing only after all necessary kernel subsystems, including workqueues, are fully operational.
Mitigation strategies for organizations running affected kernels involve applying the provided patch or updating to a kernel version that includes this fix. For environments where boot-time tracing is critical and cannot be disabled immediately, administrators should ensure they are using patched versions of the Linux kernel. Additionally, disabling specific function tracers during early boot via bootloader parameters can serve as a temporary workaround until updates are applied. It is also advisable to review configurations involving memory attribute changes and page table management in conjunction with debugging tools to identify other potential timing dependencies that might arise from similar architectural decisions regarding deferred resource cleanup.