Cloudanix VulnDB

CVE-2026-98789

None

CVSS

—

EPSS

0.2%

Published

Oct 18, 2026

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

A flaw in the Linux kernel's handling of certain low-level memory cleanup operations could let unused memory pile up until the system runs low on resources and becomes unreliable.

Exploitation
Local Privilege
Attacker needs
Local User
Complexity
Moderate
Impact
Denial Of Service
Component
OS kernel
Class
Memory Corruption
Remediation
Upgrade
Effort
Medium
Patch risk
Low

What it actually does

The vulnerability allows an unbounded number of objects to remain stuck in the free_by_rcu_ttrace list of the BPF memory allocator because do_call_rcu_ttrace() returns early when call_rcu_ttrace_in_progress is set, while __free_rcu() only clears the flag after freeing waiting_for_gp_ttrace objects.

Why it matters to the business

Kernel memory can gradually exhaust on systems that create and destroy many BPF maps, leading to resource starvation, performance degradation, or crashes in production environments that rely on eBPF for networking, security, or observability.

How an attack unfolds

An attacker repeatedly triggers BPF map allocation and deallocation paths that invoke free_bulk() or __free_by_rcu() while an RCU tasks trace grace period is active; the early return in do_call_rcu_ttrace() leaves objects stranded, and because the count is unbounded the attacker can drive memory consumption until the system becomes unstable.

How to fix it

Upgrade the Linux kernel to a version containing the three-state call_rcu_ttrace_in_progress fix and the associated queuing changes under rcu_read_lock with synchronize_rcu before barriers; rebuild and reboot all affected hosts.

How to confirm the fix worked

Confirm the patched kernel source contains the state-machine logic (idle/queued/draining) for call_rcu_ttrace_in_progress and the updated do_call_rcu_ttrace/__free_rcu paths; run stress tests that repeatedly create/destroy BPF maps while monitoring bpf_mem_cache object counts.

Typical attack path

  1. Obtain ability to load and manipulate BPF programs or maps (unprivileged or via a compromised process)
  2. Create and immediately destroy large numbers of BPF hash maps in rapid succession
  3. Force concurrent RCU tasks trace grace periods by interleaving allocations with rcu_barrier_tasks_trace calls
  4. Accumulate objects in free_by_rcu_ttrace until kernel memory pressure becomes critical

How to detect it

Inspect kernel logs and BPF allocator statistics for sustained growth in free_by_rcu_ttrace objects without corresponding frees; correlate with processes performing frequent BPF map create/destroy cycles.

What your security team should do

  • Prioritize kernel updates on all production systems within the next maintenance window
  • Temporarily restrict unprivileged BPF map creation via sysctl or seccomp where feasible
  • Add kernel memory usage and BPF allocator metrics to existing monitoring dashboards
  • Review and reduce the attack surface of workloads that dynamically create short-lived BPF maps

The record

In the Linux kernel, the following vulnerability has been resolved: bpf: Fix objects stuck in free_by_rcu_ttrace do_call_rcu_ttrace() returns early when call_rcu_ttrace_in_progress is set and leaves the objects in free_by_rcu_ttrace. __free_rcu() frees waiting_for_gp_ttrace only and clears the flag. Hence the objects that free_bulk() or __free_by_rcu() added while RCU tasks trace GP was in flight stay in free_by_rcu_ttrace until free_bulk() or alloc_bulk() is called for the same bpf_mem_cache again, which may never happen. The number of such objects is not bounded. Turn call_rcu_ttrace_in_progress into three states: 0 - idle 1 - __free_rcu() is queued 2 - __free_rcu() is queued and free_by_rcu_ttrace got more objects since do_call_rcu_ttrace() sets 2. __free_rcu() does cmpxchg(1 -> 0) and starts the next GP when it fails. It cannot clear the flag first and check free_by_rcu_ttrace later, since bpf_mem_alloc_destroy() frees bpf_mem_cache without waiting for RCU callbacks when the flag is zero. Now __free_rcu() queues itself, so the one that didn't see 'draining' may do call_rcu_tasks_trace() after rcu_barrier_tasks_trace() in free_mem_alloc(). Queue it under rcu_read_lock() and do synchronize_rcu() before the barriers. Calling rcu_barrier_tasks_trace() twice works too, but creating and destroying hash maps in a loop on many cpus slows down to one free_mem_alloc() per GP and kworkers pile up.

Affected packages

Ecosystem Package Introduced Fixed