High severity · published Sep 11, 2026
CVE-2026-89581
bpf, x86: Fix per-CPU address resolution into an extended register
7.8
CVSS
0.1%
EPSS
No
On KEV
Description
In the Linux kernel, the following vulnerability has been resolved:
bpf, x86: Fix per-CPU address resolution into an extended register
The destination of the per-CPU address MOV is encoded in ModRM.reg,
which is extended by REX.R, but the REX prefix is built with
add_1mod(), which sets REX.B. REX.B extends ModRM.rm and SIB.base, and
this instruction addresses memory as disp32 with no base, so the bit
has no effect at all and the high register bit is simply lost.
Every is_ereg() destination therefore resolves to the wrong register,
picking whichever one shares the low three bits:
R5 -> RAX R7 -> RBP R8 -> RSI R9 -> RDI
With BPF_REG_5, whose reg2hex is 0, the emitted
65 49 03 04 25 <off> add %gs:<off>,%rax
adds the per-CPU offset to RAX rather than R8. The destination keeps
the unadjusted address and RAX is clobbered, so the program goes on to
dereference a pointer that was never made per-CPU:
BUG: unable to handle page fault for address: 0000607e386a8894
RIP: bpf_prog_707837aafd2aa9ae_update_percpu_data+0x93/0xc9
Call Trace:
__bpf_prog_test_run_raw_tp+0x2dc/0x7d0
__flush_smp_call_function_queue+0x1e9/0xc80
Kernel panic - not syncing: Fatal exception in interrupt
R5 is the mildest of the four, aliasing a scratch register and faulting
at the store. R7 aliases RBP and would corrupt the frame pointer, R8
and R9 alias the argument registers.
Use add_2mod() so the register goes through REX.R, matching how
add_2reg() places it in ModRM.reg and how emit_priv_frame_ptr()
hardcodes 0x4c for the same instruction with R9. Encodings for the
non-extended registers are unchanged.
Problem showed up when trying to resurrect BPF_GCC CI (selftests built
with BPF_GCC).
This has gone unnoticed because clang reloads the address into R1
before each per-CPU access, so the destination is never an extended
register. GCC keeps several per-CPU addresses live at once, and
test_progs-bpf_gcc panics the kernel in global_percpu_data/init, where
the address of a .percpu variable ends up in R5.
CVSS vector
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
Attack vector
Local
Complexity
Low
Privileges
Low
User interaction
None
Confidentiality
High
Integrity
High
Availability
High
Scope
Unchanged
Exploitation
Is it being used?
Exploit prediction (EPSS)0.1% · higher than 2% of CVEs
Exploited in the wildNo evidence yet
CISA KEVNot listed
Ransomware campaign useNot known
Affected products
Which versions
LI
Linux · Linux
7bdbf7446305cb65c510c16d57cde82bc76b234a before 638bc3aada8ecdece184d5c15b100d489c9cccd7; 7bdbf7446305cb65c510c16d57cde82bc76b234a before 6886642414f59f928728802dc2c972a9859e6310; 7bdbf7446305cb65c510c16d57cde82bc76b234a before 6a19b18d458881bf3269a357cc6dc6db5eef4369; 7bdbf7446305cb65c510c16d57cde82bc76b234a before 5bbbce02e500d47d8e259a45be5a7be9741d0533; 6.10 · source: vendor
References
NVD
https://nvd.nist.gov/vuln/detail/CVE-2026-89581
CVE.org
https://www.cve.org/CVERecord?id=CVE-2026-89581
git.kernel.org
https://git.kernel.org/stable/c/5bbbce02e500d47d8e259a45be5a7be9741d0533
git.kernel.org
https://git.kernel.org/stable/c/638bc3aada8ecdece184d5c15b100d489c9cccd7
git.kernel.org
https://git.kernel.org/stable/c/6886642414f59f928728802dc2c972a9859e6310
git.kernel.org
https://git.kernel.org/stable/c/6a19b18d458881bf3269a357cc6dc6db5eef4369
More from Linux
9.8
CVE-2025-39682
tls: fix handling of zero-length records on the rx_list
8.8
CVE-2026-53266
netfilter: bridge: make ebt_snat ARP rewrite writable
7.8
CVE-2026-53362
ipv6: account for fraggap on the paged allocation path
7.8
CVE-2026-46300
net: skbuff: preserve shared-frag marker during coalescing
7.8
CVE-2026-31431
crypto: algif_aead - Revert to operating out-of-place
