CVE-2026-46250 Overview
CVE-2026-46250 affects the Linux kernel on MIPS architecture, where the __current_thread_info global register variable located in $gp is mishandled by LLVM during kernel relocation. LLVM restores $gp whenever it detects clobbering, including intentional clobbering through a global register variable. This behavior conflicts with GCC's documented contract, which states that callee-saved registers used as global register variables must not be restored after being clobbered. The result is that $gp continues to point to the unrelocated kernel after the epilog of relocate_kernel(), causing an early crash in init_idle during boot.
Critical Impact
Kernels built with affected LLVM versions fail to boot on MIPS systems using kernel relocation, producing a kernel paging request crash at virtual address 0x0 during sched_init.
Affected Products
- Linux kernel on MIPS architecture (notably Loongson-3 platforms) with kernel relocation enabled
- Kernels compiled using LLVM versions 18 through 21
- Configurations using __current_thread_info as a global register variable bound to $gp
Discovery Timeline
- 2026-06-03 - CVE-2026-46250 published to NVD
- 2026-06-03 - Last updated in NVD database
Technical Details for CVE-2026-46250
Vulnerability Analysis
The issue is a toolchain compatibility flaw in the MIPS kernel relocation path. On MIPS, the kernel defines __current_thread_info as a global register variable pinned to the $gp register. During kernel relocation, this register is reassigned to point to the relocated kernel image. GCC honors the global register variable contract and leaves the new value in place. LLVM, however, treats any clobber of $gp as something to undo, restoring the original value at function epilog. After relocate_kernel() returns, $gp no longer holds the relocated address.
When init_idle() later dereferences thread-local data through $gp, the access lands in unmapped memory, producing an oops at init_idle+0x130/0x270 with BadVA: 0x0. The crash occurs before user space is reached, making the system unbootable.
Root Cause
The root cause is divergent compiler behavior. GCC documentation specifies that a callee-saved register used as a global register variable must not be restored when clobbered. LLVM does not honor this contract for $gp on MIPS and emits restore code regardless. The kernel code relied on the GCC-documented behavior to retain the relocated $gp value across function returns. See the LLVM bug discussion referenced in the kernel commit log.
Attack Vector
This is a denial-of-service condition triggered by the build toolchain, not a remotely exploitable flaw. The impact surfaces as an unbootable kernel rather than memory corruption an attacker can steer. There is no published exploit and no CISA KEV listing. The vulnerability manifests deterministically at boot when an affected LLVM version is used to compile a MIPS kernel with relocation enabled.
The upstream resolution uses inline assembly to assign $gp directly, bypassing LLVM's clobber-restore logic. The fix is distributed across multiple stable branch commits referenced in the kernel git history.
Detection Methods for CVE-2026-46250
Indicators of Compromise
- Kernel oops at init_idle+0x130/0x270 during early boot on MIPS hardware
- Unable to handle kernel paging request at virtual address 0000000000000000 in the boot log
- Call trace including sched_init and start_kernel with a BadVA of 0x0
- MIPS kernel image built with LLVM/Clang versions 18 through 21
Detection Strategies
- Inspect the toolchain used to build deployed MIPS kernels and flag any image compiled with Clang 18 to 21 without the inline-assembly workaround applied.
- Review boot logs from MIPS targets (notably Loongson-3) for the init_idle oops signature documented in the upstream commit message.
- Audit kernel .config for relocation options on MIPS builds, since the failure only manifests when kernel relocation is active.
Monitoring Recommendations
- Collect serial console or early-boot logs from MIPS fleets to catch the paging-request crash before deployment.
- Track LLVM version metadata in CI build artifacts so regressions to an affected compiler version are visible.
- Monitor stable kernel branches for backports of the referenced commits and gate releases on their inclusion.
How to Mitigate CVE-2026-46250
Immediate Actions Required
- Apply the upstream kernel patches referenced in the NVD entry, which replace global register variable assignment with explicit inline assembly for $gp.
- Rebuild MIPS kernels with GCC until patched sources are deployed, since GCC honors the global register variable contract.
- Validate boot on representative MIPS hardware (such as Loongson-3) after rebuilding to confirm the init_idle crash no longer occurs.
Patch Information
The fix is committed across multiple stable branches. Relevant commits include 05bff9b0ae09, 1fe3b402b1e9, 30bfc2d6a113, 4dc65b40fb80, 561834f6d6f5, 9bc3b0ae5203, c0155dee51b9, and e3a6498a6339. Refer to the kernel git log entries for the full patch set and stable backport status.
Workarounds
- Build the MIPS kernel with GCC rather than Clang/LLVM versions 18 through 21 until the patched source is available.
- Disable kernel relocation in .config if the platform tolerates it, since the crash depends on the relocation path executing.
- Upgrade to an LLVM release that honors the global register variable clobber contract once available, then rebuild and revalidate boot.
# Verify the compiler used to build the running kernel
cat /proc/version
# Check kernel configuration for MIPS relocation
grep -E 'CONFIG_RELOCATABLE|CONFIG_RANDOMIZE_BASE' /boot/config-$(uname -r)
# Rebuild with GCC as a workaround
make ARCH=mips CROSS_COMPILE=mips64el-linux-gnuabi64- CC=gcc -j$(nproc)
Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

