Cloudanix VulnDB

CVE-2025-39886

Medium · 5.5

CVSS

5.5

EPSS

0.2%

Published

Sep 23, 2025

CISA due date

—

Cloudanix analysis

Schedule a fix SSVC: Track

A bug in the Linux kernel can cause the system to freeze or crash when certain networking or scheduling programs run inside containers.

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

What it actually does

The flaw allows bpf_map_kmalloc_node() calls from __bpf_async_init() during bpf_timer_init() to trigger memcg charging paths that acquire locks while the caller already holds rq_lock or similar scheduler locks, resulting in double-acquire deadlocks or hardlockups.

Why it matters to the business

Systems running containerized or BPF-extended workloads can experience kernel-level hangs or crashes that interrupt services, increase operational toil, and require reboots; the issue is prevalent in Linux distributions and affects many downstream packages.

How an attack unfolds

An attacker loads a malicious BPF program that invokes bpf_timer_init() from scheduler-extended ops such as runnable() while rq_lock is held; this triggers memcg accounting under GFP_ATOMIC, which can raise MEMCG_MAX and call into cgroup_file_notify() without respecting allow_spinning=false, leading to lock recursion.

How to fix it

Upgrade the Linux kernel to commit 449682e76f32601f211816d3e2100bed87e67a4c or later; for affected busybox packages on Debian 11-14 apply the fixed version 1:1.27.2-1; rebuild and redeploy any custom BPF programs after the kernel update.

How to confirm the fix worked

Confirm the running kernel contains commit 449682e76f32601f211816d3e2100bed87e67a4c; test by loading a BPF program that calls bpf_timer_init() from scheduler ops and verify absence of lockdep warnings or hardlockups under memcg pressure.

Typical attack path

  1. Load a crafted BPF program targeting sched_ext ops
  2. Trigger enqueue or wakeup paths that hold rq_lock
  3. Call bpf_timer_init() from the BPF context
  4. Force memcg charge that raises MEMCG_MAX event
  5. Induce recursive lock acquisition causing hardlockup

How to detect it

Search kernel logs for hardlockup or lockdep splats mentioning bpf_timer_init, __bpf_async_init, try_charge_memcg, or rq_lock recursion; inspect audit logs for unexpected BPF program loads from untrusted sources.

What your security team should do

  • Prioritize kernel updates on all hosts running sched_ext or heavy BPF workloads
  • Monitor for kernel lockdep or hardlockup reports referencing bpf_timer_init and memcg
  • Review and restrict untrusted BPF program loading via LSM or seccomp policies
  • Validate the fix in staging environments that reproduce the original stack trace

The record

In the Linux kernel, the following vulnerability has been resolved: bpf: Tell memcg to use allow_spinning=false path in bpf_timer_init() Currently, calling bpf_map_kmalloc_node() from __bpf_async_init() can cause various locking issues; see the following stack trace (edited for style) as one example: ... [10.011566] do_raw_spin_lock.cold [10.011570] try_to_wake_up (5) double-acquiring the same [10.011575] kick_pool rq_lock, causing a hardlockup [10.011579] __queue_work [10.011582] queue_work_on [10.011585] kernfs_notify [10.011589] cgroup_file_notify [10.011593] try_charge_memcg (4) memcg accounting raises an [10.011597] obj_cgroup_charge_pages MEMCG_MAX event [10.011599] obj_cgroup_charge_account [10.011600] __memcg_slab_post_alloc_hook [10.011603] __kmalloc_node_noprof ... [10.011611] bpf_map_kmalloc_node [10.011612] __bpf_async_init [10.011615] bpf_timer_init (3) BPF calls bpf_timer_init() [10.011617] bpf_prog_xxxxxxxxxxxxxxxx_fcg_runnable [10.011619] bpf__sched_ext_ops_runnable [10.011620] enqueue_task_scx (2) BPF runs with rq_lock held [10.011622] enqueue_task [10.011626] ttwu_do_activate [10.011629] sched_ttwu_pending (1) grabs rq_lock ... The above was reproduced on bpf-next (b338cf849ec8) by modifying ./tools/sched_ext/scx_flatcg.bpf.c to call bpf_timer_init() during ops.runnable(), and hacking the memcg accounting code a bit to make a bpf_timer_init() call more likely to raise an MEMCG_MAX event. We have also run into other similar variants (both internally and on bpf-next), including double-acquiring cgroup_file_kn_lock, the same worker_pool::lock, etc. As suggested by Shakeel, fix this by using __GFP_HIGH instead of GFP_ATOMIC in __bpf_async_init(), so that e.g. if try_charge_memcg() raises an MEMCG_MAX event, we call __memcg_memory_event() with @allow_spinning=false and avoid calling cgroup_file_notify() there. Depends on mm patch "memcg: skip cgroup_file_notify if spinning is not allowed": https://lore.kernel.org/bpf/20250905201606.66198-1-shakeel.butt@linux.dev/ v0 approach s/bpf_map_kmalloc_node/bpf_mem_alloc/ https://lore.kernel.org/bpf/20250905061919.439648-1-yepeilin@google.com/ v1 approach: https://lore.kernel.org/bpf/20250905234547.862249-1-yepeilin@google.com/

Affected packages

Ecosystem Package Introduced Fixed
Debian:12 linux 0 No fix
Debian:13 linux 0 6.12.48-1
Debian:14 linux 0 No fix
Linux Kernel 5.15.0 6.6.107
Mageia:9 kernel 0 6.6.116-1.mga9
Mageia:9 kernel-linus 0 6.6.116-1.mga9
Mageia:9 kmod-virtualbox 0 7.1.14-13.mga9
Mageia:9 kmod-xtables-addons 0 3.24-87.mga9

Related vulnerabilities