CVE-2024-35970 in Linuxinfo

Summary

by MITRE • 05/20/2024

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

af_unix: Clear stale u->oob_skb.

syzkaller started to report deadlock of unix_gc_lock after commit 4090fa373f0e ("af_unix: Replace garbage collection algorithm."), but it just uncovers the bug that has been there since commit 314001f0bf92 ("af_unix: Add OOB support").

The repro basically does the following.

from socket import * from array import array

c1, c2 = socketpair(AF_UNIX, SOCK_STREAM) c1.sendmsg([b'a'], [(SOL_SOCKET, SCM_RIGHTS, array("i", [c2.fileno()]))], MSG_OOB)
c2.recv(1) # blocked as no normal data in recv queue

c2.close() # done async and unblock recv() c1.close() # done async and trigger GC

A socket sends its file descriptor to itself as OOB data and tries to receive normal data, but finally recv() fails due to async close().

The problem here is wrong handling of OOB skb in manage_oob(). When recvmsg() is called without MSG_OOB, manage_oob() is called to check if the peeked skb is OOB skb. In such a case, manage_oob() pops it out of the receive queue but does not clear unix_sock(sk)->oob_skb. This is wrong in terms of uAPI.

Let's say we send "hello" with MSG_OOB, and "world" without MSG_OOB. The 'o' is handled as OOB data. When recv() is called twice without MSG_OOB, the OOB data should be lost.

>>> from socket import * >>> c1, c2 = socketpair(AF_UNIX, SOCK_STREAM, 0) >>> c1.send(b'hello', MSG_OOB) # 'o' is OOB data 5 >>> c1.send(b'world') 5 >>> c2.recv(5) # OOB data is not received b'hell' >>> c2.recv(5) # OOB date is skipped b'world' >>> c2.recv(5, MSG_OOB) # This should return an error b'o'

In the same situation, TCP actually returns -EINVAL for the last recv().

Also, if we do not clear unix_sk(sk)->oob_skb, unix_poll() always set EPOLLPRI even though the data has passed through by previous recv().

To avoid these issues, we must clear unix_sk(sk)->oob_skb when dequeuing it from recv queue.

The reason why the old GC did not trigger the deadlock is because the old GC relied on the receive queue to detect the loop.

When it is triggered, the socket with OOB data is marked as GC candidate because file refcount == inflight count (1). However, after traversing all inflight sockets, the socket still has a positive inflight count (1), thus the socket is excluded from candidates. Then, the old GC lose the chance to garbage-collect the socket.

With the old GC, the repro continues to create true garbage that will never be freed nor detected by kmemleak as it's linked to the global inflight list. That's why we couldn't even notice the issue.

If you want to get best quality of vulnerability data, you may have to visit VulDB.

Analysis

by VulDB Data Team • 12/11/2025

The vulnerability described in CVE-2024-35970 affects the Linux kernel's implementation of Unix domain sockets, specifically within the af_unix subsystem. This issue stems from improper handling of out-of-band (OOB) socket buffer skbs during garbage collection operations, leading to potential resource leaks and incorrect socket behavior. The flaw manifests when a socket sends its own file descriptor as OOB data and attempts to receive normal data, ultimately causing recv() to fail due to asynchronous close operations. The root cause lies in the manage_oob() function which fails to clear the unix_sock(sk)->oob_skb field when dequeuing OOB skbs from the receive queue, violating the expected socket API behavior.

The technical implementation flaw resides in the Unix domain socket garbage collection mechanism introduced in commit 4090fa373f0e, which exposed a pre-existing bug dating back to commit 314001f0bf92 that added OOB support. When recvmsg() is called without MSG_OOB, the manage_oob() function peeks at the receive queue to determine if there's OOB data present, but fails to properly clear the oob_skb reference after popping it from the queue. This results in a stale reference that persists even after the OOB data has been consumed, causing incorrect behavior in subsequent socket operations. The vulnerability creates a scenario where the socket poll mechanism continues to report EPOLLPRI events even after OOB data has been processed, and subsequent recv() calls with MSG_OOB fail to properly handle the state of the OOB data queue.

The operational impact of this vulnerability extends beyond simple incorrect behavior to potential resource exhaustion and system instability. The improper clearing of oob_skb references creates a form of memory leak where socket resources remain referenced even when they should be garbage collected, particularly evident in the garbage collection algorithm changes that altered how socket candidates are identified. The old garbage collection mechanism, while flawed in its own way, actually prevented the manifestation of this specific bug by relying on the receive queue to detect circular references, whereas the new algorithm's approach allows the stale references to persist in the global inflight list. This creates a situation where true garbage accumulates in memory without being detected by kmemleak, potentially leading to progressive memory consumption and system performance degradation. The deadlock scenario reported by syzkaller demonstrates how this flaw can manifest in complex race conditions involving asynchronous socket closure operations.

Mitigation strategies for this vulnerability require modifications to the socket subsystem's garbage collection and OOB data handling logic. The primary fix involves ensuring that unix_sock(sk)->oob_skb is properly cleared whenever an OOB skb is dequeued from the receive queue, preventing stale references from persisting. This aligns with CWE-457: Use of Uninitialized Variable, as the improper clearing of the oob_skb field creates a form of uninitialized state that affects subsequent socket operations. The fix must also ensure proper handling of socket poll events to prevent continuous EPOLLPRI notifications and align with TCP socket behavior where subsequent MSG_OOB recv() calls return -EINVAL when no OOB data remains. Additionally, the garbage collection algorithm should be enhanced to properly detect and handle sockets with stale OOB references, preventing the accumulation of unreferenced socket resources that could lead to memory exhaustion. System administrators should ensure kernel updates are applied promptly to address this vulnerability, particularly in environments where Unix domain sockets are heavily utilized and where resource consumption patterns could be affected by the memory leak characteristics of this flaw.

Reservation

05/17/2024

Disclosure

05/20/2024

Moderation

accepted

CPE

ready

EPSS

0.00499

KEV

no

Activities

very low

Sources

Might our Artificial Intelligence support you?

Check our Alexa App!