VYPR
Unrated severityNVD Advisory· Published May 28, 2026

CVE-2026-46137

CVE-2026-46137

Description

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

mptcp: pm: ADD_ADDR rtx: fix potential data-race

This mptcp_pm_add_timer() helper is executed as a timer callback in softirq context. To avoid any data races, the socket lock needs to be held with bh_lock_sock().

If the socket is in use, retry again soon after, similar to what is done with the keepalive timer.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

A data-race in Linux kernel MPTCP's ADD_ADDR retransmission timer can occur when the socket lock is not held, potentially causing concurrency issues.

Vulnerability

The MPTCP path manager's ADD_ADDR retransmission timer, implemented in mptcp_pm_add_timer(), is executed as a timer callback in softirq context. The code failed to hold the socket lock via bh_lock_sock(), leading to a potential data-race when the socket is accessed concurrently. This affects Linux kernel versions containing the MPTCP subsystem prior to the fix introduced in commit 5cd6e0ad79d2615264f63929f8b457ad97ae550d [1].

Exploitation

An attacker would need to trigger the MPTCP ADD_ADDR retransmission timer while the socket is in use by another context (e.g., user space or other kernel paths). No authentication or special privileges are mentioned; the race occurs during normal MPTCP operation. The exact sequence of steps is not specified in the available references.

Impact

A data-race can lead to undefined behavior, including memory corruption, use-after-free, or other concurrency bugs. The impact may vary depending on the kernel configuration and workload, but it could result in system instability or information disclosure.

Mitigation

The fix is included in the Linux kernel stable commit 5cd6e0ad79d2615264f63929f8b457ad97ae550d [1]. Users should update to a kernel version containing this patch. No workaround is documented.

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

1

Patches

10
013dcdc19615

