CVE-2026-93127
High · 7.8CVSS
7.8
EPSS
0.2%
Published
Sep 17, 2026
CISA due date
—
Cloudanix analysis
A bug in the Linux kernel's safety checks for certain low-level programs could let someone already on the machine bypass protections and take over the whole system.
- Exploitation
- Local Privilege
- Attacker needs
- Low Privilege
- Complexity
- Moderate
- Impact
- Full Compromise
- Component
- OS kernel
- Class
- Improper Input Validation
- Remediation
- Upgrade
- Effort
- Medium
- Patch risk
- Low
What it actually does
The BPF verifier incorrectly retains a shared scalar identifier across sign-extending and zero-extending stack loads for the same spilled register; subsequent sync_linked_regs refinement therefore derives an impossible constant value that does not match the runtime sign-extended bits, permitting an out-of-bounds memory access that the verifier had approved.
Why it matters to the business
Local attackers on affected Linux systems can escalate privileges to kernel level, potentially leading to full host compromise, data theft, or persistence; the issue affects any environment that loads untrusted or attacker-supplied BPF programs.
How an attack unfolds
An attacker compiles a malicious BPF program that performs a sign-extending narrowing load from a spilled scalar, follows it with a zero-extending load into a linked register, then uses an equality check against a constant; the verifier refines the sign-extended register to an incorrect value, allowing the program to pass verification and later dereference an attacker-controlled out-of-bounds address at runtime.
How to fix it
Apply the upstream kernel patch that drops the scalar identifier at the sign-extension site in check_mem_access when the value actually changes; rebuild and deploy the fixed kernel image, or update to a distribution release that contains the resolution.
How to confirm the fix worked
Confirm the patch is present by inspecting the check_mem_access and coerce_reg_to_size_sx functions for the added no_sext guard; recompile a test BPF program that previously triggered the mis-refinement and verify it is now rejected or produces correct runtime values.
Typical attack path
- Obtain local code execution on a Linux host that accepts BPF programs
- Craft and load a BPF program containing sign-extending narrowing stack fills followed by a comparison that triggers linked-register refinement
- Pass verifier checks with an invalid bounds assumption
- Execute the program to perform an out-of-bounds kernel memory access
- Leverage the resulting read/write primitive for privilege escalation
How to detect it
Search kernel audit logs and BPF loader traces for programs that perform mixed sign- and zero-extending loads from the same stack slot followed by register comparisons; look for verifier-accepted programs that later cause page-fault or bounds-check violations in the kernel.
What your security team should do
- Prioritize kernel updates on any system that permits unprivileged BPF loading
- Restrict unprivileged BPF via sysctl kernel.unprivileged_bpf_disabled=1 where feasible
- Audit production workloads for custom BPF programs that could be abused
- Monitor for future CVEs in the BPF verifier given its history of similar issues
The record
In the Linux kernel, the following vulnerability has been resolved: bpf: Drop scalar id on sign-extending narrowing stack fills When a spilled scalar is filled back with a sign-extending narrowing load (BPF_MEMSX), check_stack_read_fixed_off() copies the spilled register including its scalar id, but coerce_reg_to_size_sx() then sign-extends the filled register's value. If the same slot is also filled with a plain zero-extending load (BPF_MEM), both destination registers share the id yet hold different values. A later 'if <zext-reg> == const' then refines the sign-extended register through sync_linked_regs() to a value it does not have at runtime (e.g. the verifier believes 0x80000000 while the register is 0xffffffff80000000), which can be turned into an out-of-bounds access. Drop the shared scalar id at the sign-extension site in check_mem_access() when sign extension actually changes the value, mirroring the BPF_MOVSX handling in check_alu_op() (no_sext = reg_umax < 2^(size*8-1)).
Affected packages
| Ecosystem | Package | Introduced | Fixed |
|---|