CVE-2026-46168
Description
In the Linux kernel, the following vulnerability has been resolved:
mptcp: fix scheduling with atomic in timestamp sockopt
Using lock_sock_fast() (atomic context) around sock_set_timestamp() and sock_set_timestamping() is unsafe, as both helpers can sleep.
Replace lock_sock_fast() with sleepable lock_sock()/release_sock() to avoid scheduling while atomic panic.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
A Linux kernel MPTCP vulnerability allows atomic scheduling panic when using lock_sock_fast() around sleepable sock_set_timestamp*() helpers.
Vulnerability
In the Linux kernel, the MPTCP (Multipath TCP) subsystem implements timestamp socket options via sock_set_timestamp() and sock_set_timestamping(). The vulnerability occurs because lock_sock_fast() (which acquires the socket lock in atomic context) is used to wrap calls to these helpers. However, both helpers can sleep, leading to a "scheduling while atomic" panic. The affected versions are those containing the faulty code path prior to the fix commit [1].
Exploitation
An attacker must be able to set timestamp socket options on an MPTCP socket via the setsockopt() system call. This requires the ability to invoke system calls (i.e., local user access). No special privilege is needed beyond the ability to open and configure sockets. By triggering the specific code path that uses lock_sock_fast() around sock_set_timestamp() or sock_set_timestamping(), the attacker can cause the kernel to attempt to sleep in an atomic context, resulting in a kernel panic.
Impact
A successful exploitation causes a kernel panic (denial of service), crashing the system. The impact is limited to availability; there is no evidence of privilege escalation or information disclosure. The crash is immediate upon triggering the vulnerable code path.
Mitigation
The fix is included in Linux kernel stable tree via commit b157dab93a7af44a84e78cf0cb311dde475cff5b [1]. Users should update to a kernel version containing this commit. No workaround is documented for unpatched kernels. The vulnerability is not listed on the CISA Known Exploited Vulnerabilities (KEV) catalog at publication time.
AI Insight generated on May 28, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
107eb513b42721mptcp: fix scheduling with atomic in timestamp sockopt
1 file changed · +4 −5
net/mptcp/sockopt.c+4 −5 modifieddiff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 30b45d2ab38c8a..1cf608e7357bda 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -159,10 +159,10 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamp(ssk, optname, !!val); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); @@ -235,10 +235,10 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamping(ssk, optname, timestamping); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); -- cgit 1.3-korg
ebeb70e29e37mptcp: fix scheduling with atomic in timestamp sockopt
1 file changed · +4 −5
net/mptcp/sockopt.c+4 −5 modifieddiff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 9496c805185afe..b5bf47218a18f5 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -159,10 +159,10 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamp(ssk, optname, !!val); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); @@ -235,10 +235,10 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamping(ssk, optname, timestamping); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); -- cgit 1.3-korg
8a005fe451c7mptcp: fix scheduling with atomic in timestamp sockopt
1 file changed · +4 −5
net/mptcp/sockopt.c+4 −5 modifieddiff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 7e131c44945e90..de12b3c548eddc 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -159,10 +159,10 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamp(ssk, optname, !!val); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); @@ -235,10 +235,10 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamping(ssk, optname, timestamping); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); -- cgit 1.3-korg
b5c52908d52cmptcp: fix scheduling with atomic in timestamp sockopt
1 file changed · +4 −5
net/mptcp/sockopt.c+4 −5 modifieddiff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 79db15903e7a52..0efe40be2fde07 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -159,10 +159,10 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamp(ssk, optname, !!val); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); @@ -235,10 +235,10 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamping(ssk, optname, timestamping); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); -- cgit 1.3-korg
b157dab93a7amptcp: fix scheduling with atomic in timestamp sockopt
1 file changed · +4 −5
net/mptcp/sockopt.c+4 −5 modifieddiff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index e0481155c5ab0d..acaaf3174ee059 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -159,10 +159,10 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamp(ssk, optname, !!val); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); @@ -235,10 +235,10 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamping(ssk, optname, timestamping); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); -- cgit 1.3-korg
ebeb70e29e37mptcp: fix scheduling with atomic in timestamp sockopt
1 file changed · +4 −5
net/mptcp/sockopt.c+4 −5 modifieddiff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 9496c805185afe..b5bf47218a18f5 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -159,10 +159,10 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamp(ssk, optname, !!val); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); @@ -235,10 +235,10 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamping(ssk, optname, timestamping); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); -- cgit 1.3-korg
7eb513b42721mptcp: fix scheduling with atomic in timestamp sockopt
1 file changed · +4 −5
net/mptcp/sockopt.c+4 −5 modifieddiff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 30b45d2ab38c8a..1cf608e7357bda 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -159,10 +159,10 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamp(ssk, optname, !!val); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); @@ -235,10 +235,10 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamping(ssk, optname, timestamping); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); -- cgit 1.3-korg
8a005fe451c7mptcp: fix scheduling with atomic in timestamp sockopt
1 file changed · +4 −5
net/mptcp/sockopt.c+4 −5 modifieddiff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 7e131c44945e90..de12b3c548eddc 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -159,10 +159,10 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamp(ssk, optname, !!val); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); @@ -235,10 +235,10 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamping(ssk, optname, timestamping); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); -- cgit 1.3-korg
b157dab93a7amptcp: fix scheduling with atomic in timestamp sockopt
1 file changed · +4 −5
net/mptcp/sockopt.c+4 −5 modifieddiff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index e0481155c5ab0d..acaaf3174ee059 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -159,10 +159,10 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamp(ssk, optname, !!val); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); @@ -235,10 +235,10 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamping(ssk, optname, timestamping); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); -- cgit 1.3-korg
b5c52908d52cmptcp: fix scheduling with atomic in timestamp sockopt
1 file changed · +4 −5
net/mptcp/sockopt.c+4 −5 modifieddiff --git a/net/mptcp/sockopt.c b/net/mptcp/sockopt.c index 79db15903e7a52..0efe40be2fde07 100644 --- a/net/mptcp/sockopt.c +++ b/net/mptcp/sockopt.c @@ -159,10 +159,10 @@ static int mptcp_setsockopt_sol_socket_tstamp(struct mptcp_sock *msk, int optnam lock_sock(sk); mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamp(ssk, optname, !!val); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); @@ -235,10 +235,10 @@ static int mptcp_setsockopt_sol_socket_timestamping(struct mptcp_sock *msk, mptcp_for_each_subflow(msk, subflow) { struct sock *ssk = mptcp_subflow_tcp_sock(subflow); - bool slow = lock_sock_fast(ssk); + lock_sock(ssk); sock_set_timestamping(ssk, optname, timestamping); - unlock_sock_fast(ssk, slow); + release_sock(ssk); } release_sock(sk); -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Using lock_sock_fast() (atomic context) around sock_set_timestamp() and sock_set_timestamping(), which can sleep, causes a scheduling-while-atomic panic."
Attack vector
An attacker (or any user with `setsockopt` access) triggers the bug by setting a socket timestamp option (e.g., `SO_TIMESTAMP`, `SO_TIMESTAMPING`, or related `SOF_TIMESTAMPING_*` flags) on an MPTCP socket. The kernel then propagates the timestamp request to each TCP subflow via `mptcp_setsockopt_sol_socket_tstamp` or `mptcp_setsockopt_sol_socket_timestamping`. Because the subflow socket is locked with `lock_sock_fast()` (atomic context) but `sock_set_timestamp()` and `sock_set_timestamping()` can sleep, the kernel may trigger a "scheduling while atomic" panic, resulting in a denial of service [patch_id=2898103].
Affected code
The vulnerability is in `net/mptcp/sockopt.c` in two functions: `mptcp_setsockopt_sol_socket_tstamp` (line ~159) and `mptcp_setsockopt_sol_socket_timestamping` (line ~235). Both functions iterate over MPTCP subflows and call `sock_set_timestamp()` or `sock_set_timestamping()` while holding the subflow socket lock obtained via `lock_sock_fast()`, which is an atomic-context lock [patch_id=2898103].
What the fix does
The patch replaces `lock_sock_fast(ssk)` / `unlock_sock_fast(ssk, slow)` with `lock_sock(ssk)` / `release_sock(ssk)` in both `mptcp_setsockopt_sol_socket_tstamp` and `mptcp_setsockopt_sol_socket_timestamping` [patch_id=2898103]. `lock_sock()` is a sleepable lock that permits the subsequent `sock_set_timestamp()` and `sock_set_timestamping()` calls to sleep if needed, eliminating the "scheduling while atomic" panic. The `slow` boolean variable is no longer needed and is removed.
Preconditions
- inputThe attacker must be able to invoke setsockopt() on an MPTCP socket with timestamp-related options (SO_TIMESTAMP, SO_TIMESTAMPING, etc.).
- configThe MPTCP socket must have at least one established subflow for the propagation loop to execute.
Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- git.kernel.org/stable/c/7eb513b42721bee4b96da69f6188d5a7783f210dnvd
- git.kernel.org/stable/c/8a005fe451c73fd2b3d1faa5643c11e6bd07acfcnvd
- git.kernel.org/stable/c/b157dab93a7af44a84e78cf0cb311dde475cff5bnvd
- git.kernel.org/stable/c/b5c52908d52c6c8eb8933264aa6087a0600fd892nvd
- git.kernel.org/stable/c/ebeb70e29e37cfce899309cc2665a3bfe960ed94nvd
News mentions
0No linked articles in our index yet.