MPTCP Linux Development
 help / color / mirror / Atom feed
* [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted
@ 2026-07-14  8:03 luoqing
  2026-07-14  9:25 ` MPTCP CI
                   ` (5 more replies)
  0 siblings, 6 replies; 12+ messages in thread
From: luoqing @ 2026-07-14  8:03 UTC (permalink / raw)
  To: mptcp; +Cc: pabeni, matttbe, davem

From: luoqing <luoqing@kylinos.cn>

When all MPTCP address IDs (1-255) are exhausted, find_next_zero_bit()
returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value overflows when stored
in the u8 field e->addr.id, resulting in ID 0 being stored.

ID 0 has special meaning in MPTCP (it's reserved for the initial connection),
so this overflow can cause confusion and incorrect behavior, including
unintentional ID 0 reuse or address conflicts.

Signed-off-by: luoqing <luoqing@kylinos.cn>
---
 net/mptcp/pm_kernel.c    | 11 ++++++++---
 net/mptcp/pm_userspace.c | 15 +++++++++++----
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
index 424f1a7f9248..a0fc9cabd770 100644
--- a/net/mptcp/pm_kernel.c
+++ b/net/mptcp/pm_kernel.c
@@ -795,9 +795,14 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
 
 	if (!entry->addr.id) {
 find_next:
-		entry->addr.id = find_next_zero_bit(pernet->id_bitmap,
-						    MPTCP_PM_MAX_ADDR_ID + 1,
-						    pernet->next_id);
+		unsigned int id = find_next_zero_bit(pernet->id_bitmap,
+						     MPTCP_PM_MAX_ADDR_ID + 1,
+						     pernet->next_id);
+		if (id > MPTCP_PM_MAX_ADDR_ID) {
+			ret = -ENOSPC;
+			goto out;
+		}
+		entry->addr.id = id;
 		if (!entry->addr.id && pernet->next_id != 1) {
 			pernet->next_id = 1;
 			goto find_next;
diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index d100867e9202..c48fd905f7a0 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -74,10 +74,17 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
 			goto append_err;
 		}
 
-		if (!e->addr.id && needs_id)
-			e->addr.id = find_next_zero_bit(id_bitmap,
-							MPTCP_PM_MAX_ADDR_ID + 1,
-							1);
+		if (!e->addr.id && needs_id) {
+			unsigned int id = find_next_zero_bit(id_bitmap,
+							     MPTCP_PM_MAX_ADDR_ID + 1,
+							     1);
+			if (id > MPTCP_PM_MAX_ADDR_ID) {
+				sock_kfree_s(sk, e, sizeof(*e));
+				ret = -ENOSPC;
+				goto append_err;
+			}
+			e->addr.id = id;
+		}
 		list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
 		msk->pm.local_addr_used++;
 		ret = e->addr.id;
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted
  2026-07-14  8:03 [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted luoqing
@ 2026-07-14  9:25 ` MPTCP CI
  2026-07-14  9:54 ` MPTCP CI
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: MPTCP CI @ 2026-07-14  9:25 UTC (permalink / raw)
  To: luoqing; +Cc: mptcp

Hi luoqing,

Thank you for your modifications, that's great!

But sadly, our CI spotted some issues with it when trying to build it.

You can find more details there:

  https://github.com/multipath-tcp/mptcp_net-next/actions/runs/29320601476

Status: failure
Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/7832e6717726
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1127208

Feel free to reply to this email if you cannot access logs, if you need
some support to fix the error, if this doesn't seem to be caused by your
modifications or if the error is a false positive one.

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted
  2026-07-14  8:03 [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted luoqing
  2026-07-14  9:25 ` MPTCP CI
@ 2026-07-14  9:54 ` MPTCP CI
  2026-07-15  9:10 ` Matthieu Baerts
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: MPTCP CI @ 2026-07-14  9:54 UTC (permalink / raw)
  To: luoqing; +Cc: mptcp

Hi luoqing,

Thank you for your modifications, that's great!

Our CI did some validations and here is its report:

- KVM Validation: normal (except selftest_mptcp_join): Unstable: 1 failed test(s): selftest_pm_netlink ⚠️ 
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Unstable: 1 failed test(s): selftest_pm_netlink ⚠️ 
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/29320601438

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/7832e6717726
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1127208


If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:

    $ cd [kernel source code]
    $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
        --pull always mptcp/mptcp-upstream-virtme-docker:latest \
        auto-normal

For more details:

    https://github.com/multipath-tcp/mptcp-upstream-virtme-docker


Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted
  2026-07-14  8:03 [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted luoqing
  2026-07-14  9:25 ` MPTCP CI
  2026-07-14  9:54 ` MPTCP CI
@ 2026-07-15  9:10 ` Matthieu Baerts
  2026-08-04  2:23 ` [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted luoqing
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 12+ messages in thread
From: Matthieu Baerts @ 2026-07-15  9:10 UTC (permalink / raw)
  To: mptcp

Hi,

Thank you for this patch. Here is a very quick review done in between
tasks.

(-people who were in Cc: no need to add them when sending only to the
MPTCP ML.)

Also, please use a prefix: mptcp-net for fixes, mptcp-next for features.

The CI reported a few issues at build time, please check that.

> When all MPTCP address IDs (1-255) are exhausted, find_next_zero_bit()
> returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value overflows when stored
> in the u8 field e->addr.id, resulting in ID 0 being stored.

Are you sure? With the in-kernel PM? Do you have a reproducer?

> ID 0 has special meaning in MPTCP (it's reserved for the initial connection),
> so this overflow can cause confusion and incorrect behavior, including
> unintentional ID 0 reuse or address conflicts.

A fix should have a Fixes tag, please add one.

Also, if you were assisted by a tool, please add the Assisted-by tag.

> Signed-off-by: luoqing <luoqing@kylinos.cn>

For "legal" reasons, you are supposed to put your full name. Having only
one "word" for your full name, without capital letters looks wrong, no?

>
> diff --git a/net/mptcp/pm_kernel.c b/net/mptcp/pm_kernel.c
> index 331f6fa99014..1bd81c94b971 100644
> --- a/net/mptcp/pm_kernel.c
> +++ b/net/mptcp/pm_kernel.c
> @@ -795,9 +795,14 @@ static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
>
>  	if (!entry->addr.id) {
>  find_next:
> -		entry->addr.id = find_next_zero_bit(pernet->id_bitmap,
> -						    MPTCP_PM_MAX_ADDR_ID + 1,
> -						    pernet->next_id);
> +		unsigned int id = find_next_zero_bit(pernet->id_bitmap,
> +						     MPTCP_PM_MAX_ADDR_ID + 1,
> +						     pernet->next_id);
> +		if (id > MPTCP_PM_MAX_ADDR_ID) {
> +			ret = -ENOSPC;
> +			goto out;
> +		}
> +		entry->addr.id = id;
>  		if (!entry->addr.id && pernet->next_id != 1) {

The overflow is a normal case: find_next_zero_bit() will find the next
zero bit from next_id. If there it didn't find any, this block here
restart find_next_zero_bit() but from the beginning.

>  			pernet->next_id = 1;
>  			goto find_next;
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index ad6ba658e5a5..0a1e835ae049 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -74,10 +74,17 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
>  			goto append_err;
>  		}
>
> -		if (!e->addr.id && needs_id)
> -			e->addr.id = find_next_zero_bit(id_bitmap,

Do you need to change this line? In case of error, 'e' is dropped.

> -							MPTCP_PM_MAX_ADDR_ID + 1,
> -							1);
> +		if (!e->addr.id && needs_id) {
> +			unsigned int id = find_next_zero_bit(id_bitmap,
> +							     MPTCP_PM_MAX_ADDR_ID + 1,
> +							     1);
> +			if (id > MPTCP_PM_MAX_ADDR_ID) {
> +				sock_kfree_s(sk, e, sizeof(*e));
> +				ret = -ENOSPC;
> +				goto append_err;
> +			}
> +			e->addr.id = id;

I didn't check the code, but here, it looks like such check is needed.
But please, provide a test reproducing the issue, e.g. by adding a test
in userspace_pm.sh. (Be careful that such test should also run on older
kernels where the limits are lower, see what is done in pm_netlink.sh)

-- 
Matthieu Baerts (NGI0) <matttbe@kernel.org>

^ permalink raw reply	[flat|nested] 12+ messages in thread

* [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted
  2026-07-14  8:03 [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted luoqing
                   ` (2 preceding siblings ...)
  2026-07-15  9:10 ` Matthieu Baerts
@ 2026-08-04  2:23 ` luoqing
  2026-08-04  2:23   ` [PATCH MPTCH-next] selftests: add test for userspace PM address ID overflow luoqing
                     ` (2 more replies)
  2026-08-06 20:17 ` [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted kernel test robot
  2026-08-06 22:04 ` kernel test robot
  5 siblings, 3 replies; 12+ messages in thread
From: luoqing @ 2026-08-04  2:23 UTC (permalink / raw)
  To: l1138897701; +Cc: davem, matttbe, mptcp, pabeni

From: Qing Luo <luoqing@kylinos.cn>

When all MPTCP address IDs (1-255) are exhausted in the userspace PM,
find_next_zero_bit() returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value
overflows when stored in the u8 field e->addr.id, resulting in ID 0
being stored and the entry being incorrectly added to the list.

ID 0 is reserved for the initial connection in MPTCP, so this overflow
can cause address conflicts.

Note: the in-kernel PM already has an 'endpoints == MPTCP_PM_MAX_ADDR_ID'
check in mptcp_pm_nl_append_new_local_addr() that returns -ERANGE before
reaching find_next_zero_bit(), preventing this overflow. So this fix only
addresses the userspace PM path.

Store the find_next_zero_bit() result in a temporary unsigned int, check
against MPTCP_PM_MAX_ADDR_ID, and return -ENOSPC if all IDs are truly
exhausted. Properly free the allocated entry with sock_kfree_s() on error.

Also modify the CSF (subflow create) handler to pass !entry.addr.id as
the needs_id parameter. When no local ID is provided by user-space
(entry.addr.id == 0), this triggers auto-allocation instead of silently
using the reserved ID 0.

Fixes: 4638de5aefe5 ("mptcp: handle local addrs announced by userspace PMs")
Assisted-by: LLM # review
Signed-off-by: Qing Luo <luoqing@kylinos.cn>
---
 net/mptcp/pm_userspace.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
index 945aa5afc2dd..ada7d6cef625 100644
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -74,10 +74,17 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
 			goto append_err;
 		}
 
-		if (!e->addr.id && needs_id)
-			e->addr.id = find_next_zero_bit(id_bitmap,
-							MPTCP_PM_MAX_ADDR_ID + 1,
-							1);
+		if (!e->addr.id && needs_id) {
+			unsigned int id = find_next_zero_bit(id_bitmap,
+							     MPTCP_PM_MAX_ADDR_ID + 1,
+							     1);
+			if (id > MPTCP_PM_MAX_ADDR_ID) {
+				sock_kfree_s(sk, e, sizeof(*e));
+				ret = -ENOSPC;
+				goto append_err;
+			}
+			e->addr.id = id;
+		}
 		list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
 		msk->pm.local_addr_used++;
 		ret = e->addr.id;
@@ -400,7 +407,8 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
 		goto create_err;
 	}
 
-	err = mptcp_userspace_pm_append_new_local_addr(msk, &entry, false);
+	err = mptcp_userspace_pm_append_new_local_addr(msk, &entry,
+						       !entry.addr.id);
 	if (err < 0) {
 		NL_SET_ERR_MSG_ATTR(info->extack, laddr,
 				    "did not match address and id");
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* [PATCH MPTCH-next] selftests: add test for userspace PM address ID overflow
  2026-08-04  2:23 ` [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted luoqing
@ 2026-08-04  2:23   ` luoqing
  2026-08-04  3:29     ` MPTCP CI
  2026-08-04 18:37     ` Matthieu Baerts
  2026-08-04  3:34   ` [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted MPTCP CI
  2026-08-04 18:22   ` Matthieu Baerts
  2 siblings, 2 replies; 12+ messages in thread
From: luoqing @ 2026-08-04  2:23 UTC (permalink / raw)
  To: l1138897701; +Cc: davem, matttbe, mptcp, pabeni

From: Qing Luo <luoqing@kylinos.cn>

Add a test that verifies the userspace PM correctly returns an error
when all address IDs (1-255) are exhausted, instead of overflowing.

The test first announces 255 unique addresses (IDs 1-255) to fill the
ID bitmap. It then attempts to create a subflow (CSF) without specifying
a local ID, which triggers auto-allocation via
mptcp_userspace_pm_get_local_id(). With all IDs in use, the allocation
should fail with -ENOSPC.

Also modify pm_nl_ctl to make the 'lid' parameter optional for the CSF
command. When omitted, the kernel auto-allocates a local ID.

MPTCP_PM_MAX_ADDR_ID has been 255 since the userspace PM was introduced,
so no version-dependent limit adjustment is needed (unlike pm_netlink.sh).

Assisted-by: LLM # code
Signed-off-by: Qing Luo <luoqing@kylinos.cn>
---
 tools/testing/selftests/net/mptcp/pm_nl_ctl.c |  8 +--
 .../selftests/net/mptcp/userspace_pm.sh       | 63 +++++++++++++++++++
 2 files changed, 67 insertions(+), 4 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
index 78180da1efcc..a9dd650805a9 100644
--- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
+++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
@@ -32,7 +32,7 @@ static void syntax(char *argv[])
 	fprintf(stderr, "\tadd [flags signal|subflow|backup|fullmesh] [id <nr>] [dev <name>] <ip>\n");
 	fprintf(stderr, "\tann <local-ip> id <local-id> token <token> [port <local-port>] [dev <name>]\n");
 	fprintf(stderr, "\trem id <local-id> token <token>\n");
-	fprintf(stderr, "\tcsf lip <local-ip> lid <local-id> rip <remote-ip> rport <remote-port> token <token>\n");
+	fprintf(stderr, "\tcsf lip <local-ip> [lid <local-id>] rip <remote-ip> rport <remote-port> token <token>\n");
 	fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n");
 	fprintf(stderr, "\tdel <id> [<ip>]\n");
 	fprintf(stderr, "\tget <id>\n");
@@ -481,7 +481,7 @@ int csf(int fd, int pm_family, int argc, char *argv[])
 	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_SUBFLOW_CREATE,
 			    MPTCP_PM_VER);
 
-	if (argc < 12)
+	if (argc < 10)
 		syntax(argv);
 
 	/* Params recorded in this order:
@@ -557,9 +557,9 @@ int csf(int fd, int pm_family, int argc, char *argv[])
 			off += NLMSG_ALIGN(rta->rta_len);
 		}
 
-		if (arg == 0) {
+		if (arg == 0 && params[1]) {
 			/* id */
-			id = atoi(params[arg + 1]);
+			id = atoi(params[1]);
 			rta = (void *)(data + off);
 			rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
 			rta->rta_len = RTA_LENGTH(1);
diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh
index 30a809752d1b..45b040a8c0e5 100755
--- a/tools/testing/selftests/net/mptcp/userspace_pm.sh
+++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh
@@ -847,6 +847,68 @@ test_subflows_v4_v6_mix()
 	sleep 0.5
 }
 
+test_addr_id_overflow()
+{
+	print_title "Address ID overflow tests"
+
+	local i announced=0
+
+	:>"$server_evts"
+
+	# Clear leftover addresses from previous tests
+	for i in $(seq 0 255); do
+		ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id "$i" > /dev/null 2>&1
+	done
+
+	# Announce 255 addresses (IDs 1-255) to exhaust all available IDs
+	for i in $(seq 1 255); do
+		if ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.3."${i}" token "$client4_token" id \
+			"$i" dev ns2eth1 > /dev/null 2>&1; then
+			announced=$((announced + 1))
+		fi
+	done
+
+	print_test "ADD_ADDR with all IDs 1-255 exhausted"
+	sleep 1
+	if [ -s "$server_evts" ]; then
+		test_pass
+	else
+		test_fail "No events generated"
+		return
+	fi
+
+	# Start listener to ensure subflow creation doesn't fail on connectivity
+	ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.1.1 "$app4_port" >/dev/null 2>&1 &
+	local listener_pid=$!
+	sleep 0.5
+
+	# Try to create a subflow without specifying a local ID.
+	# With all IDs exhausted, this should fail with -ENOSPC.
+	print_test "CSF without local ID after all IDs exhausted - expect failure"
+	local out
+	if out=$(ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.1.2 \
+		rip 10.0.1.1 rport "$app4_port" token "$client4_token" 2>&1); then
+		test_fail "Expected failure but CSF succeeded"
+	else
+		# pm_nl_ctl prints the kernel error as "netlink error -28 (No space
+		# left on device)" for -ENOSPC. Match either form.
+		if echo "$out" | grep -qE "netlink error -?28|No space left on device"; then
+			test_pass
+		else
+			test_fail "CSF failed, but not with the expected ENOSPC: ${out}"
+		fi
+	fi
+
+	# Delete the listener from the server ns, if one was created
+	mptcp_lib_kill_wait $listener_pid
+
+	# Cleanup: remove all announced addresses
+	for i in $(seq 1 255); do
+		ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id "$i" > /dev/null 2>&1
+	done
+	sleep 1
+}
+
 test_prio()
 {
 	print_title "Prio tests"
@@ -940,6 +1002,7 @@ test_subflows
 test_subflows_v4_v6_mix
 test_prio
 test_listener
+test_addr_id_overflow
 
 mptcp_lib_result_print_all_tap
 exit ${ret}
-- 
2.25.1


^ permalink raw reply related	[flat|nested] 12+ messages in thread

* Re: [PATCH MPTCH-next] selftests: add test for userspace PM address ID overflow
  2026-08-04  2:23   ` [PATCH MPTCH-next] selftests: add test for userspace PM address ID overflow luoqing
@ 2026-08-04  3:29     ` MPTCP CI
  2026-08-04 18:37     ` Matthieu Baerts
  1 sibling, 0 replies; 12+ messages in thread
From: MPTCP CI @ 2026-08-04  3:29 UTC (permalink / raw)
  To: Qing Luo; +Cc: mptcp

Hi Qing,

Thank you for your modifications, that's great!

Our CI did some validations and here is its report:

- KVM Validation: normal (except selftest_mptcp_join): Unstable: 1 failed test(s): selftest_userspace_pm ⚠️ 
- KVM Validation: normal (only selftest_mptcp_join): Success! ✅
- KVM Validation: debug (except selftest_mptcp_join): Unstable: 1 failed test(s): selftest_userspace_pm ⚠️ 
- KVM Validation: debug (only selftest_mptcp_join): Success! ✅
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/30872689423

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/dc56ec09ff01
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1139751


If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:

    $ cd [kernel source code]
    $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
        --pull always mptcp/mptcp-upstream-virtme-docker:latest \
        auto-normal

For more details:

    https://github.com/multipath-tcp/mptcp-upstream-virtme-docker


Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted
  2026-08-04  2:23 ` [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted luoqing
  2026-08-04  2:23   ` [PATCH MPTCH-next] selftests: add test for userspace PM address ID overflow luoqing
@ 2026-08-04  3:34   ` MPTCP CI
  2026-08-04 18:22   ` Matthieu Baerts
  2 siblings, 0 replies; 12+ messages in thread
From: MPTCP CI @ 2026-08-04  3:34 UTC (permalink / raw)
  To: Qing Luo; +Cc: mptcp

Hi Qing,

Thank you for your modifications, that's great!

Our CI did some validations and here is its report:

- KVM Validation: normal (except selftest_mptcp_join): Success! ✅
- KVM Validation: normal (only selftest_mptcp_join): Unstable: 1 failed test(s): selftest_mptcp_join ⚠️ 
- KVM Validation: debug (except selftest_mptcp_join): Success! ✅
- KVM Validation: debug (only selftest_mptcp_join): Unstable: 1 failed test(s): selftest_mptcp_join ⚠️ 
- KVM Validation: btf-normal (only bpftest_all): Success! ✅
- KVM Validation: btf-debug (only bpftest_all): Success! ✅
- Task: https://github.com/multipath-tcp/mptcp_net-next/actions/runs/30872730143

Initiator: Patchew Applier
Commits: https://github.com/multipath-tcp/mptcp_net-next/commits/e6cb13c9a93b
Patchwork: https://patchwork.kernel.org/project/mptcp/list/?series=1139752


If there are some issues, you can reproduce them using the same environment as
the one used by the CI thanks to a docker image, e.g.:

    $ cd [kernel source code]
    $ docker run -v "${PWD}:${PWD}:rw" -w "${PWD}" --privileged --rm -it \
        --pull always mptcp/mptcp-upstream-virtme-docker:latest \
        auto-normal

For more details:

    https://github.com/multipath-tcp/mptcp-upstream-virtme-docker


Please note that despite all the efforts that have been already done to have a
stable tests suite when executed on a public CI like here, it is possible some
reported issues are not due to your modifications. Still, do not hesitate to
help us improve that ;-)

Cheers,
MPTCP GH Action bot
Bot operated by Matthieu Baerts (NGI0 Core)

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted
  2026-08-04  2:23 ` [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted luoqing
  2026-08-04  2:23   ` [PATCH MPTCH-next] selftests: add test for userspace PM address ID overflow luoqing
  2026-08-04  3:34   ` [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted MPTCP CI
@ 2026-08-04 18:22   ` Matthieu Baerts
  2 siblings, 0 replies; 12+ messages in thread
From: Matthieu Baerts @ 2026-08-04 18:22 UTC (permalink / raw)
  To: luoqing; +Cc: mptcp

Hi luoqing,

(-cc David/Paolo)

Thank you for the patch.

Please only Cc the MPTCP mailing list.

Also, please send new versions in a new email thread, not as a reply to
a previous one.

One last thing: here, you can send the fix and the selftest as part of
the same series, not as separated patches, so the CI will validate the
new selftest with the fix. It is fine to have patches for -net and -next
in the same series. Also, please use 'mptcp-ne(x)t', no capital letters.

On 04/08/2026 04:23, luoqing wrote:
> From: Qing Luo <luoqing@kylinos.cn>
> 
> When all MPTCP address IDs (1-255) are exhausted in the userspace PM,
> find_next_zero_bit() returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value
> overflows when stored in the u8 field e->addr.id, resulting in ID 0
> being stored and the entry being incorrectly added to the list.
> 
> ID 0 is reserved for the initial connection in MPTCP, so this overflow
> can cause address conflicts.
> 
> Note: the in-kernel PM already has an 'endpoints == MPTCP_PM_MAX_ADDR_ID'
> check in mptcp_pm_nl_append_new_local_addr() that returns -ERANGE before
> reaching find_next_zero_bit(), preventing this overflow. So this fix only
> addresses the userspace PM path.
> 
> Store the find_next_zero_bit() result in a temporary unsigned int, check
> against MPTCP_PM_MAX_ADDR_ID, and return -ENOSPC if all IDs are truly
> exhausted. Properly free the allocated entry with sock_kfree_s() on error.
> 
> Also modify the CSF (subflow create) handler to pass !entry.addr.id as
> the needs_id parameter. When no local ID is provided by user-space
> (entry.addr.id == 0), this triggers auto-allocation instead of silently
> using the reserved ID 0.
> 
> Fixes: 4638de5aefe5 ("mptcp: handle local addrs announced by userspace PMs")
> Assisted-by: LLM # review
> Signed-off-by: Qing Luo <luoqing@kylinos.cn>
> ---
>  net/mptcp/pm_userspace.c | 18 +++++++++++++-----
>  1 file changed, 13 insertions(+), 5 deletions(-)
> 
> diff --git a/net/mptcp/pm_userspace.c b/net/mptcp/pm_userspace.c
> index 945aa5afc2dd..ada7d6cef625 100644
> --- a/net/mptcp/pm_userspace.c
> +++ b/net/mptcp/pm_userspace.c
> @@ -74,10 +74,17 @@ static int mptcp_userspace_pm_append_new_local_addr(struct mptcp_sock *msk,
>  			goto append_err;
>  		}
>  
> -		if (!e->addr.id && needs_id)
> -			e->addr.id = find_next_zero_bit(id_bitmap,
> -							MPTCP_PM_MAX_ADDR_ID + 1,
> -							1);
> +		if (!e->addr.id && needs_id) {
> +			unsigned int id = find_next_zero_bit(id_bitmap,
> +							     MPTCP_PM_MAX_ADDR_ID + 1,
> +							     1);
> +			if (id > MPTCP_PM_MAX_ADDR_ID) {
> +				sock_kfree_s(sk, e, sizeof(*e));
> +				ret = -ENOSPC;
> +				goto append_err;
> +			}
> +			e->addr.id = id;
> +		}
>  		list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
>  		msk->pm.local_addr_used++;
>  		ret = e->addr.id;
> @@ -400,7 +407,8 @@ int mptcp_pm_nl_subflow_create_doit(struct sk_buff *skb, struct genl_info *info)
>  		goto create_err;
>  	}
>  
> -	err = mptcp_userspace_pm_append_new_local_addr(msk, &entry, false);
> +	err = mptcp_userspace_pm_append_new_local_addr(msk, &entry,
> +						       !entry.addr.id);

I don't think you can do that: it is valid to give an ID set to 0. But
it is different to give no ID.

I don't think this modification here should be part of this patch: it is
different from the overflow case you are trying to fix. It could be in
another patch, but that's changing the behaviour, and that's not a fix I
think.

Also, see my series:


https://lore.kernel.org/20260727-mptcp-pm-userspace-id0-case-v1-0-9877f02a9bae@kernel.org

*Maybe*, for -next, we could check if the ID was not set via Netlink
(and not set to 0), and pick an ID for it. *But*, it might not be a good
idea: the userspace daemon will not know the ID that has been picked,
and will need to get it via another request. That doesn't sound like a
good idea, no?

>  	if (err < 0) {
>  		NL_SET_ERR_MSG_ATTR(info->extack, laddr,
>  				    "did not match address and id");

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH MPTCH-next] selftests: add test for userspace PM address ID overflow
  2026-08-04  2:23   ` [PATCH MPTCH-next] selftests: add test for userspace PM address ID overflow luoqing
  2026-08-04  3:29     ` MPTCP CI
@ 2026-08-04 18:37     ` Matthieu Baerts
  1 sibling, 0 replies; 12+ messages in thread
From: Matthieu Baerts @ 2026-08-04 18:37 UTC (permalink / raw)
  To: luoqing; +Cc: mptcp

Hi luoqing,

On 04/08/2026 04:23, luoqing wrote:
> From: Qing Luo <luoqing@kylinos.cn>
> 
> Add a test that verifies the userspace PM correctly returns an error
> when all address IDs (1-255) are exhausted, instead of overflowing.
> 
> The test first announces 255 unique addresses (IDs 1-255) to fill the
> ID bitmap. It then attempts to create a subflow (CSF) without specifying
> a local ID, which triggers auto-allocation via
> mptcp_userspace_pm_get_local_id(). With all IDs in use, the allocation
> should fail with -ENOSPC.
> 
> Also modify pm_nl_ctl to make the 'lid' parameter optional for the CSF
> command. When omitted, the kernel auto-allocates a local ID.

Same as for the other patch: should be in a different patch, but can
certainly be dropped.

> MPTCP_PM_MAX_ADDR_ID has been 255 since the userspace PM was introduced,
> so no version-dependent limit adjustment is needed (unlike pm_netlink.sh).
> 
> Assisted-by: LLM # code
> Signed-off-by: Qing Luo <luoqing@kylinos.cn>
> ---
>  tools/testing/selftests/net/mptcp/pm_nl_ctl.c |  8 +--
>  .../selftests/net/mptcp/userspace_pm.sh       | 63 +++++++++++++++++++
>  2 files changed, 67 insertions(+), 4 deletions(-)
> 
> diff --git a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
> index 78180da1efcc..a9dd650805a9 100644
> --- a/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
> +++ b/tools/testing/selftests/net/mptcp/pm_nl_ctl.c
> @@ -32,7 +32,7 @@ static void syntax(char *argv[])
>  	fprintf(stderr, "\tadd [flags signal|subflow|backup|fullmesh] [id <nr>] [dev <name>] <ip>\n");
>  	fprintf(stderr, "\tann <local-ip> id <local-id> token <token> [port <local-port>] [dev <name>]\n");
>  	fprintf(stderr, "\trem id <local-id> token <token>\n");
> -	fprintf(stderr, "\tcsf lip <local-ip> lid <local-id> rip <remote-ip> rport <remote-port> token <token>\n");
> +	fprintf(stderr, "\tcsf lip <local-ip> [lid <local-id>] rip <remote-ip> rport <remote-port> token <token>\n");
>  	fprintf(stderr, "\tdsf lip <local-ip> lport <local-port> rip <remote-ip> rport <remote-port> token <token>\n");
>  	fprintf(stderr, "\tdel <id> [<ip>]\n");
>  	fprintf(stderr, "\tget <id>\n");
> @@ -481,7 +481,7 @@ int csf(int fd, int pm_family, int argc, char *argv[])
>  	off = init_genl_req(data, pm_family, MPTCP_PM_CMD_SUBFLOW_CREATE,
>  			    MPTCP_PM_VER);
>  
> -	if (argc < 12)
> +	if (argc < 10)
>  		syntax(argv);
>  
>  	/* Params recorded in this order:
> @@ -557,9 +557,9 @@ int csf(int fd, int pm_family, int argc, char *argv[])
>  			off += NLMSG_ALIGN(rta->rta_len);
>  		}
>  
> -		if (arg == 0) {
> +		if (arg == 0 && params[1]) {
>  			/* id */
> -			id = atoi(params[arg + 1]);
> +			id = atoi(params[1]);
>  			rta = (void *)(data + off);
>  			rta->rta_type = MPTCP_PM_ADDR_ATTR_ID;
>  			rta->rta_len = RTA_LENGTH(1);
> diff --git a/tools/testing/selftests/net/mptcp/userspace_pm.sh b/tools/testing/selftests/net/mptcp/userspace_pm.sh
> index 30a809752d1b..45b040a8c0e5 100755
> --- a/tools/testing/selftests/net/mptcp/userspace_pm.sh
> +++ b/tools/testing/selftests/net/mptcp/userspace_pm.sh
> @@ -847,6 +847,68 @@ test_subflows_v4_v6_mix()
>  	sleep 0.5
>  }
>  
> +test_addr_id_overflow()
> +{
> +	print_title "Address ID overflow tests"
> +
> +	local i announced=0
> +
> +	:>"$server_evts"
> +
> +	# Clear leftover addresses from previous tests
> +	for i in $(seq 0 255); do
> +		ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id "$i" > /dev/null 2>&1
> +	done

Is this really needed?

> +
> +	# Announce 255 addresses (IDs 1-255) to exhaust all available IDs
> +	for i in $(seq 1 255); do
> +		if ip netns exec "$ns2" ./pm_nl_ctl ann 10.0.3."${i}" token "$client4_token" id \
> +			"$i" dev ns2eth1 > /dev/null 2>&1; then

Why hiding errors? (OK to hide if it is just to use all bits, then try
one extra to check the error)

> +			announced=$((announced + 1))

Set but not used?

> +		fi
> +	done

Mmh, all of this is very slow: 19 seconds on the CI with a "normal"
kconfig, 52 seconds with a "debug" one...

That's a lot... Any ideas on how to reduce this time? (maybe not possible?)

> +
> +	print_test "ADD_ADDR with all IDs 1-255 exhausted"
> +	sleep 1

Why this "sleep 1"?

> +	if [ -s "$server_evts" ]; then
> +		test_pass
> +	else
> +		test_fail "No events generated"
> +		return
> +	fi
> +
> +	# Start listener to ensure subflow creation doesn't fail on connectivity

Really needed?

> +	ip netns exec "$ns1" ./pm_nl_ctl listen 10.0.1.1 "$app4_port" >/dev/null 2>&1 &
> +	local listener_pid=$!
> +	sleep 0.5
> +
> +	# Try to create a subflow without specifying a local ID.
> +	# With all IDs exhausted, this should fail with -ENOSPC.
> +	print_test "CSF without local ID after all IDs exhausted - expect failure"
> +	local out
> +	if out=$(ip netns exec "$ns2" ./pm_nl_ctl csf lip 10.0.1.2 \
> +		rip 10.0.1.1 rport "$app4_port" token "$client4_token" 2>&1); then

I guess you cannot have an overflow with csf, because an ID is required.

> +		test_fail "Expected failure but CSF succeeded"
> +	else
> +		# pm_nl_ctl prints the kernel error as "netlink error -28 (No space
> +		# left on device)" for -ENOSPC. Match either form.

Really needed? The pm_nl_ctl should fail.

> +		if echo "$out" | grep -qE "netlink error -?28|No space left on device"; then
> +			test_pass
> +		else
> +			test_fail "CSF failed, but not with the expected ENOSPC: ${out}"
> +		fi
> +	fi
> +
> +	# Delete the listener from the server ns, if one was created
> +	mptcp_lib_kill_wait $listener_pid
> +
> +	# Cleanup: remove all announced addresses
> +	for i in $(seq 1 255); do
> +		ip netns exec "$ns2" ./pm_nl_ctl rem token "$client4_token" id "$i" > /dev/null 2>&1
> +	done

Maybe not needed?

> +	sleep 1

Clearly not needed.

> +}
> +
>  test_prio()
>  {
>  	print_title "Prio tests"
> @@ -940,6 +1002,7 @@ test_subflows
>  test_subflows_v4_v6_mix
>  test_prio
>  test_listener
> +test_addr_id_overflow
>  
>  mptcp_lib_result_print_all_tap
>  exit ${ret}

Cheers,
Matt
-- 
Sponsored by the NGI0 Core fund.


^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted
  2026-07-14  8:03 [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted luoqing
                   ` (3 preceding siblings ...)
  2026-08-04  2:23 ` [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted luoqing
@ 2026-08-06 20:17 ` kernel test robot
  2026-08-06 22:04 ` kernel test robot
  5 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2026-08-06 20:17 UTC (permalink / raw)
  To: luoqing, mptcp; +Cc: oe-kbuild-all, pabeni, matttbe, davem

Hi luoqing,

kernel test robot noticed the following build errors:

[auto build test ERROR on mptcp/export]
[also build test ERROR on mptcp/export-net linus/master v7.2-rc6 next-20260806]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/luoqing/mptcp-pm-Fix-address-ID-overflow-when-all-IDs-are-exhausted/20260806-155815
base:   https://github.com/multipath-tcp/mptcp_net-next.git export
patch link:    https://lore.kernel.org/r/20260714080356.805839-1-l1138897701%40163.com
patch subject: [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted
config: nios2-randconfig-001-20260807 (https://download.01.org/0day-ci/archive/20260807/202608070408.cjzYB3m6-lkp@intel.com/config)
compiler: nios2-linux-gcc (GCC) 8.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260807/202608070408.cjzYB3m6-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608070408.cjzYB3m6-lkp@intel.com/

All errors (new ones prefixed by >>):

   net/mptcp/pm_kernel.c: In function 'mptcp_pm_nl_append_new_local_addr':
>> net/mptcp/pm_kernel.c:798:3: error: a label can only be part of a statement and a declaration is not a statement
      unsigned int id = find_next_zero_bit(pernet->id_bitmap,
      ^~~~~~~~


vim +798 net/mptcp/pm_kernel.c

   734	
   735	static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
   736						     struct mptcp_pm_addr_entry *entry,
   737						     bool replace)
   738	{
   739		struct mptcp_pm_addr_entry *cur, *del_entry = NULL;
   740		int ret = -EINVAL;
   741		u8 addr_max;
   742	
   743		spin_lock_bh(&pernet->lock);
   744		/* to keep the code simple, don't do IDR-like allocation for address ID,
   745		 * just bail when we exceed limits
   746		 */
   747		if (pernet->next_id == MPTCP_PM_MAX_ADDR_ID)
   748			pernet->next_id = 1;
   749		if (pernet->endpoints == MPTCP_PM_MAX_ADDR_ID) {
   750			ret = -ERANGE;
   751			goto out;
   752		}
   753		if (test_bit(entry->addr.id, pernet->id_bitmap)) {
   754			ret = -EBUSY;
   755			goto out;
   756		}
   757	
   758		/* do not insert duplicate address, differentiate on port only
   759		 * singled addresses
   760		 */
   761		if (!address_use_port(entry))
   762			entry->addr.port = 0;
   763		list_for_each_entry(cur, &pernet->endp_list, list) {
   764			if (mptcp_addresses_equal(&cur->addr, &entry->addr,
   765						  cur->addr.port || entry->addr.port)) {
   766				/* allow replacing the exiting endpoint only if such
   767				 * endpoint is an implicit one and the user-space
   768				 * did not provide an endpoint id
   769				 */
   770				if (!(cur->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT)) {
   771					ret = -EEXIST;
   772					goto out;
   773				}
   774				if (entry->addr.id)
   775					goto out;
   776	
   777				/* allow callers that only need to look up the local
   778				 * addr's id to skip replacement. This allows them to
   779				 * avoid calling synchronize_rcu in the packet recv
   780				 * path.
   781				 */
   782				if (!replace) {
   783					kfree(entry);
   784					ret = cur->addr.id;
   785					goto out;
   786				}
   787	
   788				pernet->endpoints--;
   789				entry->addr.id = cur->addr.id;
   790				list_del_rcu(&cur->list);
   791				del_entry = cur;
   792				break;
   793			}
   794		}
   795	
   796		if (!entry->addr.id) {
   797	find_next:
 > 798			unsigned int id = find_next_zero_bit(pernet->id_bitmap,
   799							     MPTCP_PM_MAX_ADDR_ID + 1,
   800							     pernet->next_id);
   801			if (id > MPTCP_PM_MAX_ADDR_ID) {
   802				ret = -ENOSPC;
   803				goto out;
   804			}
   805			entry->addr.id = id;
   806			if (!entry->addr.id && pernet->next_id != 1) {
   807				pernet->next_id = 1;
   808				goto find_next;
   809			}
   810		}
   811	
   812		if (!entry->addr.id)
   813			goto out;
   814	
   815		__set_bit(entry->addr.id, pernet->id_bitmap);
   816		if (entry->addr.id > pernet->next_id)
   817			pernet->next_id = entry->addr.id;
   818	
   819		if (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
   820			addr_max = pernet->endp_signal_max;
   821			WRITE_ONCE(pernet->endp_signal_max, addr_max + 1);
   822		}
   823		if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
   824			addr_max = pernet->endp_subflow_max;
   825			WRITE_ONCE(pernet->endp_subflow_max, addr_max + 1);
   826		}
   827		if (entry->flags & MPTCP_PM_ADDR_FLAG_LAMINAR) {
   828			addr_max = pernet->endp_laminar_max;
   829			WRITE_ONCE(pernet->endp_laminar_max, addr_max + 1);
   830		}
   831		if (entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) {
   832			addr_max = pernet->endp_fullmesh_max;
   833			WRITE_ONCE(pernet->endp_fullmesh_max, addr_max + 1);
   834		}
   835	
   836		pernet->endpoints++;
   837		if (!entry->addr.port)
   838			list_add_tail_rcu(&entry->list, &pernet->endp_list);
   839		else
   840			list_add_rcu(&entry->list, &pernet->endp_list);
   841		ret = entry->addr.id;
   842	
   843	out:
   844		spin_unlock_bh(&pernet->lock);
   845	
   846		/* just replaced an existing entry, free it */
   847		if (del_entry) {
   848			synchronize_rcu();
   849			__mptcp_pm_release_addr_entry(del_entry);
   850		}
   851		return ret;
   852	}
   853	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 12+ messages in thread

* Re: [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted
  2026-07-14  8:03 [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted luoqing
                   ` (4 preceding siblings ...)
  2026-08-06 20:17 ` [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted kernel test robot
@ 2026-08-06 22:04 ` kernel test robot
  5 siblings, 0 replies; 12+ messages in thread
From: kernel test robot @ 2026-08-06 22:04 UTC (permalink / raw)
  To: luoqing, mptcp; +Cc: llvm, oe-kbuild-all, pabeni, matttbe, davem

Hi luoqing,

kernel test robot noticed the following build warnings:

[auto build test WARNING on mptcp/export]
[also build test WARNING on mptcp/export-net linus/master v7.2-rc6 next-20260806]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/luoqing/mptcp-pm-Fix-address-ID-overflow-when-all-IDs-are-exhausted/20260806-155815
base:   https://github.com/multipath-tcp/mptcp_net-next.git export
patch link:    https://lore.kernel.org/r/20260714080356.805839-1-l1138897701%40163.com
patch subject: [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted
config: um-randconfig-002-20260807 (https://download.01.org/0day-ci/archive/20260807/202608070615.6V9gQGfK-lkp@intel.com/config)
compiler: clang version 24.0.0git (https://github.com/llvm/llvm-project 12df34b8469b8095359de8c249cb1b2753fadeea)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20260807/202608070615.6V9gQGfK-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202608070615.6V9gQGfK-lkp@intel.com/

All warnings (new ones prefixed by >>):

   In file included from net/mptcp/pm_kernel.c:9:
   In file included from include/net/netns/generic.h:11:
   In file included from include/net/net_namespace.h:44:
   In file included from include/linux/skbuff.h:17:
   In file included from include/linux/bvec.h:10:
   In file included from include/linux/highmem.h:12:
   In file included from include/linux/hardirq.h:11:
   In file included from arch/um/include/asm/hardirq.h:24:
   In file included from include/linux/irq.h:20:
   In file included from include/linux/io.h:12:
   In file included from arch/um/include/asm/io.h:24:
   include/asm-generic/io.h:1209:55: warning: performing pointer arithmetic on a null pointer has undefined behavior [-Wnull-pointer-arithmetic]
    1209 |         return (port > MMIO_UPPER_LIMIT) ? NULL : PCI_IOBASE + port;
         |                                                   ~~~~~~~~~~ ^
>> net/mptcp/pm_kernel.c:798:3: warning: label followed by a declaration is a C23 extension [-Wc23-extensions]
     798 |                 unsigned int id = find_next_zero_bit(pernet->id_bitmap,
         |                 ^
   2 warnings generated.


vim +798 net/mptcp/pm_kernel.c

   734	
   735	static int mptcp_pm_nl_append_new_local_addr(struct pm_nl_pernet *pernet,
   736						     struct mptcp_pm_addr_entry *entry,
   737						     bool replace)
   738	{
   739		struct mptcp_pm_addr_entry *cur, *del_entry = NULL;
   740		int ret = -EINVAL;
   741		u8 addr_max;
   742	
   743		spin_lock_bh(&pernet->lock);
   744		/* to keep the code simple, don't do IDR-like allocation for address ID,
   745		 * just bail when we exceed limits
   746		 */
   747		if (pernet->next_id == MPTCP_PM_MAX_ADDR_ID)
   748			pernet->next_id = 1;
   749		if (pernet->endpoints == MPTCP_PM_MAX_ADDR_ID) {
   750			ret = -ERANGE;
   751			goto out;
   752		}
   753		if (test_bit(entry->addr.id, pernet->id_bitmap)) {
   754			ret = -EBUSY;
   755			goto out;
   756		}
   757	
   758		/* do not insert duplicate address, differentiate on port only
   759		 * singled addresses
   760		 */
   761		if (!address_use_port(entry))
   762			entry->addr.port = 0;
   763		list_for_each_entry(cur, &pernet->endp_list, list) {
   764			if (mptcp_addresses_equal(&cur->addr, &entry->addr,
   765						  cur->addr.port || entry->addr.port)) {
   766				/* allow replacing the exiting endpoint only if such
   767				 * endpoint is an implicit one and the user-space
   768				 * did not provide an endpoint id
   769				 */
   770				if (!(cur->flags & MPTCP_PM_ADDR_FLAG_IMPLICIT)) {
   771					ret = -EEXIST;
   772					goto out;
   773				}
   774				if (entry->addr.id)
   775					goto out;
   776	
   777				/* allow callers that only need to look up the local
   778				 * addr's id to skip replacement. This allows them to
   779				 * avoid calling synchronize_rcu in the packet recv
   780				 * path.
   781				 */
   782				if (!replace) {
   783					kfree(entry);
   784					ret = cur->addr.id;
   785					goto out;
   786				}
   787	
   788				pernet->endpoints--;
   789				entry->addr.id = cur->addr.id;
   790				list_del_rcu(&cur->list);
   791				del_entry = cur;
   792				break;
   793			}
   794		}
   795	
   796		if (!entry->addr.id) {
   797	find_next:
 > 798			unsigned int id = find_next_zero_bit(pernet->id_bitmap,
   799							     MPTCP_PM_MAX_ADDR_ID + 1,
   800							     pernet->next_id);
   801			if (id > MPTCP_PM_MAX_ADDR_ID) {
   802				ret = -ENOSPC;
   803				goto out;
   804			}
   805			entry->addr.id = id;
   806			if (!entry->addr.id && pernet->next_id != 1) {
   807				pernet->next_id = 1;
   808				goto find_next;
   809			}
   810		}
   811	
   812		if (!entry->addr.id)
   813			goto out;
   814	
   815		__set_bit(entry->addr.id, pernet->id_bitmap);
   816		if (entry->addr.id > pernet->next_id)
   817			pernet->next_id = entry->addr.id;
   818	
   819		if (entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL) {
   820			addr_max = pernet->endp_signal_max;
   821			WRITE_ONCE(pernet->endp_signal_max, addr_max + 1);
   822		}
   823		if (entry->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) {
   824			addr_max = pernet->endp_subflow_max;
   825			WRITE_ONCE(pernet->endp_subflow_max, addr_max + 1);
   826		}
   827		if (entry->flags & MPTCP_PM_ADDR_FLAG_LAMINAR) {
   828			addr_max = pernet->endp_laminar_max;
   829			WRITE_ONCE(pernet->endp_laminar_max, addr_max + 1);
   830		}
   831		if (entry->flags & MPTCP_PM_ADDR_FLAG_FULLMESH) {
   832			addr_max = pernet->endp_fullmesh_max;
   833			WRITE_ONCE(pernet->endp_fullmesh_max, addr_max + 1);
   834		}
   835	
   836		pernet->endpoints++;
   837		if (!entry->addr.port)
   838			list_add_tail_rcu(&entry->list, &pernet->endp_list);
   839		else
   840			list_add_rcu(&entry->list, &pernet->endp_list);
   841		ret = entry->addr.id;
   842	
   843	out:
   844		spin_unlock_bh(&pernet->lock);
   845	
   846		/* just replaced an existing entry, free it */
   847		if (del_entry) {
   848			synchronize_rcu();
   849			__mptcp_pm_release_addr_entry(del_entry);
   850		}
   851		return ret;
   852	}
   853	

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 12+ messages in thread

end of thread, other threads:[~2026-08-06 22:05 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14  8:03 [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted luoqing
2026-07-14  9:25 ` MPTCP CI
2026-07-14  9:54 ` MPTCP CI
2026-07-15  9:10 ` Matthieu Baerts
2026-08-04  2:23 ` [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted luoqing
2026-08-04  2:23   ` [PATCH MPTCH-next] selftests: add test for userspace PM address ID overflow luoqing
2026-08-04  3:29     ` MPTCP CI
2026-08-04 18:37     ` Matthieu Baerts
2026-08-04  3:34   ` [PATCH v2 MPTCP-net] pm: userspace: fix address ID overflow when all IDs exhausted MPTCP CI
2026-08-04 18:22   ` Matthieu Baerts
2026-08-06 20:17 ` [PATCH] mptcp: pm: Fix address ID overflow when all IDs are exhausted kernel test robot
2026-08-06 22:04 ` kernel test robot

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox