Skip to main content
Vulnerability Database/CVE-2026-98158

CVE-2026-98158: Linux Kernel PPP Async DoS Vulnerability

CVE-2026-98158 is a denial of service flaw in the Linux kernel PPP async module that causes system crashes through malformed frames. This post explains its technical details, impact, and mitigation steps.

Published:

CVE-2026-98158 Overview

CVE-2026-98158 is a Linux kernel vulnerability in the ppp_async driver that corrupts socket buffer (skb) headroom on the receive error path. The flawed error handler in process_input_packet() zeroes the headroom of a reused skb while claiming to restore it to a freshly allocated state. Subsequent calls to skb_push() in ppp_receive_nonmp_frame() then write below skb->head, triggering a skb_under_panic and kernel BUG. A remote peer that sends a malformed frame followed by a crafted follow-up frame can crash the kernel, producing a denial-of-service condition.

Critical Impact

A remote PPP peer can panic the Linux kernel by sending two crafted frames after a root-configured PPP session is established, with a reproducer that triggers the crash in approximately one second.

Affected Products

  • Linux kernel versions containing the ppp_async driver prior to the fix commits
  • Systems running Point-to-Point Protocol (PPP) over asynchronous transports (serial, pty)
  • Distributions shipping the vulnerable drivers/net/ppp/ppp_async.c code path

Discovery Timeline

  • 2026-09-25 - CVE-2026-98158 published to the National Vulnerability Database
  • 2026-09-30 - Last updated in NVD database

Technical Details for CVE-2026-98158

Vulnerability Analysis

The vulnerability resides in the PPP asynchronous receive path. ppp_receive_nonmp_frame() prepends a two-byte direction tag using skb_push(skb, 2) before executing the Berkeley Packet Filter (BPF) pass and active filters. The receive path assumes the skb always carries at least NET_SKB_PAD bytes of headroom, which dev_alloc_skb() guarantees for freshly allocated buffers.

The error handler in process_input_packet() violates this invariant. On a frame error, the code calls skb_trim(skb, 0) followed by skb_reserve(skb, -skb_headroom(skb)), which zeroes the headroom. The comment claims this restores the skb to a freshly allocated state, but a real fresh skb retains NET_SKB_PAD. Because ap->rpkt still points at this corrupted buffer, the next incoming frame is reassembled into it with zero headroom.

A peer that transmits a bad-FCS frame followed by a frame beginning with ff 03 leaves only a single byte of headroom when the filter tag push occurs. The resulting skb_push() writes one byte below skb->head, triggering skb_under_panic at net/core/skbuff.c:214 and a fatal kernel exception in interrupt context.

Root Cause

The root cause is an incorrect assumption in the error-recovery path about what constitutes a freshly allocated skb. By negating headroom entirely, the error handler breaks the NET_SKB_PAD contract that the rest of the receive path depends on. The same corrupted buffer also causes ppp_decompress_frame() to pass skb->data - 2 to ->decompress() and ->incomp() callbacks when CCP compression is enabled, producing an out-of-bounds read before skb->head.

Attack Vector

Exploitation requires a PPP session configured by a privileged local user, with a malicious or malformed remote peer on the other end of the link. The peer transmits two crafted frames: one with a bad frame check sequence to trigger the error path, followed by a frame whose header reduces available headroom to one byte. The second frame's filter-tag push then writes below skb->head, panicking the kernel. The attack is unauthenticated at the PPP layer once the session is established and can be executed over a pseudo-terminal, serial line, or any asynchronous transport that carries PPP.

No exploitation code is published with the advisory. The upstream commit message references a private fuzzing reproducer (repro-ppp-skb.c) that panics the kernel in approximately one second.

Detection Methods for CVE-2026-98158

Indicators of Compromise

  • Kernel panic messages containing skb_under_panic with a call trace through skb_push, ppp_receive_nonmp_frame, ppp_input, and ppp_async_process
  • Unexpected system reboots or crashes on hosts running pppd or terminating PPP sessions
  • BUG at net/core/skbuff.c:214 with RIP: skb_panic in the kernel log before the crash
  • Out-of-bounds read reports from KASAN inside ppp_decompress_frame when CCP is enabled

Detection Strategies

  • Audit hosts for loaded ppp_async and ppp_generic kernel modules using lsmod and inventory active PPP interfaces with ip link show type ppp
  • Compare running kernel versions against distribution advisories referencing commits 0c53eb14, 71713722, 8dc5d98a, and d0fc3dab
  • Enable kernel crash dumps (kdump) so post-crash analysis can confirm the signature when a panic occurs

Monitoring Recommendations

  • Forward /var/log/kern.log, dmesg, and journalctl -k output to a centralized log pipeline and alert on skb_under_panic or ppp_receive_nonmp_frame strings
  • Monitor PPP session establishment events and correlate them with subsequent kernel instability on the same host
  • Track unplanned reboots on systems exposing PPP endpoints and investigate any clustered occurrences

How to Mitigate CVE-2026-98158

Immediate Actions Required

  • Apply the upstream Linux kernel patches referenced in the stable tree commits as soon as distribution packages are available
  • Restrict which users can configure PPP interfaces by auditing CAP_NET_ADMIN grants and pppd setuid configuration
  • Disable PPP services on hosts that do not require them by unloading ppp_async and ppp_generic modules and blacklisting them in /etc/modprobe.d/

Patch Information

The upstream fix drops the errored frame and clears ap->rpkt so the next frame is reassembled into a freshly allocated skb with proper headroom, matching the behavior already present in ppp_synctty. The fix is distributed across the following stable kernel commits: Kernel Git Commit 0c53eb149, Kernel Git Commit 717137221, Kernel Git Commit 8dc5d98a16, and Kernel Git Commit d0fc3dabfe. Rebuild and reboot affected systems after applying the patch.

Workarounds

  • Terminate PPP sessions with untrusted peers until the kernel patch is deployed
  • Where PPP is required, restrict peers to authenticated and trusted endpoints over physically controlled links
  • Unload the ppp_async module on systems that do not actively need asynchronous PPP support
bash
# Prevent ppp_async from loading until patched kernel is deployed
echo 'blacklist ppp_async' | sudo tee /etc/modprobe.d/disable-ppp-async.conf
sudo rmmod ppp_async 2>/dev/null || true

# Verify the module is no longer loaded
lsmod | grep ppp_async

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.