Look up another CVE · open CVE-2026-93147 in the interactive tracker
CVE-2026-93147
s390/bpf: Replace ly instruction with llgf
Published 2026-09-17 (31 days ago) by the Linux kernel CNA. Subsystem arch/s390. Debian urgency: unimportant.
What to do, per Debian release
Debian's own status for CVE-2026-93147 in every release this site tracks, and what each one means in practice. Every status below is the one the Debian Security Team publishes for this CVE. source
| Release | Status | Version | What this means |
|---|---|---|---|
| Debian 12bookworm | not affected | 6.1.190-1 | Nothing to do. bookworm never shipped the vulnerable code. |
| Debian 13trixie | not affected | 6.12.113-1 | Nothing to do. trixie never shipped the vulnerable code. |
| Debian 14forky | not affected | 7.2.11-1 | Nothing to do. forky never shipped the vulnerable code. |
| Debian unstablesid | not affected | 7.2.11-1 | Nothing to do. sid never shipped the vulnerable code. |
The vulnerability
What the bug is
cpu_nr is a 32 bit value and BPF_REG_0 is a 64 bit register, when ly loads the cpu_nr into BPF_REG_0 it does not zero the upper bits, but llgf does.
Where it lives
The fix touches these files. If the subsystem is one you do not use, the practical exposure is lower, though the package is still the vulnerable one.
arch/s390/net/bpf_jit_comp.c
- What this is
- BPF JIT for S390MAINTAINERS section matched on arch/s390/net/ · bpf@vger.kernel.org · Supported
Check it on the machine
grep -w CONFIG_BPF_JIT /boot/config-$(uname -r)Reads the booted kernel's own configuration, on the machine and nowhere else. =y is built in, =m is a module, and an is not set line means the code is not there.
Show whether Debian builds this, per release
Debian builds this, but not on every flavour. At least one release below builds the code on some of its kernel flavours and not on others, so the answer depends on the architecture and flavour installed.
- bookwormy
- trixie, forky, sidYnot built on s390x/s390x
- y
- built into the kernel image on every flavour - only a patch removes it
- Y
- built in where it is built at all; some flavours do not build it
- Build switch
- CONFIG_BPF_JIT
From the configuration Debian publishes for every kernel flavour it builds. It covers only the architectures Debian ships a linux-config package for, and nothing about a kernel you built yourself. Debian's own status above stays authoritative about the source package.MAINTAINERS kbuild Makefiles Debian linux-config packages
Signals
- Published
- 2026-09-17 (31 days ago)source
- CVSS
- 7.8 high
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:Hsource recompute it - Attack vector
- local (AV:L)source
- EPSS
- 0.17%, higher than 5.4% of all CVEssource
- CISA KEV
- not listedthe KEV catalogue
- Debian urgency
- unimportantsource
- Subsystem
- arch/s390
Upstream fixes
The versions the CNA records as introducing and fixing this, and the commit for each. source
| Introduced | Fixed in | Commit |
|---|---|---|
| 7.2 | 7.2.6 | 88500a86ab79 |
| 7.2 | 7.3 | 5f6cc299938b |
Why the CNA scored it this way
Quoted from the kernel CNA's own scoring file, word for word. A highlighted metric carries the most severe value CVSS v3.1 defines for it, which is what pushes the score up. source
- AV:LAttack vector, local
- The malformed input is eBPF bytecode containing BPF_JMP|BPF_CALL with imm=BPF_FUNC_get_smp_processor_id, loaded via bpf_prog_load() (bpf(2) BPF_PROG_LOAD). s390 bpf_jit_insn() then inlines that call as LY from get_lowcore()->cpu_nr; no remote protocol carries this bytecode.
- AC:LAttack complexity, low
- The attacker sets BPF_REG_0 (s390 %r14) with BPF_LD_IMM64, then emits the helper call; bpf_jit_insn() always compiles it to LY (E358), which writes only bits 32-63 and leaves the attacker-chosen high half intact. bpf_opt_remove_dead_code() does not delete that store, and there is no race.
- PR:LPrivileges required, low
- bpf_prog_load() allows BPF_PROG_TYPE_SOCKET_FILTER; sk_filter_func_proto() reaches bpf_base_func_proto(), which returns bpf_get_raw_smp_processor_id_proto for BPF_FUNC_get_smp_processor_id before its CAP_BPF gate, and BPF_MAP_TYPE_ARRAY is an unprivileged map. CAP_BPF is also granted by bpf_token_capable() in a delegated user namespace.
- UI:NUser interaction, none
- The attacker loads the crafted program with bpf(BPF_PROG_LOAD) and executes it themselves via BPF_PROG_TEST_RUN (sk_filter_prog_ops.test_run = bpf_prog_test_run_skb) or SO_ATTACH_BPF on their own socket; no other user must mount, open, or otherwise act.
- S:UScope, unchanged
- LY leaving stale high bits in BPF_REG_0 lets the JITed program read and write the host kernel through a verifier-approved PTR_TO_MAP_VALUE. That stays inside the same kernel authority; it is not a KVM guest-to-host or IOMMU bypass.
- C:HConfidentiality impact, high
- do_refine_retval_range() sets R0’s 64-bit range to [0, nr_cpu_ids-1] after BPF_FUNC_get_smp_processor_id, so check_map_access() allows adding it to a map-value pointer. LY preserves attacker high bits, so the subsequent BPF_LDX reads kernel memory far outside the map.
- I:HIntegrity impact, high
- The same forged pointer is a BPF_STX destination: the store lands at map_value + ((old_r0 & 0xFFFFFFFF00000000) | cpu_nr). That is an attacker-controlled kernel write usable for corruption and control-flow hijack.
- A:HAvailability impact, high
- Using that out-of-bounds map-value pointer (map_value plus the uncleared high 32 bits of %r14 after LY of cpu_nr) faults on unmapped addresses and oopses or panics the kernel.