Cloudanix VulnDB

CVE-2025-39748

Medium · 5.5

CVSS

5.5

EPSS

0.2%

Published

Sep 11, 2025

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

A Linux kernel bug could cause unexpected errors or instability when certain low-level network or security programs run, so updating the operating system fixes the problem.

Exploitation
Local Privilege
Attacker needs
Low Privilege
Complexity
Low
Impact
Denial Of Service
Component
OS kernel
Class
Improper Input Validation
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

The BPF verifier fails to maintain consistent register range and tnum invariants on unreachable paths after JSET-based narrowing, resulting in a kernel warning when reg_bounds_sync detects the mismatch.

Why it matters to the business

Systems running affected kernels may experience spurious verifier warnings or crashes when loading certain BPF programs, increasing operational risk for workloads that rely on eBPF for networking, security, or observability; low exploitability and absence from known campaigns reduce immediate urgency but still require patching of production Linux hosts.

How an attack unfolds

An attacker crafts a BPF program containing sequential JMP_EQ and JSET instructions that create an unreachable fall-through path; the verifier walks the path, incorrectly refines bounds after the JSET, violates internal invariants, and triggers a warning. No runtime execution of the unreachable code occurs, and LLVM does not emit JSET, limiting practical use.

How to fix it

Upgrade the Linux kernel to a version containing commit f01e06930444cab289a8783017af9b64255bd103 or later; rebuild and redeploy any out-of-tree BPF programs after the update.

How to confirm the fix worked

Confirm the running kernel contains commit f01e06930444cab289a8783017af9b64255bd103; attempt to load a minimal test program that exercises the original JSET path and verify absence of range-invariant warnings in dmesg.

Typical attack path

  1. Compile or hand-craft a BPF program with a JSET instruction followed by an EQ comparison that produces an unreachable branch
  2. Load the program via bpf() syscall or a user-space loader on an affected kernel
  3. Trigger verifier path exploration that reaches the inconsistent bounds state
  4. Observe kernel warning or verifier rejection

How to detect it

Search kernel logs (dmesg, journalctl) for messages containing 'range invariant violation' or 'reg_bounds_sync' originating from the BPF verifier; correlate with bpf() syscall activity from untrusted sources.

  • range invariant violation
  • reg_bounds_sync
  • JSET tnum refinement

What your security team should do

  • Prioritize kernel updates on systems that load untrusted or third-party BPF programs
  • Monitor EPSS and KEV status for any future increase in exploit maturity
  • Add kernel log monitoring for BPF verifier warnings as a temporary detection control

The record

In the Linux kernel, the following vulnerability has been resolved: bpf: Forget ranges when refining tnum after JSET Syzbot reported a kernel warning due to a range invariant violation on the following BPF program. 0: call bpf_get_netns_cookie 1: if r0 == 0 goto <exit> 2: if r0 & Oxffffffff goto <exit> The issue is on the path where we fall through both jumps. That path is unreachable at runtime: after insn 1, we know r0 != 0, but with the sign extension on the jset, we would only fallthrough insn 2 if r0 == 0. Unfortunately, is_branch_taken() isn't currently able to figure this out, so the verifier walks all branches. The verifier then refines the register bounds using the second condition and we end up with inconsistent bounds on this unreachable path: 1: if r0 == 0 goto <exit> r0: u64=[0x1, 0xffffffffffffffff] var_off=(0, 0xffffffffffffffff) 2: if r0 & 0xffffffff goto <exit> r0 before reg_bounds_sync: u64=[0x1, 0xffffffffffffffff] var_off=(0, 0) r0 after reg_bounds_sync: u64=[0x1, 0] var_off=(0, 0) Improving the range refinement for JSET to cover all cases is tricky. We also don't expect many users to rely on JSET given LLVM doesn't generate those instructions. So instead of improving the range refinement for JSETs, Eduard suggested we forget the ranges whenever we're narrowing tnums after a JSET. This patch implements that approach.

Affected packages

Ecosystem Package Introduced Fixed
Debian:11 linux 0 No fix
Debian:12 linux 0 No fix
Debian:13 linux 0 6.12.43-1
Debian:14 linux 0 6.16.3-1
Linux Kernel 0 6.12.43
Linux Kernel 5.0.0 6.12.43
openSUSE:Leap 16.0 dtb-aarch64 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-64kb 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-default 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-default-base 0 6.12.0-160000.6.1.160000.2.4
openSUSE:Leap 16.0 kernel-docs 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-kvmsmall 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-obs-build 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-obs-qa 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-rt 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-source 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-syms 0 6.12.0-160000.6.1
openSUSE:Leap 16.0 kernel-zfcpdump 0 6.12.0-160000.6.1

Related vulnerabilities