CVE-2026-46158
Description
In the Linux kernel, the following vulnerability has been resolved:
mptcp: pm: ADD_ADDR rtx: always decrease sk refcount
When an ADD_ADDR is retransmitted, the sk is held in sk_reset_timer(). It should then be released in all cases at the end.
Some (unlikely) checks were returning directly instead of calling sock_put() to decrease the refcount. Jump to a new 'exit' label to call __sock_put() (which will become sock_put() in the next commit) to fix this potential leak.
While at it, drop the '!msk' check which cannot happen because it is never reset, and explicitly mark the remaining one as "unlikely".
Affected products
2Patches
6acd3d3562315mptcp: pm: ADD_ADDR rtx: always decrease sk refcount
1 file changed · +3 −6
net/mptcp/pm.c+3 −6 modifieddiff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 5cb62ab42cbe1f..4dcac6135fbfaf 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -344,11 +344,8 @@ static void mptcp_pm_add_timer(struct timer_list *timer) pr_debug("msk=%p\n", msk); - if (!msk) - return; - - if (inet_sk_state_load(sk) == TCP_CLOSE) - return; + if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE)) + goto exit; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -386,6 +383,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer) out: bh_unlock_sock(sk); +exit: __sock_put(sk); } -- cgit 1.3-korg
9634cb35af17mptcp: pm: ADD_ADDR rtx: always decrease sk refcount
1 file changed · +3 −6
net/mptcp/pm.c+3 −6 modifieddiff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 3912128d9b8668..2a01bf1b5bfdad 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -331,11 +331,8 @@ static void mptcp_pm_add_timer(struct timer_list *timer) pr_debug("msk=%p\n", msk); - if (!msk) - return; - - if (inet_sk_state_load(sk) == TCP_CLOSE) - return; + if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE)) + goto exit; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -373,6 +370,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer) out: bh_unlock_sock(sk); +exit: __sock_put(sk); } -- cgit 1.3-korg
25e37407442bmptcp: pm: ADD_ADDR rtx: always decrease sk refcount
1 file changed · +3 −6
net/mptcp/pm.c+3 −6 modifieddiff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 24295517711b46..37e48381ddebe5 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -344,11 +344,8 @@ static void mptcp_pm_add_timer(struct timer_list *timer) pr_debug("msk=%p\n", msk); - if (!msk) - return; - - if (inet_sk_state_load(sk) == TCP_CLOSE) - return; + if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE)) + goto exit; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -386,6 +383,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer) out: bh_unlock_sock(sk); +exit: __sock_put(sk); } -- cgit 1.3-korg
25e37407442bmptcp: pm: ADD_ADDR rtx: always decrease sk refcount
1 file changed · +3 −6
net/mptcp/pm.c+3 −6 modifieddiff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 24295517711b46..37e48381ddebe5 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -344,11 +344,8 @@ static void mptcp_pm_add_timer(struct timer_list *timer) pr_debug("msk=%p\n", msk); - if (!msk) - return; - - if (inet_sk_state_load(sk) == TCP_CLOSE) - return; + if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE)) + goto exit; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -386,6 +383,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer) out: bh_unlock_sock(sk); +exit: __sock_put(sk); } -- cgit 1.3-korg
9634cb35af17mptcp: pm: ADD_ADDR rtx: always decrease sk refcount
1 file changed · +3 −6
net/mptcp/pm.c+3 −6 modifieddiff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 3912128d9b8668..2a01bf1b5bfdad 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -331,11 +331,8 @@ static void mptcp_pm_add_timer(struct timer_list *timer) pr_debug("msk=%p\n", msk); - if (!msk) - return; - - if (inet_sk_state_load(sk) == TCP_CLOSE) - return; + if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE)) + goto exit; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -373,6 +370,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer) out: bh_unlock_sock(sk); +exit: __sock_put(sk); } -- cgit 1.3-korg
acd3d3562315mptcp: pm: ADD_ADDR rtx: always decrease sk refcount
1 file changed · +3 −6
net/mptcp/pm.c+3 −6 modifieddiff --git a/net/mptcp/pm.c b/net/mptcp/pm.c index 5cb62ab42cbe1f..4dcac6135fbfaf 100644 --- a/net/mptcp/pm.c +++ b/net/mptcp/pm.c @@ -344,11 +344,8 @@ static void mptcp_pm_add_timer(struct timer_list *timer) pr_debug("msk=%p\n", msk); - if (!msk) - return; - - if (inet_sk_state_load(sk) == TCP_CLOSE) - return; + if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE)) + goto exit; bh_lock_sock(sk); if (sock_owned_by_user(sk)) { @@ -386,6 +383,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer) out: bh_unlock_sock(sk); +exit: __sock_put(sk); } -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing `__sock_put()` call on early-return paths in `mptcp_pm_add_timer()` causes a socket reference-count leak."
Attack vector
An attacker who can influence MPTCP path-management signaling may cause the kernel to retransmit an ADD_ADDR option. When the retransmission timer fires (`sk_reset_timer()` holds a reference on `sk`), the `mptcp_pm_add_timer()` callback could hit an early-return check (e.g., the socket is in `TCP_CLOSE` state) and exit without calling `__sock_put()`. This leaks a socket reference; repeated occurrences could exhaust the socket memory or trigger use-after-free conditions. No special network position is required beyond the ability to establish an MPTCP connection and trigger ADD_ADDR retransmission.
Affected code
The bug is in the `mptcp_pm_add_timer()` function in `net/mptcp/pm.c` [patch_id=2898199]. Two early-return paths (the `!msk` check and the `inet_sk_state_load(sk) == TCP_CLOSE` check) returned directly without calling `__sock_put()`, causing a socket reference-count leak when an ADD_ADDR retransmission timer fires on a closed or otherwise early-exit path.
What the fix does
The patch replaces the two direct `return` statements with a `goto exit` and adds an `exit:` label after the existing `out:` label that calls `__sock_put(sk)` [patch_id=2898199]. This ensures the socket reference acquired by `sk_reset_timer()` is always released, even on the early-exit paths. The `!msk` check was removed entirely because `msk` is never reset after allocation, and the `TCP_CLOSE` check is now marked `unlikely` to reflect its rare occurrence.
Preconditions
- networkThe attacker must be able to establish an MPTCP connection and cause ADD_ADDR retransmissions (e.g., by triggering path-manager timeouts).
- configThe target kernel must have MPTCP path management enabled and the `mptcp_pm_add_timer()` code path reachable.
Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
3News mentions
0No linked articles in our index yet.