← Back to Feed CACHED · 2026-11-02 08:10:48 · CACHE_KEY CVE-2026-31419
CVE-2026-31419 · CWE-416 · Disclosed 2026-04-13

Linux kernel bonding UAF in bond_xmit_broadcast via racy last-slave check

ASSESSED — NOISGATE
Vendor
—
—
—
Reassessed
—
—
—
Verdict: —
Do you agree?
01 · The Real Story

The last courier on a shifting delivery route grabs the same parcel twice because the route list changes mid-handoff

bond_xmit_broadcast() in the Linux bonding driver re-uses the original skb for the last slave and clones it for earlier slaves. A concurrent enslave/release operation mutates the slave list while the transmit loop is iterating, so bond_is_last_slave() can return true twice and the same skb is consumed/freed more than once. The result is a slab use-after-free/double-free in skb_clone(). Affected kernels are those carrying the racy logic before the fix; the patch replaces the check with a snapshot index comparison (i + 1 == slaves_count) against a pre-read slave count.

Vendor severity of HIGH/7.8 is broadly fair for a local privilege-escalation-class bug, but the practical attack population is smaller than a generic Linux kernel LPE: the bug only exists when a bond is configured in mode=3 broadcast, and the trigger requires racing slave-list mutation — normally a privileged operation — with packet transmission. On hardened servers with unprivileged user namespaces disabled and static bonds, exposure is meaningfully less than the CVSS base suggests.

"Bonding broadcast UAF gives local attackers a high-value kernel corruption target, but only on hosts with broadcast-mode bonds and a race window."
02 · The Attack Path

5 steps from start to impact.

STEP 01

Obtain local low-privilege execution on a Linux host

The attacker needs a shell or a compromised container on a host that has the bonding module loaded. On permissive systems, unprivileged user namespaces allow creation of a private network namespace with CAP_NET_ADMIN, providing the required control without root in the init namespace.
Conditions required:
  • Local shell or compromised container
  • Linux host with bonding module available
Where this breaks in practice:
  • Unprivileged user namespaces are disabled on many hardened enterprise hosts
  • No remote network path reaches this code
STEP 02

Set up or locate a broadcast-mode bond with mutable slaves

Within the local namespace, create a bond interface and set mode=3 broadcast; attach veth slaves. Alternatively, race against an administrator or automation daemon that occasionally enslaves or releases physical devices on a production bond.
Conditions required:
  • CAP_NET_ADMIN in relevant user/network namespace
  • Bonding driver not blocked by LSM or module policy
Where this breaks in practice:
  • Broadcast mode is uncommon; most bonds use 802.3ad or active-backup
  • Creating network devices in a private namespace does not grant init-namespace privileges unless user namespaces are enabled
Detection/coverage: eBPF or auditd can monitor netlink RTM_SETLINK enslave/release events and bonding sysfs mode changes.
STEP 03

Flood broadcast traffic while mutating the slave list

Send small broadcast or unknown-destination packets into the bond rapidly while concurrently adding or removing a veth slave. The loop in bond_xmit_broadcast() sees the slave count change across iterations, so the last-slave decision becomes stale mid-transmit.
Conditions required:
  • Ability to generate packet traffic on the bond interface
  • Concurrent CAP_NET_ADMIN changes to slave list
Where this breaks in practice:
  • Race window is very small and usually requires repeated attempts
  • Some systems enforce restrictive netlink policies or LSMs that block unprivileged device control
Detection/coverage: KASAN builds will report the UAF; production hosts without KASAN may only show kernel oops or panic.
STEP 04

Trigger double-consumption and corrupt the skb slab

When the original skb is re-used both as the last slave and as a clone source after its reference has been dropped, skb_clone() dereferences freed memory. Attackers can groom the skbuff_head_cache slab to place a controlled object in the freed slot, converting the UAF into arbitrary read/write.
Conditions required:
  • Multiple overlapping transmit attempts
  • Heap grooming capability in the same CPU/slab context
Where this breaks in practice:
  • Kernel heap randomization and slab freelist hardening make deterministic exploitation non-trivial
  • Public PoC may stop at a KASAN crash rather than reliable LPE
Detection/coverage: KASAN, KUBSAN, or slab tracepoints can catch object reuse.
STEP 05

Escalate to root or crash the host

Successful UAF exploitation yields kernel-mode code execution, leading to local privilege escalation or container escape. Even an unsuccessful attempt can panic or crash the host, causing availability impact on shared hypervisor and storage workloads.
Conditions required:
  • Exploitable slab layout or repeated race attempts
Where this breaks in practice:
  • Kernel lockdown, SELinux/AppArmor, and reduced userns permissions can block namespace setup
  • On static bonds with no slave changes, the path never becomes racy
Detection/coverage: dmesg for BUG: KASAN: slab-use-after-free, skb_clone crash signatures, or repeated kernel panics.
03 · Compensating Control

