* [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp [not found] <2024082656-bamboo-skinless-9366@gregkh> @ 2024-09-04 10:57 ` Matthieu Baerts (NGI0) 2024-09-04 11:03 ` [PATCH 6.1.y 0/2] Backport of "mptcp: pm: reuse ID 0 after delete and re-add" and more Matthieu Baerts (NGI0) ` (4 more replies) 0 siblings, 5 replies; 10+ messages in thread From: Matthieu Baerts (NGI0) @ 2024-09-04 10:57 UTC (permalink / raw) To: stable, gregkh Cc: MPTCP Upstream, Matthieu Baerts (NGI0), Paolo Abeni, Mat Martineau, Jakub Kicinski commit 48e50dcbcbaaf713d82bf2da5c16aeced94ad07d upstream. select_local_address() and select_signal_address() both select an endpoint entry from the list inside an RCU protected section, but return a reference to it, to be read later on. If the entry is dereferenced after the RCU unlock, reading info could cause a Use-after-Free. A simple solution is to copy the required info while inside the RCU protected section to avoid any risk of UaF later. The address ID might need to be modified later to handle the ID0 case later, so a copy seems OK to deal with. Reported-by: Paolo Abeni <pabeni@redhat.com> Closes: https://lore.kernel.org/45cd30d3-7710-491c-ae4d-a1368c00beb1@redhat.com Fixes: 01cacb00b35c ("mptcp: add netlink-based PM") Cc: stable@vger.kernel.org Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20240819-net-mptcp-pm-reusing-id-v1-14-38035d40de5b@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org> [ Conflicts in pm_netlink.c, because the context has been modified in commit b9d69db87fb7 ("mptcp: let the in-kernel PM use mixed IPv4 and IPv6 addresses"), which is not a candidate for the backports. The same modifications have been applied in this version. The conflict in mptcp_pm_create_subflow_or_signal_addr() has been resolved by taking the newer version, which skip a lock if it is not needed. ] Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> --- net/mptcp/pm_netlink.c | 68 +++++++++++++++++++++++------------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index a152a3474d2c..44b036abe30f 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -150,12 +150,14 @@ static bool lookup_subflow_by_daddr(const struct list_head *list, return false; } -static struct mptcp_pm_addr_entry * +static bool select_local_address(const struct pm_nl_pernet *pernet, - const struct mptcp_sock *msk) + const struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *new_entry) { const struct sock *sk = (const struct sock *)msk; - struct mptcp_pm_addr_entry *entry, *ret = NULL; + struct mptcp_pm_addr_entry *entry; + bool found = false; msk_owned_by_me(msk); @@ -177,17 +179,21 @@ select_local_address(const struct pm_nl_pernet *pernet, continue; } - ret = entry; + *new_entry = *entry; + found = true; break; } rcu_read_unlock(); - return ret; + + return found; } -static struct mptcp_pm_addr_entry * -select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk) +static bool +select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *new_entry) { - struct mptcp_pm_addr_entry *entry, *ret = NULL; + struct mptcp_pm_addr_entry *entry; + bool found = false; rcu_read_lock(); /* do not keep any additional per socket state, just signal @@ -202,11 +208,13 @@ select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk) if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) continue; - ret = entry; + *new_entry = *entry; + found = true; break; } rcu_read_unlock(); - return ret; + + return found; } unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk) @@ -527,9 +535,10 @@ __lookup_addr(struct pm_nl_pernet *pernet, const struct mptcp_addr_info *info, static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) { - struct mptcp_pm_addr_entry *local, *signal_and_subflow = NULL; struct sock *sk = (struct sock *)msk; + struct mptcp_pm_addr_entry local; unsigned int add_addr_signal_max; + bool signal_and_subflow = false; unsigned int local_addr_max; struct pm_nl_pernet *pernet; unsigned int subflows_max; @@ -580,23 +589,22 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) return; - local = select_signal_address(pernet, msk); - if (!local) + if (!select_signal_address(pernet, msk, &local)) goto subflow; /* If the alloc fails, we are on memory pressure, not worth * continuing, and trying to create subflows. */ - if (!mptcp_pm_alloc_anno_list(msk, &local->addr)) + if (!mptcp_pm_alloc_anno_list(msk, &local.addr)) return; - __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); + __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); msk->pm.add_addr_signaled++; - mptcp_pm_announce_addr(msk, &local->addr, false); + mptcp_pm_announce_addr(msk, &local.addr, false); mptcp_pm_nl_addr_send_ack(msk); - if (local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) - signal_and_subflow = local; + if (local.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) + signal_and_subflow = true; } subflow: @@ -607,24 +615,22 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) bool fullmesh; int i, nr; - if (signal_and_subflow) { - local = signal_and_subflow; - signal_and_subflow = NULL; - } else { - local = select_local_address(pernet, msk); - if (!local) - break; - } + if (signal_and_subflow) + signal_and_subflow = false; + else if (!select_local_address(pernet, msk, &local)) + break; - fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH); + fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH); msk->pm.local_addr_used++; - nr = fill_remote_addresses_vec(msk, &local->addr, fullmesh, addrs); - if (nr) - __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); + __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); + nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs); + if (nr == 0) + continue; + spin_unlock_bh(&msk->pm.lock); for (i = 0; i < nr; i++) - __mptcp_subflow_connect(sk, &local->addr, &addrs[i]); + __mptcp_subflow_connect(sk, &local.addr, &addrs[i]); spin_lock_bh(&msk->pm.lock); } mptcp_pm_nl_check_work_pending(msk); -- 2.45.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* [PATCH 6.1.y 0/2] Backport of "mptcp: pm: reuse ID 0 after delete and re-add" and more 2024-09-04 10:57 ` [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp Matthieu Baerts (NGI0) @ 2024-09-04 11:03 ` Matthieu Baerts (NGI0) 2024-09-04 11:03 ` [PATCH 6.1.y 1/2] mptcp: pm: reuse ID 0 after delete and re-add Matthieu Baerts (NGI0) ` (3 subsequent siblings) 4 siblings, 0 replies; 10+ messages in thread From: Matthieu Baerts (NGI0) @ 2024-09-04 11:03 UTC (permalink / raw) To: mptcp, stable, gregkh; +Cc: Matthieu Baerts (NGI0) After having applied the patch "mptcp: pm: avoid possible UaF when selecting endp" in v6.1 with the adaptations proposed in the parent message [1], the two following patches can be applied without conflicts: - 8b8ed1b429f8 ("mptcp: pm: reuse ID 0 after delete and re-add") - 9366922adc6a ("mptcp: pm: fix ID 0 endp usage after multiple re-creations") [1] https://lore.kernel.org/20240904105721.4075460-2-matttbe@kernel.org Matthieu Baerts (NGI0) (2): mptcp: pm: reuse ID 0 after delete and re-add mptcp: pm: fix ID 0 endp usage after multiple re-creations net/mptcp/pm_netlink.c | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) -- 2.45.2 ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 6.1.y 1/2] mptcp: pm: reuse ID 0 after delete and re-add 2024-09-04 10:57 ` [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp Matthieu Baerts (NGI0) 2024-09-04 11:03 ` [PATCH 6.1.y 0/2] Backport of "mptcp: pm: reuse ID 0 after delete and re-add" and more Matthieu Baerts (NGI0) @ 2024-09-04 11:03 ` Matthieu Baerts (NGI0) 2024-09-04 14:31 ` Greg KH 2024-09-04 14:32 ` Patch "mptcp: pm: reuse ID 0 after delete and re-add" has been added to the 6.1-stable tree gregkh 2024-09-04 11:03 ` [PATCH 6.1.y 2/2] mptcp: pm: fix ID 0 endp usage after multiple re-creations Matthieu Baerts (NGI0) ` (2 subsequent siblings) 4 siblings, 2 replies; 10+ messages in thread From: Matthieu Baerts (NGI0) @ 2024-09-04 11:03 UTC (permalink / raw) To: mptcp, stable, gregkh; +Cc: Matthieu Baerts (NGI0), Mat Martineau, Paolo Abeni commit 8b8ed1b429f8fa7ebd5632555e7b047bc0620075 upstream. When the endpoint used by the initial subflow is removed and re-added later, the PM has to force the ID 0, it is a special case imposed by the MPTCP specs. Note that the endpoint should then need to be re-added reusing the same ID. Fixes: 3ad14f54bd74 ("mptcp: more accurate MPC endpoint tracking") Cc: stable@vger.kernel.org Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> --- net/mptcp/pm_netlink.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index 44b036abe30f..c834de47bddc 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -600,6 +600,11 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); msk->pm.add_addr_signaled++; + + /* Special case for ID0: set the correct ID */ + if (local.addr.id == msk->mpc_endpoint_id) + local.addr.id = 0; + mptcp_pm_announce_addr(msk, &local.addr, false); mptcp_pm_nl_addr_send_ack(msk); @@ -624,6 +629,11 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) msk->pm.local_addr_used++; __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); + + /* Special case for ID0: set the correct ID */ + if (local.addr.id == msk->mpc_endpoint_id) + local.addr.id = 0; + nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs); if (nr == 0) continue; -- 2.45.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 6.1.y 1/2] mptcp: pm: reuse ID 0 after delete and re-add 2024-09-04 11:03 ` [PATCH 6.1.y 1/2] mptcp: pm: reuse ID 0 after delete and re-add Matthieu Baerts (NGI0) @ 2024-09-04 14:31 ` Greg KH 2024-09-04 14:32 ` Patch "mptcp: pm: reuse ID 0 after delete and re-add" has been added to the 6.1-stable tree gregkh 1 sibling, 0 replies; 10+ messages in thread From: Greg KH @ 2024-09-04 14:31 UTC (permalink / raw) To: Matthieu Baerts (NGI0); +Cc: mptcp, stable, Mat Martineau, Paolo Abeni On Wed, Sep 04, 2024 at 01:03:08PM +0200, Matthieu Baerts (NGI0) wrote: > commit 8b8ed1b429f8fa7ebd5632555e7b047bc0620075 upstream. > Applied ^ permalink raw reply [flat|nested] 10+ messages in thread
* Patch "mptcp: pm: reuse ID 0 after delete and re-add" has been added to the 6.1-stable tree 2024-09-04 11:03 ` [PATCH 6.1.y 1/2] mptcp: pm: reuse ID 0 after delete and re-add Matthieu Baerts (NGI0) 2024-09-04 14:31 ` Greg KH @ 2024-09-04 14:32 ` gregkh 1 sibling, 0 replies; 10+ messages in thread From: gregkh @ 2024-09-04 14:32 UTC (permalink / raw) To: gregkh, martineau, matttbe, mptcp, pabeni; +Cc: stable-commits This is a note to let you know that I've just added the patch titled mptcp: pm: reuse ID 0 after delete and re-add to the 6.1-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: mptcp-pm-reuse-id-0-after-delete-and-re-add.patch and it can be found in the queue-6.1 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@vger.kernel.org> know about it. From stable+bounces-73005-greg=kroah.com@vger.kernel.org Wed Sep 4 13:04:05 2024 From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org> Date: Wed, 4 Sep 2024 13:03:08 +0200 Subject: mptcp: pm: reuse ID 0 after delete and re-add To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Mat Martineau <martineau@kernel.org>, Paolo Abeni <pabeni@redhat.com> Message-ID: <20240904110306.4082410-5-matttbe@kernel.org> From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org> commit 8b8ed1b429f8fa7ebd5632555e7b047bc0620075 upstream. When the endpoint used by the initial subflow is removed and re-added later, the PM has to force the ID 0, it is a special case imposed by the MPTCP specs. Note that the endpoint should then need to be re-added reusing the same ID. Fixes: 3ad14f54bd74 ("mptcp: more accurate MPC endpoint tracking") Cc: stable@vger.kernel.org Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- net/mptcp/pm_netlink.c | 10 ++++++++++ 1 file changed, 10 insertions(+) --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -600,6 +600,11 @@ static void mptcp_pm_create_subflow_or_s __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); msk->pm.add_addr_signaled++; + + /* Special case for ID0: set the correct ID */ + if (local.addr.id == msk->mpc_endpoint_id) + local.addr.id = 0; + mptcp_pm_announce_addr(msk, &local.addr, false); mptcp_pm_nl_addr_send_ack(msk); @@ -624,6 +629,11 @@ subflow: msk->pm.local_addr_used++; __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); + + /* Special case for ID0: set the correct ID */ + if (local.addr.id == msk->mpc_endpoint_id) + local.addr.id = 0; + nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs); if (nr == 0) continue; Patches currently in stable-queue which might be from matttbe@kernel.org are queue-6.1/mptcp-pm-fix-rm_addr-id-for-the-initial-subflow.patch queue-6.1/selftests-mptcp-join-validate-fullmesh-endp-on-1st-sf.patch queue-6.1/mptcp-pm-fix-id-0-endp-usage-after-multiple-re-creations.patch queue-6.1/mptcp-make-pm_remove_addrs_and_subflows-static.patch queue-6.1/mptcp-pm-avoid-possible-uaf-when-selecting-endp.patch queue-6.1/mptcp-pm-reuse-id-0-after-delete-and-re-add.patch queue-6.1/selftests-mptcp-join-check-re-adding-init-endp-with-id.patch queue-6.1/selftests-mptcp-join-test-for-flush-re-add-endpoints.patch queue-6.1/selftests-mptcp-add-explicit-test-case-for-remove-re.patch queue-6.1/selftests-mptcp-add-explicit-test-case-for-remove-readd.patch queue-6.1/selftests-mptcp-join-check-re-adding-init-endp-with-.patch queue-6.1/selftests-mptcp-join-check-re-using-id-of-closed-subflow.patch queue-6.1/mptcp-pm-fullmesh-select-the-right-id-later.patch queue-6.1/mptcp-pr_debug-add-missing-n-at-the-end.patch queue-6.1/selftests-mptcp-join-check-re-using-id-of-unused-add.patch queue-6.1/selftests-mptcp-join-check-re-using-id-of-unused-add_addr.patch ^ permalink raw reply [flat|nested] 10+ messages in thread
* [PATCH 6.1.y 2/2] mptcp: pm: fix ID 0 endp usage after multiple re-creations 2024-09-04 10:57 ` [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp Matthieu Baerts (NGI0) 2024-09-04 11:03 ` [PATCH 6.1.y 0/2] Backport of "mptcp: pm: reuse ID 0 after delete and re-add" and more Matthieu Baerts (NGI0) 2024-09-04 11:03 ` [PATCH 6.1.y 1/2] mptcp: pm: reuse ID 0 after delete and re-add Matthieu Baerts (NGI0) @ 2024-09-04 11:03 ` Matthieu Baerts (NGI0) 2024-09-04 14:31 ` Greg KH 2024-09-04 14:32 ` Patch "mptcp: pm: fix ID 0 endp usage after multiple re-creations" has been added to the 6.1-stable tree gregkh 2024-09-04 14:31 ` [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp Greg KH 2024-09-04 14:32 ` Patch "mptcp: pm: avoid possible UaF when selecting endp" has been added to the 6.1-stable tree gregkh 4 siblings, 2 replies; 10+ messages in thread From: Matthieu Baerts (NGI0) @ 2024-09-04 11:03 UTC (permalink / raw) To: mptcp, stable, gregkh Cc: Matthieu Baerts (NGI0), Arınç ÜNAL, syzbot+455d38ecd5f655fc45cf, Mat Martineau, Paolo Abeni commit 9366922adc6a71378ca01f898c41be295309f044 upstream. 'local_addr_used' and 'add_addr_accepted' are decremented for addresses not related to the initial subflow (ID0), because the source and destination addresses of the initial subflows are known from the beginning: they don't count as "additional local address being used" or "ADD_ADDR being accepted". It is then required not to increment them when the entrypoint used by the initial subflow is removed and re-added during a connection. Without this modification, this entrypoint cannot be removed and re-added more than once. Reported-by: Arınç ÜNAL <arinc.unal@arinc9.com> Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/512 Fixes: 3ad14f54bd74 ("mptcp: more accurate MPC endpoint tracking") Reported-by: syzbot+455d38ecd5f655fc45cf@syzkaller.appspotmail.com Closes: https://lore.kernel.org/00000000000049861306209237f4@google.com Cc: stable@vger.kernel.org Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com> Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> --- net/mptcp/pm_netlink.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/net/mptcp/pm_netlink.c b/net/mptcp/pm_netlink.c index c834de47bddc..2f8a13589ed6 100644 --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -627,12 +627,13 @@ static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH); - msk->pm.local_addr_used++; __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); /* Special case for ID0: set the correct ID */ if (local.addr.id == msk->mpc_endpoint_id) local.addr.id = 0; + else /* local_addr_used is not decr for ID 0 */ + msk->pm.local_addr_used++; nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs); if (nr == 0) @@ -758,7 +759,9 @@ static void mptcp_pm_nl_add_addr_received(struct mptcp_sock *msk) spin_lock_bh(&msk->pm.lock); if (sf_created) { - msk->pm.add_addr_accepted++; + /* add_addr_accepted is not decr for ID 0 */ + if (remote.id) + msk->pm.add_addr_accepted++; if (msk->pm.add_addr_accepted >= add_addr_accept_max || msk->pm.subflows >= subflows_max) WRITE_ONCE(msk->pm.accept_addr, false); -- 2.45.2 ^ permalink raw reply related [flat|nested] 10+ messages in thread
* Re: [PATCH 6.1.y 2/2] mptcp: pm: fix ID 0 endp usage after multiple re-creations 2024-09-04 11:03 ` [PATCH 6.1.y 2/2] mptcp: pm: fix ID 0 endp usage after multiple re-creations Matthieu Baerts (NGI0) @ 2024-09-04 14:31 ` Greg KH 2024-09-04 14:32 ` Patch "mptcp: pm: fix ID 0 endp usage after multiple re-creations" has been added to the 6.1-stable tree gregkh 1 sibling, 0 replies; 10+ messages in thread From: Greg KH @ 2024-09-04 14:31 UTC (permalink / raw) To: Matthieu Baerts (NGI0) Cc: mptcp, stable, Arınç ÜNAL, syzbot+455d38ecd5f655fc45cf, Mat Martineau, Paolo Abeni On Wed, Sep 04, 2024 at 01:03:09PM +0200, Matthieu Baerts (NGI0) wrote: > commit 9366922adc6a71378ca01f898c41be295309f044 upstream. > Applied ^ permalink raw reply [flat|nested] 10+ messages in thread
* Patch "mptcp: pm: fix ID 0 endp usage after multiple re-creations" has been added to the 6.1-stable tree 2024-09-04 11:03 ` [PATCH 6.1.y 2/2] mptcp: pm: fix ID 0 endp usage after multiple re-creations Matthieu Baerts (NGI0) 2024-09-04 14:31 ` Greg KH @ 2024-09-04 14:32 ` gregkh 1 sibling, 0 replies; 10+ messages in thread From: gregkh @ 2024-09-04 14:32 UTC (permalink / raw) To: arinc.unal, gregkh, martineau, matttbe, mptcp, pabeni, syzbot+455d38ecd5f655fc45cf Cc: stable-commits This is a note to let you know that I've just added the patch titled mptcp: pm: fix ID 0 endp usage after multiple re-creations to the 6.1-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: mptcp-pm-fix-id-0-endp-usage-after-multiple-re-creations.patch and it can be found in the queue-6.1 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@vger.kernel.org> know about it. From stable+bounces-73006-greg=kroah.com@vger.kernel.org Wed Sep 4 13:04:07 2024 From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org> Date: Wed, 4 Sep 2024 13:03:09 +0200 Subject: mptcp: pm: fix ID 0 endp usage after multiple re-creations To: mptcp@lists.linux.dev, stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, "Arınç ÜNAL" <arinc.unal@arinc9.com>, syzbot+455d38ecd5f655fc45cf@syzkaller.appspotmail.com, "Mat Martineau" <martineau@kernel.org>, "Paolo Abeni" <pabeni@redhat.com> Message-ID: <20240904110306.4082410-6-matttbe@kernel.org> From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org> commit 9366922adc6a71378ca01f898c41be295309f044 upstream. 'local_addr_used' and 'add_addr_accepted' are decremented for addresses not related to the initial subflow (ID0), because the source and destination addresses of the initial subflows are known from the beginning: they don't count as "additional local address being used" or "ADD_ADDR being accepted". It is then required not to increment them when the entrypoint used by the initial subflow is removed and re-added during a connection. Without this modification, this entrypoint cannot be removed and re-added more than once. Reported-by: Arınç ÜNAL <arinc.unal@arinc9.com> Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/512 Fixes: 3ad14f54bd74 ("mptcp: more accurate MPC endpoint tracking") Reported-by: syzbot+455d38ecd5f655fc45cf@syzkaller.appspotmail.com Closes: https://lore.kernel.org/00000000000049861306209237f4@google.com Cc: stable@vger.kernel.org Tested-by: Arınç ÜNAL <arinc.unal@arinc9.com> Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- net/mptcp/pm_netlink.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -627,12 +627,13 @@ subflow: fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH); - msk->pm.local_addr_used++; __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); /* Special case for ID0: set the correct ID */ if (local.addr.id == msk->mpc_endpoint_id) local.addr.id = 0; + else /* local_addr_used is not decr for ID 0 */ + msk->pm.local_addr_used++; nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs); if (nr == 0) @@ -758,7 +759,9 @@ static void mptcp_pm_nl_add_addr_receive spin_lock_bh(&msk->pm.lock); if (sf_created) { - msk->pm.add_addr_accepted++; + /* add_addr_accepted is not decr for ID 0 */ + if (remote.id) + msk->pm.add_addr_accepted++; if (msk->pm.add_addr_accepted >= add_addr_accept_max || msk->pm.subflows >= subflows_max) WRITE_ONCE(msk->pm.accept_addr, false); Patches currently in stable-queue which might be from matttbe@kernel.org are queue-6.1/mptcp-pm-fix-rm_addr-id-for-the-initial-subflow.patch queue-6.1/selftests-mptcp-join-validate-fullmesh-endp-on-1st-sf.patch queue-6.1/mptcp-pm-fix-id-0-endp-usage-after-multiple-re-creations.patch queue-6.1/mptcp-make-pm_remove_addrs_and_subflows-static.patch queue-6.1/mptcp-pm-avoid-possible-uaf-when-selecting-endp.patch queue-6.1/mptcp-pm-reuse-id-0-after-delete-and-re-add.patch queue-6.1/selftests-mptcp-join-check-re-adding-init-endp-with-id.patch queue-6.1/selftests-mptcp-join-test-for-flush-re-add-endpoints.patch queue-6.1/selftests-mptcp-add-explicit-test-case-for-remove-re.patch queue-6.1/selftests-mptcp-add-explicit-test-case-for-remove-readd.patch queue-6.1/selftests-mptcp-join-check-re-adding-init-endp-with-.patch queue-6.1/selftests-mptcp-join-check-re-using-id-of-closed-subflow.patch queue-6.1/mptcp-pm-fullmesh-select-the-right-id-later.patch queue-6.1/mptcp-pr_debug-add-missing-n-at-the-end.patch queue-6.1/selftests-mptcp-join-check-re-using-id-of-unused-add.patch queue-6.1/selftests-mptcp-join-check-re-using-id-of-unused-add_addr.patch ^ permalink raw reply [flat|nested] 10+ messages in thread
* Re: [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp 2024-09-04 10:57 ` [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp Matthieu Baerts (NGI0) ` (2 preceding siblings ...) 2024-09-04 11:03 ` [PATCH 6.1.y 2/2] mptcp: pm: fix ID 0 endp usage after multiple re-creations Matthieu Baerts (NGI0) @ 2024-09-04 14:31 ` Greg KH 2024-09-04 14:32 ` Patch "mptcp: pm: avoid possible UaF when selecting endp" has been added to the 6.1-stable tree gregkh 4 siblings, 0 replies; 10+ messages in thread From: Greg KH @ 2024-09-04 14:31 UTC (permalink / raw) To: Matthieu Baerts (NGI0) Cc: stable, MPTCP Upstream, Paolo Abeni, Mat Martineau, Jakub Kicinski On Wed, Sep 04, 2024 at 12:57:22PM +0200, Matthieu Baerts (NGI0) wrote: > commit 48e50dcbcbaaf713d82bf2da5c16aeced94ad07d upstream. > Applied ^ permalink raw reply [flat|nested] 10+ messages in thread
* Patch "mptcp: pm: avoid possible UaF when selecting endp" has been added to the 6.1-stable tree 2024-09-04 10:57 ` [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp Matthieu Baerts (NGI0) ` (3 preceding siblings ...) 2024-09-04 14:31 ` [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp Greg KH @ 2024-09-04 14:32 ` gregkh 4 siblings, 0 replies; 10+ messages in thread From: gregkh @ 2024-09-04 14:32 UTC (permalink / raw) To: gregkh, kuba, martineau, matttbe, mptcp, pabeni; +Cc: stable-commits This is a note to let you know that I've just added the patch titled mptcp: pm: avoid possible UaF when selecting endp to the 6.1-stable tree which can be found at: http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary The filename of the patch is: mptcp-pm-avoid-possible-uaf-when-selecting-endp.patch and it can be found in the queue-6.1 subdirectory. If you, or anyone else, feels it should not be added to the stable tree, please let <stable@vger.kernel.org> know about it. From stable+bounces-73002-greg=kroah.com@vger.kernel.org Wed Sep 4 12:58:37 2024 From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org> Date: Wed, 4 Sep 2024 12:57:22 +0200 Subject: mptcp: pm: avoid possible UaF when selecting endp To: stable@vger.kernel.org, gregkh@linuxfoundation.org Cc: MPTCP Upstream <mptcp@lists.linux.dev>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Paolo Abeni <pabeni@redhat.com>, Mat Martineau <martineau@kernel.org>, Jakub Kicinski <kuba@kernel.org> Message-ID: <20240904105721.4075460-2-matttbe@kernel.org> From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org> commit 48e50dcbcbaaf713d82bf2da5c16aeced94ad07d upstream. select_local_address() and select_signal_address() both select an endpoint entry from the list inside an RCU protected section, but return a reference to it, to be read later on. If the entry is dereferenced after the RCU unlock, reading info could cause a Use-after-Free. A simple solution is to copy the required info while inside the RCU protected section to avoid any risk of UaF later. The address ID might need to be modified later to handle the ID0 case later, so a copy seems OK to deal with. Reported-by: Paolo Abeni <pabeni@redhat.com> Closes: https://lore.kernel.org/45cd30d3-7710-491c-ae4d-a1368c00beb1@redhat.com Fixes: 01cacb00b35c ("mptcp: add netlink-based PM") Cc: stable@vger.kernel.org Reviewed-by: Mat Martineau <martineau@kernel.org> Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Link: https://patch.msgid.link/20240819-net-mptcp-pm-reusing-id-v1-14-38035d40de5b@kernel.org Signed-off-by: Jakub Kicinski <kuba@kernel.org> [ Conflicts in pm_netlink.c, because the context has been modified in commit b9d69db87fb7 ("mptcp: let the in-kernel PM use mixed IPv4 and IPv6 addresses"), which is not a candidate for the backports. The same modifications have been applied in this version. The conflict in mptcp_pm_create_subflow_or_signal_addr() has been resolved by taking the newer version, which skip a lock if it is not needed. ] Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> --- net/mptcp/pm_netlink.c | 68 ++++++++++++++++++++++++++----------------------- 1 file changed, 37 insertions(+), 31 deletions(-) --- a/net/mptcp/pm_netlink.c +++ b/net/mptcp/pm_netlink.c @@ -150,12 +150,14 @@ static bool lookup_subflow_by_daddr(cons return false; } -static struct mptcp_pm_addr_entry * +static bool select_local_address(const struct pm_nl_pernet *pernet, - const struct mptcp_sock *msk) + const struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *new_entry) { const struct sock *sk = (const struct sock *)msk; - struct mptcp_pm_addr_entry *entry, *ret = NULL; + struct mptcp_pm_addr_entry *entry; + bool found = false; msk_owned_by_me(msk); @@ -177,17 +179,21 @@ select_local_address(const struct pm_nl_ continue; } - ret = entry; + *new_entry = *entry; + found = true; break; } rcu_read_unlock(); - return ret; + + return found; } -static struct mptcp_pm_addr_entry * -select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk) +static bool +select_signal_address(struct pm_nl_pernet *pernet, const struct mptcp_sock *msk, + struct mptcp_pm_addr_entry *new_entry) { - struct mptcp_pm_addr_entry *entry, *ret = NULL; + struct mptcp_pm_addr_entry *entry; + bool found = false; rcu_read_lock(); /* do not keep any additional per socket state, just signal @@ -202,11 +208,13 @@ select_signal_address(struct pm_nl_perne if (!(entry->flags & MPTCP_PM_ADDR_FLAG_SIGNAL)) continue; - ret = entry; + *new_entry = *entry; + found = true; break; } rcu_read_unlock(); - return ret; + + return found; } unsigned int mptcp_pm_get_add_addr_signal_max(const struct mptcp_sock *msk) @@ -527,9 +535,10 @@ __lookup_addr(struct pm_nl_pernet *perne static void mptcp_pm_create_subflow_or_signal_addr(struct mptcp_sock *msk) { - struct mptcp_pm_addr_entry *local, *signal_and_subflow = NULL; struct sock *sk = (struct sock *)msk; + struct mptcp_pm_addr_entry local; unsigned int add_addr_signal_max; + bool signal_and_subflow = false; unsigned int local_addr_max; struct pm_nl_pernet *pernet; unsigned int subflows_max; @@ -580,23 +589,22 @@ static void mptcp_pm_create_subflow_or_s if (msk->pm.addr_signal & BIT(MPTCP_ADD_ADDR_SIGNAL)) return; - local = select_signal_address(pernet, msk); - if (!local) + if (!select_signal_address(pernet, msk, &local)) goto subflow; /* If the alloc fails, we are on memory pressure, not worth * continuing, and trying to create subflows. */ - if (!mptcp_pm_alloc_anno_list(msk, &local->addr)) + if (!mptcp_pm_alloc_anno_list(msk, &local.addr)) return; - __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); + __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); msk->pm.add_addr_signaled++; - mptcp_pm_announce_addr(msk, &local->addr, false); + mptcp_pm_announce_addr(msk, &local.addr, false); mptcp_pm_nl_addr_send_ack(msk); - if (local->flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) - signal_and_subflow = local; + if (local.flags & MPTCP_PM_ADDR_FLAG_SUBFLOW) + signal_and_subflow = true; } subflow: @@ -607,24 +615,22 @@ subflow: bool fullmesh; int i, nr; - if (signal_and_subflow) { - local = signal_and_subflow; - signal_and_subflow = NULL; - } else { - local = select_local_address(pernet, msk); - if (!local) - break; - } + if (signal_and_subflow) + signal_and_subflow = false; + else if (!select_local_address(pernet, msk, &local)) + break; - fullmesh = !!(local->flags & MPTCP_PM_ADDR_FLAG_FULLMESH); + fullmesh = !!(local.flags & MPTCP_PM_ADDR_FLAG_FULLMESH); msk->pm.local_addr_used++; - nr = fill_remote_addresses_vec(msk, &local->addr, fullmesh, addrs); - if (nr) - __clear_bit(local->addr.id, msk->pm.id_avail_bitmap); + __clear_bit(local.addr.id, msk->pm.id_avail_bitmap); + nr = fill_remote_addresses_vec(msk, &local.addr, fullmesh, addrs); + if (nr == 0) + continue; + spin_unlock_bh(&msk->pm.lock); for (i = 0; i < nr; i++) - __mptcp_subflow_connect(sk, &local->addr, &addrs[i]); + __mptcp_subflow_connect(sk, &local.addr, &addrs[i]); spin_lock_bh(&msk->pm.lock); } mptcp_pm_nl_check_work_pending(msk); Patches currently in stable-queue which might be from matttbe@kernel.org are queue-6.1/mptcp-pm-fix-rm_addr-id-for-the-initial-subflow.patch queue-6.1/selftests-mptcp-join-validate-fullmesh-endp-on-1st-sf.patch queue-6.1/mptcp-pm-fix-id-0-endp-usage-after-multiple-re-creations.patch queue-6.1/mptcp-make-pm_remove_addrs_and_subflows-static.patch queue-6.1/mptcp-pm-avoid-possible-uaf-when-selecting-endp.patch queue-6.1/mptcp-pm-reuse-id-0-after-delete-and-re-add.patch queue-6.1/selftests-mptcp-join-check-re-adding-init-endp-with-id.patch queue-6.1/selftests-mptcp-join-test-for-flush-re-add-endpoints.patch queue-6.1/selftests-mptcp-add-explicit-test-case-for-remove-re.patch queue-6.1/selftests-mptcp-add-explicit-test-case-for-remove-readd.patch queue-6.1/selftests-mptcp-join-check-re-adding-init-endp-with-.patch queue-6.1/selftests-mptcp-join-check-re-using-id-of-closed-subflow.patch queue-6.1/mptcp-pm-fullmesh-select-the-right-id-later.patch queue-6.1/mptcp-pr_debug-add-missing-n-at-the-end.patch queue-6.1/selftests-mptcp-join-check-re-using-id-of-unused-add.patch queue-6.1/selftests-mptcp-join-check-re-using-id-of-unused-add_addr.patch ^ permalink raw reply [flat|nested] 10+ messages in thread
end of thread, other threads:[~2024-09-04 14:33 UTC | newest]
Thread overview: 10+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
[not found] <2024082656-bamboo-skinless-9366@gregkh>
2024-09-04 10:57 ` [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp Matthieu Baerts (NGI0)
2024-09-04 11:03 ` [PATCH 6.1.y 0/2] Backport of "mptcp: pm: reuse ID 0 after delete and re-add" and more Matthieu Baerts (NGI0)
2024-09-04 11:03 ` [PATCH 6.1.y 1/2] mptcp: pm: reuse ID 0 after delete and re-add Matthieu Baerts (NGI0)
2024-09-04 14:31 ` Greg KH
2024-09-04 14:32 ` Patch "mptcp: pm: reuse ID 0 after delete and re-add" has been added to the 6.1-stable tree gregkh
2024-09-04 11:03 ` [PATCH 6.1.y 2/2] mptcp: pm: fix ID 0 endp usage after multiple re-creations Matthieu Baerts (NGI0)
2024-09-04 14:31 ` Greg KH
2024-09-04 14:32 ` Patch "mptcp: pm: fix ID 0 endp usage after multiple re-creations" has been added to the 6.1-stable tree gregkh
2024-09-04 14:31 ` [PATCH 6.1.y] mptcp: pm: avoid possible UaF when selecting endp Greg KH
2024-09-04 14:32 ` Patch "mptcp: pm: avoid possible UaF when selecting endp" has been added to the 6.1-stable tree gregkh
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox