Cloudanix VulnDB

CVE-2026-98647

None

CVSS

—

EPSS

0.2%

Published

Oct 18, 2026

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

A bug in the Linux kernel can cause the entire system to crash when certain specially crafted programs are loaded for performance or security monitoring.

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

What it actually does

Divide-by-zero in btf_struct_walk() during BTF validation for BPF programs when an empty struct containing only a flexible array member is referenced via a non-MEM_ALLOC PTR_TO_BTF_ID, causing an oops at program load time.

Why it matters to the business

Systems may experience kernel crashes or become unavailable when untrusted or malformed BPF programs are loaded, increasing operational risk for environments relying on eBPF for observability, networking, or security.

How an attack unfolds

An attacker crafts BTF definitions for structs that are conditionally empty and contain flexible arrays, loads them through a sleepable BPF program that stores a plain kptr in a map, then triggers bpf_prog_load which reaches btf_struct_walk and divides by the zero-sized element type.

How to fix it

Update the Linux kernel to a version containing the upstream fix that rejects zero-sized element types in btf_struct_walk before performing the modulo operation.

How to confirm the fix worked

Confirm the kernel source contains the added size check in btf_struct_walk, or attempt to load a reproducer program containing an empty struct with flexible array and verify it is now rejected with an appropriate verifier error instead of crashing.

Typical attack path

  1. Define BTF for an empty struct followed by a flexible array member inside a batch-like structure
  2. Compile and load a sleepable BPF program that obtains a non-allocated PTR_TO_BTF_ID referencing the struct
  3. Store the pointer in a map and later access it to force BTF walking at verification time
  4. Trigger the divide-by-zero during bpf_check in the kernel

How to detect it

Search kernel logs and dmesg for Oops messages containing divide error and the symbol btf_struct_walk, along with the call trace through btf_struct_access and bpf_check; also look for audit records of bpf_prog_load syscalls preceding the crash.

  • btf_struct_walk+0x53f/0x1570
  • divide error: 0000 [#1] SMP KASAN PTI
  • btf_struct_access+0x42a/0xcd0
  • bpf_check+0x6d3b/0x8580

What your security team should do

  • Prioritize kernel updates on any system exposing unprivileged BPF loading or accepting programs from untrusted sources
  • Restrict BPF program loading to privileged users via sysctl or LSM controls until patches are applied
  • Monitor for kernel oops involving btf_struct_walk in system logs

The record

In the Linux kernel, the following vulnerability has been resolved: bpf: Fix divide-by-zero in btf_struct_walk() When an access goes past the struct and the last member is a flexible array, btf_struct_walk() folds the offset back into a single element with (off - moff) % t->size, but never checks that the element type has a size. BTF takes an empty struct, so this in program BTF /* event could be empty */ struct event { #ifdef HAVE_TIMESTAMP __u64 ts; #endif }; struct batch { int nr; struct event events[]; }; divides by zero at prog load time. Getting there needs a PTR_TO_BTF_ID that is not MEM_ALLOC, e.g. a plain read of a local kptr stashed in a map from a sleepable program. Oops: divide error: 0000 [#1] SMP KASAN PTI RIP: 0010:btf_struct_walk+0x53f/0x1570 Call Trace: <TASK> btf_struct_access+0x42a/0xcd0 check_ptr_to_btf_access+0x4dc/0x1160 check_mem_access+0x3a45/0x8740 check_load_mem+0x36a/0xd10 do_check_common+0x3ef0/0xb210 bpf_check+0x6d3b/0x8580 bpf_prog_load+0xf7c/0x2720 __sys_bpf+0xa83/0x3690 __x64_sys_bpf+0xc7/0x150 x64_sys_call+0x1f3f/0x27e0 do_syscall_64+0xe5/0x610 entry_SYSCALL_64_after_hwframe+0x76/0x7e </TASK> Reject a zero-sized element type. The fixed array path in the same function already bails out on the same thing: btf_struct_walk() ... /* skip empty array */ if (moff == mtrue_end) continue; msize /= total_nelems;

Affected packages

Ecosystem Package Introduced Fixed