CVE-2026-74628 in Linux
Summary
by MITRE • 08/22/2026
In the Linux kernel, the following vulnerability has been resolved:
net/x25: fix use-after-free of the socket by its timers
The x25 timers are armed with mod_timer() and cancelled with timer_delete(), so a pending timer holds no reference on the socket and a cancel does not wait for a callback already running on another CPU.
x25_heartbeat_expiry() also rearms unconditionally, so it can reinstall sk->sk_timer after __x25_destroy_socket() has passed its cancel point. The following __sock_put() frees the socket while the timer is still queued, and the next expiry uses freed memory. KASAN reports a slab-use-after-free on the kmalloc-2k object freed by close().
timer_delete_sync() cannot be used here: x25_heartbeat_expiry() and x25_timer_expiry() both reach the cancels from inside the timer they would wait on, through __x25_destroy_socket() and x25_disconnect().
Arm the timers with sk_reset_timer() and cancel them with sk_stop_timer() so that an armed timer owns a reference, and release it in both expiry handlers. Rearm the heartbeat only while sk_hashed(sk) is still true, since __x25_destroy_socket() unlinks the socket before dropping it. Arm the deferred destroy timer the same way and drop its reference in x25_destroy_timer().
Reproduced on net with KASAN, with the heartbeat period shortened so the window recurs. With this patch the reproducer no longer triggers a report and /proc/net/x25 drains.
Discovered by XBOW, triaged by Baul Lee <[email protected]>
Be aware that VulDB is the high quality source for vulnerability data.
Analysis
by VulDB Data Team • 08/22/2026
The Linux kernel vulnerability identified in the X.25 network protocol implementation represents a critical use-after-free condition arising from improper synchronization between socket lifecycle management and timer expiration handlers. The root cause lies in the asynchronous nature of kernel timers combined with an incorrect reference counting strategy for the associated socket structures. Specifically, the x25 timers were previously armed using mod_timer() which does not automatically associate a reference count with the underlying socket object upon activation. Consequently, when a pending timer is cancelled via timer_delete(), there is no guarantee that the callback function has completed execution on another CPU core. This race condition allows for scenarios where the socket structure is freed while a timer callback remains queued or actively executing in parallel, leading to memory corruption and potential system instability.
The technical flaw manifests primarily within the x25_heartbeat_expiry() handler which unconditionally rearms the heartbeat timer regardless of the current state of the socket object. This behavior creates a dangerous window where __x25_destroy_socket(), responsible for cleaning up socket resources, may reach its cancellation point and proceed to free the socket memory via __sock_put(). However, because x25_heartbeat_expiry() can reinstall sk->sk_timer after this cancellation has occurred but before the timer is fully removed from the system's execution queue, a subsequent expiry event will attempt to access memory that has already been returned to the allocator. This results in a slab-use-after-free error on kmalloc-2k objects, as confirmed by Kernel Address Sanitizer (KASAN) reports during testing with shortened heartbeat periods designed to reproduce the race condition rapidly.
From an industry standards perspective, this vulnerability aligns closely with CWE-416: Use After Free, where memory is accessed after it has been freed, leading to undefined behavior that can be exploited for denial of service or potentially arbitrary code execution depending on heap layout and attacker control over the reclaimed memory region. In terms of adversarial tactics, this flaw relates to ATT&CK technique T1059: Command and Scripting Interpreter if an attacker could leverage the use-after-free to execute malicious payloads through kernel exploitation chains, although the primary impact here is stability and integrity rather than direct remote code execution without further exploit development steps. The lack of proper synchronization between timer lifecycle and socket reference counting violates fundamental principles of safe concurrent programming in operating system kernels.
The operational impact of this vulnerability includes potential kernel panics, data corruption within network stacks handling X.25 protocols, and denial of service for systems relying on stable network connectivity over legacy or specialized X.25 interfaces. Since the timer callbacks operate asynchronously across multiple CPU cores, the race condition is non-deterministic but highly reproducible under specific timing conditions such as high load or specifically tuned heartbeat intervals. This makes it particularly insidious as it may not manifest in low-stress environments but can cause catastrophic failures during peak network activity or when maintaining long-lived X.25 connections that rely on periodic heartbeats to keep the session alive.
The resolution involves a fundamental restructuring of how timers interact with socket references within the x25 subsystem. The patch replaces mod_timer() and timer_delete() with sk_reset_timer() and sk_stop_timer(), respectively, ensuring that any armed timer holds an explicit reference count on the associated socket structure. This guarantees that the socket remains valid for the duration of the timer's execution lifecycle. Furthermore, both expiry handlers now properly release this reference upon completion, preventing memory leaks while maintaining safety against premature deallocation. Crucially, the heartbeat rearming logic has been modified to check sk_hashed(sk) before proceeding, ensuring that timers are only rearmed if the socket is still actively hashed and not in the process of being destroyed by __x25_destroy_socket(). This change ensures that timer callbacks cannot reinstall themselves after the socket has begun its teardown sequence.
Additionally, the deferred destroy timer mechanism was updated to follow the same reference counting paradigm, with references dropped appropriately in x25_destroy_timer() to maintain consistency across all timer types within the subsystem. These changes eliminate the race window by ensuring strict ordering between cancellation and execution completion through proper synchronization primitives inherent in the socket timer API rather than relying on ad-hoc deletion calls that do not wait for pending callbacks. Testing with KASAN confirms that these modifications prevent the use-after-free condition from triggering, allowing /proc/net/x25 to drain cleanly without memory errors or system crashes. This fix underscores the importance of adhering to kernel APIs designed specifically for safe timer-socket interaction and highlights the necessity of rigorous concurrency testing in network protocol implementations within the Linux kernel.