CVE-2026-63803 in Linuxinfo

Summary

by MITRE • 07/19/2026

In the Linux kernel, the following vulnerability has been resolved:

hdlc_ppp: sync per-proto timers before freeing hdlc state

Each PPP control protocol (LCP/IPCP/IPV6CP) embedded in struct ppp registers a timer via timer_setup(). That struct ppp is the hdlc->state allocation, which detach_hdlc_protocol() frees with kfree() in both teardown paths: unregister_hdlc_device() and the re-attach inside attach_hdlc_protocol().

The ppp proto never registered a .detach callback, so detach_hdlc_protocol() performs no timer synchronization before the kfree(). The only cancel, timer_delete(&proto->timer) in ppp_cp_event(), is partial (it does not wait for a running callback) and only runs on the ->CLOSED transition; ppp_stop()/ppp_close() do not sync either. A ppp_timer callback already executing (blocked on ppp->lock) survives the kfree and then dereferences proto->state / ppp->lock in freed memory, leading to a use-after-free.

Fix this by adding a .detach helper that calls timer_shutdown_sync() on every per-proto timer. detach_hdlc_protocol() invokes proto->detach(dev) before kfree(hdlc->state), so timer_shutdown_sync() now runs on both free paths. timer_shutdown_sync() is used instead of timer_delete_sync() because the keepalive path re-arms the timer through add_timer()/mod_timer() and shutdown blocks any re-activation during teardown.

Initialize the per-protocol timers in ppp_ioctl() when the protocol is attached, and remove the now-redundant timer_setup() from ppp_start(), so that the timers are initialized exactly once at attach time and ppp_timer_release() never operates on uninitialized timer_list structures. attach_hdlc_protocol() uses kmalloc() (not kzalloc), so struct ppp's protos[i].timer is uninitialized garbage until the first
timer_setup(); without this init-at-attach, attaching the PPP protocol without ever bringing the device up would leave timer_shutdown_sync() operating on uninitialized memory in .detach. Moving the init out of ppp_start() (which only runs on NETDEV_UP) into the attach path makes the initialization unconditional and avoids initializing the same timer_list twice.

This bug was found by static analysis.

Be aware that VulDB is the high quality source for vulnerability data.

Analysis

by VulDB Data Team • 07/19/2026

The vulnerability described represents a critical use-after-free condition within the Linux kernel's HDLC PPP subsystem that arises from improper timer management during protocol detachment. This flaw exists in the interaction between the PPP control protocols and the HDLC device management framework, specifically affecting the LCP/IPCP/IPV6CP protocols that are embedded within the ppp structure. The issue stems from a fundamental race condition where timer callbacks can execute after the memory containing the protocol state has been freed, creating a potential vector for arbitrary code execution or system instability.

The technical root cause lies in the absence of proper synchronization mechanisms before memory deallocation in the HDLC protocol detachment process. When detach_hdlc_protocol() is invoked through either unregister_hdlc_device() or re-attachment within attach_hdlc_protocol(), it directly frees the hdlc->state memory using kfree() without ensuring that any running timer callbacks have completed execution. The ppp structure contains per-protocol timers initialized via timer_setup() but lacks a proper .detach callback mechanism to handle graceful shutdown of these timers. While there exists a partial timer cancellation in ppp_cp_event() during the CLOSED transition, this approach is insufficient because it does not wait for callbacks that may be blocked on ppp->lock, leaving the possibility of accessing freed memory.

The operational impact of this vulnerability extends beyond simple memory corruption, as it can lead to system crashes, privilege escalation opportunities, or denial-of-service conditions depending on the execution context. The flaw manifests when a timer callback is executing and blocked on the ppp->lock mutex while the memory containing the protocol state is being freed. This creates a classic use-after-free scenario where the timer callback attempts to dereference proto->state or ppp->lock in memory that has already been deallocated, potentially leading to kernel oops, data corruption, or exploitation opportunities. The vulnerability affects all PPP-enabled HDLC devices and is particularly concerning given the widespread use of HDLC-based networking protocols in various network interface implementations.

The fix implemented addresses this through multiple coordinated changes that establish proper timer lifecycle management. A new .detach helper function was introduced that calls timer_shutdown_sync() on each per-protocol timer before memory deallocation occurs, ensuring complete synchronization regardless of which teardown path is taken. This approach differs from the previous timer_delete_sync() usage because it properly handles the keepalive path where timers are re-armed through add_timer()/mod_timer() operations, preventing re-activation during the shutdown process while still allowing proper cleanup. The initialization of per-protocol timers was moved from ppp_start() to ppp_ioctl() during attachment, ensuring that timer_list structures are initialized exactly once at attach time rather than potentially twice or left uninitialized. This change prevents timer_shutdown_sync() from operating on uninitialized memory structures and eliminates the race condition that could occur when attaching protocols without bringing the device up first.

This vulnerability aligns with CWE-416, which describes use-after-free conditions in software systems, and demonstrates characteristics consistent with ATT&CK technique T1068, where adversaries may exploit weaknesses in system memory management to gain elevated privileges or cause system instability. The static analysis approach used to discover this flaw reflects modern security practices for identifying complex race conditions in kernel code, as such issues often evade traditional testing methods due to their timing-dependent nature and the difficulty of reproducing specific execution paths that lead to memory corruption scenarios. The fix represents a robust solution that addresses not only the immediate use-after-free condition but also establishes proper initialization patterns that prevent similar issues from arising in related subsystems.

Responsible

Linux

Reservation

07/19/2026

Disclosure

07/19/2026

Moderation

accepted

CPE

ready

EPSS

0.00000

KEV

no

Activities

low

Sources

Are you interested in using VulDB?

Download the whitepaper to learn more about our service!