1
HIGH 7.2→MEDIUM 5.4
SEVERITY REDUCED
Disable unprivileged user namespaces on Linux hosts with bonded interfaces — Set kernel.unprivileged_userns_clone=0 or user.max_user_namespaces=0 so a local low-privilege user cannot create a private network namespace with CAP_NET_ADMIN. Deploy within 30 days on HIGH. This breaks the easiest path for unprivileged attackers on multi-tenant and hypervisor nodes.
2
HIGH 7.2→LOW 1.8
SEVERITY REDUCED
Replace broadcast-mode bonding with 802.3ad or active-backup — The vulnerable function is only reached for mode=3 broadcast. Move bonded interfaces to LACP or active-backup unless broadcast is mandatory. Deploy within 30 days on HIGH. This removes the affected code path entirely on those hosts.
3
HIGH 7.2→IGNORE 0.0
SEVERITY REDUCED
Apply the kernel patch or backported fix — Remediation: update to a kernel containing the i + 1 == slaves_count snapshot fix. Schedule via noisgate remediation SLA ≤180 days for HIGH; prioritize KVM, storage, and network-edge bonding hosts.
What doesn't work
  • Network firewalls and ACLs do not help — this is local kernel memory corruption reached after local packet transmission, not a remote packet path.
  • Disabling IPv6 or UDP does not stop the race; IPv4 and ARP broadcast frames through any broadcast-mode bond can reach the same function.
  • LSM DAC/ACLs alone are insufficient because unprivileged user namespaces can grant CAP_NET_ADMIN in a private namespace; only disabling userns or blocking bonding setup closes that vector.
04 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo known in-the-wild exploitation; not in CISA KEV as of 2026-04-13.
Proof-of-concept availabilityNo public weaponized PoC indexed; the CVE record mentions a KASAN reproducer using task exploit/147, but no published repository was identified.
EPSS score0.00129 (0.129% probability over next 30 days; bottom percentile).
KEV statusNot listed in CISA KEV as of 2026-04-13.
CVSS vectorCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H — local low-privilege attacker, no user interaction, high confidentiality/integrity/availability impact.
Affected versionsLinux kernels before the bond_xmit_broadcast fix; all stable branches that backported the buggy bond_is_last_slave logic.
Fixed versionsMainline after the fix; stable backports expected but not enumerated in the CVE record.
Exposure scanningNot remotely detectable; local checks for mode=broadcast bond interfaces and unprivileged userns settings.
Disclosed2026-04-13
ReporterLinux kernel networking maintainers; details in the official CVE record.

Sources.

  1. NVD CVE-2026-31419
  2. CVE.org record
  3. Linux kernel bonding source
  4. Red Hat CVE page
  5. Ubuntu CVE page
  6. Debian security tracker
  7. CISA KEV catalog
  8. PoCindex entry
05 · The Call

Final Verdict
= UNCHANGED to HIGH (7.2/10)

Why this verdict

  • Local-only, narrow config: the flaw requires local execution plus a bond in broadcast mode, which is a minority of enterprise bonds.
  • Race dependency: an attacker must mutate the slave list concurrently with transmit; static bond configs never hit the path.
  • Role multiplier: on KVM/container/storage hosts that use bonded NICs, successful UAF exploitation becomes a host LPE and can cross tenant/VLAN boundaries — this keeps the floor at HIGH despite the friction.
  • Starting from the vendor 7.8 baseline, subtract for uncommon broadcast mode and race/userns restrictions; the high-value-role floor arrests the downgrade at HIGH.

Why not higher?

Not CRITICAL because there is no remote unauthenticated vector, no KEV or active-exploitation evidence, and no public weaponized PoC. Reliable LPE requires winning a small race and out-maneuvering modern kernel slab hardening; many attempts will only crash the target.

Why not lower?

Cannot go below HIGH for realistic high-value deployments because bonded Linux servers are commonly hypervisor, storage, or network-edge systems where a kernel UAF means host compromise. Even a simple race-triggered crash gives a local unprivileged user a reliable availability attack on those systems.

06 · Verification

Crowdsourced verification payload.

Run on each Linux host that may use bonding, especially hypervisor, container, storage, and network-edge nodes. Invoke sudo bash cve-2026-31419-check.sh. The script needs read access to sysfs and /proc; sudo helps inspect module state and kernel source if present.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/bin/bash
# CVE-2026-31419 detector: Linux bonding UAF in bond_xmit_broadcast
set -u

patch_state='unknown'
bond_found=0
has_broadcast=0

if lsmod 2>/dev/null | grep -q '^bonding'; then
  bond_found=1
fi
if [ -d /sys/module/bonding ]; then
  bond_found=1
fi

for modefile in /sys/class/net/*/bonding/mode; do
  [ -e "$modefile" ] || continue
  iface=$(echo "$modefile" | cut -d/ -f5)
  mode=$(cat "$modefile" 2>/dev/null || true)
  echo "INFO: $iface mode = $mode" >&2
  if echo "$mode" | grep -qi 'broadcast'; then
    has_broadcast=1
  fi
  bond_found=1
done

build_dir="/lib/modules/$(uname -r)/build"
if [ -f "$build_dir/drivers/net/bonding/bond_main.c" ]; then
  if grep -q 'i + 1 == slaves_count' "$build_dir/drivers/net/bonding/bond_main.c"; then
    patch_state='patched'
  elif grep -q 'bond_is_last_slave' "$build_dir/drivers/net/bonding/bond_main.c"; then
    patch_state='vulnerable'
  fi
fi

if [ "$patch_state" = 'patched' ]; then
  echo 'PATCHED'
  exit 0
fi

if [ "$patch_state" = 'vulnerable' ]; then
  echo 'VULNERABLE'
  exit 1
fi

if [ "$bond_found" -eq 1 ] && [ "$has_broadcast" -eq 1 ]; then
  echo 'VULNERABLE'
  exit 1
fi

if [ "$bond_found" -eq 1 ]; then
  echo 'UNKNOWN'
  exit 2
fi

echo 'UNKNOWN'
exit 2