mptcp: pm: ADD_ADDR rtx: fix potential data-race

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"Matthieu Baerts (NGI0)"May 18, 2026Fixed in 6.6.141via kernel-cna
1 file changed · +8 1
  • net/mptcp/pm_netlink.c+8 1 modified
    diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
    index a2f15d332da597..440dfc4d362419 100644
    --- a/net/mptcp/pm_netlink.c
    +++ b/net/mptcp/pm_netlink.c
    @@ -308,6 +308,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     	if (!entry->addr.id)
     		return;
     
    +	bh_lock_sock(sk);
    +	if (sock_owned_by_user(sk)) {
    +		/* Try again later. */
    +		sk_reset_timer(sk, timer, jiffies + HZ / 20);
    +		goto out;
    +	}
    +
     	if (mptcp_pm_should_add_signal_addr(msk)) {
     		sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
     		goto out;
    @@ -336,6 +343,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     		mptcp_pm_subflow_established(msk);
     
     out:
    +	bh_unlock_sock(sk);
     	__sock_put(sk);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
6e4710d7d878

mptcp: pm: ADD_ADDR rtx: fix potential data-race

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"Matthieu Baerts (NGI0)"May 18, 2026Fixed in 6.12.91via kernel-cna
1 file changed · +8 1
  • net/mptcp/pm_netlink.c+8 1 modified
    diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
    index 11743b37d01f67..b17eaea26ce4b1 100644
    --- a/net/mptcp/pm_netlink.c
    +++ b/net/mptcp/pm_netlink.c
    @@ -307,6 +307,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     	if (!entry->addr.id)
     		return;
     
    +	bh_lock_sock(sk);
    +	if (sock_owned_by_user(sk)) {
    +		/* Try again later. */
    +		sk_reset_timer(sk, timer, jiffies + HZ / 20);
    +		goto out;
    +	}
    +
     	if (mptcp_pm_should_add_signal_addr(msk)) {
     		sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
     		goto out;
    @@ -335,6 +342,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     		mptcp_pm_subflow_established(msk);
     
     out:
    +	bh_unlock_sock(sk);
     	__sock_put(sk);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
2ad56e434199

mptcp: pm: ADD_ADDR rtx: fix potential data-race

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"Matthieu Baerts (NGI0)"Fixed in 6.18.30via kernel-cna
1 file changed · +8 1
  • net/mptcp/pm.c+8 1 modified
    diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
    index 8852aef5e61879..5cb62ab42cbe1f 100644
    --- a/net/mptcp/pm.c
    +++ b/net/mptcp/pm.c
    @@ -350,6 +350,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     	if (inet_sk_state_load(sk) == TCP_CLOSE)
     		return;
     
    +	bh_lock_sock(sk);
    +	if (sock_owned_by_user(sk)) {
    +		/* Try again later. */
    +		sk_reset_timer(sk, timer, jiffies + HZ / 20);
    +		goto out;
    +	}
    +
     	if (mptcp_pm_should_add_signal_addr(msk)) {
     		sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
     		goto out;
    @@ -378,6 +385,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     		mptcp_pm_subflow_established(msk);
     
     out:
    +	bh_unlock_sock(sk);
     	__sock_put(sk);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
5cd6e0ad79d2

mptcp: pm: ADD_ADDR rtx: fix potential data-race

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"Matthieu Baerts (NGI0)"Fixed in 7.1-rc3via kernel-cna
1 file changed · +8 1
  • net/mptcp/pm.c+8 1 modified
    diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
    index 5056eb8db24e05..3912128d9b8668 100644
    --- a/net/mptcp/pm.c
    +++ b/net/mptcp/pm.c
    @@ -337,6 +337,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     	if (inet_sk_state_load(sk) == TCP_CLOSE)
     		return;
     
    +	bh_lock_sock(sk);
    +	if (sock_owned_by_user(sk)) {
    +		/* Try again later. */
    +		sk_reset_timer(sk, timer, jiffies + HZ / 20);
    +		goto out;
    +	}
    +
     	if (mptcp_pm_should_add_signal_addr(msk)) {
     		sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
     		goto out;
    @@ -365,6 +372,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     		mptcp_pm_subflow_established(msk);
     
     out:
    +	bh_unlock_sock(sk);
     	__sock_put(sk);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
cc3c0399361e

mptcp: pm: ADD_ADDR rtx: fix potential data-race

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git"Matthieu Baerts (NGI0)"Fixed in 7.0.7via kernel-cna
1 file changed · +8 1
  • net/mptcp/pm.c+8 1 modified
    diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
    index c46b7b0ca71380..24295517711b46 100644
    --- a/net/mptcp/pm.c
    +++ b/net/mptcp/pm.c
    @@ -350,6 +350,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     	if (inet_sk_state_load(sk) == TCP_CLOSE)
     		return;
     
    +	bh_lock_sock(sk);
    +	if (sock_owned_by_user(sk)) {
    +		/* Try again later. */
    +		sk_reset_timer(sk, timer, jiffies + HZ / 20);
    +		goto out;
    +	}
    +
     	if (mptcp_pm_should_add_signal_addr(msk)) {
     		sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
     		goto out;
    @@ -378,6 +385,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     		mptcp_pm_subflow_established(msk);
     
     out:
    +	bh_unlock_sock(sk);
     	__sock_put(sk);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
013dcdc19615

mptcp: pm: ADD_ADDR rtx: fix potential data-race

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git"Matthieu Baerts (NGI0)"May 18, 2026via nvd-ref
1 file changed · +8 1
  • net/mptcp/pm_netlink.c+8 1 modified
    diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
    index a2f15d332da597..440dfc4d362419 100644
    --- a/net/mptcp/pm_netlink.c
    +++ b/net/mptcp/pm_netlink.c
    @@ -308,6 +308,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     	if (!entry->addr.id)
     		return;
     
    +	bh_lock_sock(sk);
    +	if (sock_owned_by_user(sk)) {
    +		/* Try again later. */
    +		sk_reset_timer(sk, timer, jiffies + HZ / 20);
    +		goto out;
    +	}
    +
     	if (mptcp_pm_should_add_signal_addr(msk)) {
     		sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
     		goto out;
    @@ -336,6 +343,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     		mptcp_pm_subflow_established(msk);
     
     out:
    +	bh_unlock_sock(sk);
     	__sock_put(sk);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
6e4710d7d878

mptcp: pm: ADD_ADDR rtx: fix potential data-race

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git"Matthieu Baerts (NGI0)"May 18, 2026via nvd-ref
1 file changed · +8 1
  • net/mptcp/pm_netlink.c+8 1 modified
    diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c
    index 11743b37d01f67..b17eaea26ce4b1 100644
    --- a/net/mptcp/pm_netlink.c
    +++ b/net/mptcp/pm_netlink.c
    @@ -307,6 +307,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     	if (!entry->addr.id)
     		return;
     
    +	bh_lock_sock(sk);
    +	if (sock_owned_by_user(sk)) {
    +		/* Try again later. */
    +		sk_reset_timer(sk, timer, jiffies + HZ / 20);
    +		goto out;
    +	}
    +
     	if (mptcp_pm_should_add_signal_addr(msk)) {
     		sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
     		goto out;
    @@ -335,6 +342,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     		mptcp_pm_subflow_established(msk);
     
     out:
    +	bh_unlock_sock(sk);
     	__sock_put(sk);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
cc3c0399361e

mptcp: pm: ADD_ADDR rtx: fix potential data-race

1 file changed · +8 1
  • net/mptcp/pm.c+8 1 modified
    diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
    index c46b7b0ca71380..24295517711b46 100644
    --- a/net/mptcp/pm.c
    +++ b/net/mptcp/pm.c
    @@ -350,6 +350,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     	if (inet_sk_state_load(sk) == TCP_CLOSE)
     		return;
     
    +	bh_lock_sock(sk);
    +	if (sock_owned_by_user(sk)) {
    +		/* Try again later. */
    +		sk_reset_timer(sk, timer, jiffies + HZ / 20);
    +		goto out;
    +	}
    +
     	if (mptcp_pm_should_add_signal_addr(msk)) {
     		sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
     		goto out;
    @@ -378,6 +385,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     		mptcp_pm_subflow_established(msk);
     
     out:
    +	bh_unlock_sock(sk);
     	__sock_put(sk);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
2ad56e434199

mptcp: pm: ADD_ADDR rtx: fix potential data-race

1 file changed · +8 1
  • net/mptcp/pm.c+8 1 modified
    diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
    index 8852aef5e61879..5cb62ab42cbe1f 100644
    --- a/net/mptcp/pm.c
    +++ b/net/mptcp/pm.c
    @@ -350,6 +350,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     	if (inet_sk_state_load(sk) == TCP_CLOSE)
     		return;
     
    +	bh_lock_sock(sk);
    +	if (sock_owned_by_user(sk)) {
    +		/* Try again later. */
    +		sk_reset_timer(sk, timer, jiffies + HZ / 20);
    +		goto out;
    +	}
    +
     	if (mptcp_pm_should_add_signal_addr(msk)) {
     		sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
     		goto out;
    @@ -378,6 +385,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     		mptcp_pm_subflow_established(msk);
     
     out:
    +	bh_unlock_sock(sk);
     	__sock_put(sk);
     }
     
    -- 
    cgit 1.3-korg
    
    
    
5cd6e0ad79d2

mptcp: pm: ADD_ADDR rtx: fix potential data-race

1 file changed · +8 1
  • net/mptcp/pm.c+8 1 modified
    diff --git a/net/mptcp/pm.c b/net/mptcp/pm.c
    index 5056eb8db24e05..3912128d9b8668 100644
    --- a/net/mptcp/pm.c
    +++ b/net/mptcp/pm.c
    @@ -337,6 +337,13 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     	if (inet_sk_state_load(sk) == TCP_CLOSE)
     		return;
     
    +	bh_lock_sock(sk);
    +	if (sock_owned_by_user(sk)) {
    +		/* Try again later. */
    +		sk_reset_timer(sk, timer, jiffies + HZ / 20);
    +		goto out;
    +	}
    +
     	if (mptcp_pm_should_add_signal_addr(msk)) {
     		sk_reset_timer(sk, timer, jiffies + TCP_RTO_MAX / 8);
     		goto out;
    @@ -365,6 +372,7 @@ static void mptcp_pm_add_timer(struct timer_list *timer)
     		mptcp_pm_subflow_established(msk);
     
     out:
    +	bh_unlock_sock(sk);
     	__sock_put(sk);
     }
     
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"Missing socket lock acquisition in softirq timer callback allows concurrent access to shared socket state."

Attack vector

The `mptcp_pm_add_timer()` callback executes in softirq context and accesses shared socket state without holding the socket lock. A concurrent userspace operation on the same socket (e.g., a setsockopt or close) can race with the timer callback, leading to a data-race on socket fields. An attacker who can trigger ADD_ADDR retransmission timeouts while the socket is in use by userspace can exploit this race condition. The timer fires in softirq context, and without `bh_lock_sock()`, there is no synchronization against a concurrent user holding the socket lock.

Affected code

The vulnerability is in the `mptcp_pm_add_timer()` function, located in `net/mptcp/pm.c` (or `net/mptcp/pm_netlink.c` in backported versions) [patch_id=2898378]. This function is a timer callback that runs in softirq context and accesses the MPTCP socket without proper locking.

What the fix does

The patch adds `bh_lock_sock(sk)` at the start of `mptcp_pm_add_timer()` and `bh_unlock_sock(sk)` at the `out` label [patch_id=2898378]. If the socket is already owned by userspace (`sock_owned_by_user(sk)`), the timer is rescheduled for ~50ms later (`jiffies + HZ / 20`) and the callback returns early, avoiding the race. This pattern mirrors the existing keepalive timer handling in the TCP stack.

Preconditions

  • configThe MPTCP connection must have an ADD_ADDR retransmission timer active (i.e., an ADD_ADDR option was sent and a timeout occurs).
  • inputThe socket must be concurrently in use by a userspace thread holding the socket lock (e.g., via a setsockopt or close syscall).

Generated on May 28, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

5

News mentions

0

No linked articles in our index yet.