* [PATCH mptcp 0/2] mptcp: a couple of fix - almost @ 2021-08-20 17:44 Paolo Abeni 2021-08-20 17:44 ` [PATCH mptcp 1/2] mptcp: fix possible divide by zero Paolo Abeni ` (2 more replies) 0 siblings, 3 replies; 7+ messages in thread From: Paolo Abeni @ 2021-08-20 17:44 UTC (permalink / raw) To: mptcp This are couple of changes poped-up while investigating issues/219. They does not address the mentioned issue, but the first one should fix an actual bug, the other is more a cleanup, so the target tree is undefined ;) Paolo Abeni (2): mptcp: fix possible divide by zero mptcp: make the locking tx schema more readable net/mptcp/protocol.c | 73 +++++++++++++++++++++----------------------- 1 file changed, 35 insertions(+), 38 deletions(-) -- 2.26.3 ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH mptcp 1/2] mptcp: fix possible divide by zero 2021-08-20 17:44 [PATCH mptcp 0/2] mptcp: a couple of fix - almost Paolo Abeni @ 2021-08-20 17:44 ` Paolo Abeni 2021-08-20 17:53 ` Mat Martineau 2021-08-24 7:28 ` Matthieu Baerts 2021-08-20 17:44 ` [PATCH mptcp 2/2] mptcp: make the locking tx schema more readable Paolo Abeni 2021-08-20 23:02 ` [PATCH mptcp 0/2] mptcp: a couple of fix - almost Mat Martineau 2 siblings, 2 replies; 7+ messages in thread From: Paolo Abeni @ 2021-08-20 17:44 UTC (permalink / raw) To: mptcp Florian noted that if mptcp_alloc_tx_skb() allocation fails in __mptcp_push_pending(), we can end-up invoking mptcp_push_release()/tcp_push() with a zero mss, causing a divide by 0 error. This change addresses the issue refactoring the skb allocation code so that skb allocation always happens after the call to tcp_send_mss() correctly initialize mss_now. As side bonuses we now fill the skb tx cache only when needed, and this also clean-up a bit the output path. Reported-by: Florian Westphal <fw@strlen.de> Fixes: 724cfd2ee8aa ("mptcp: allocate TX skbs in msk context") Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- net/mptcp/protocol.c | 63 ++++++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 35 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index b5f8ad634571..84aa11a0b2d5 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1003,6 +1003,15 @@ static void mptcp_wmem_uncharge(struct sock *sk, int size) msk->wmem_reserved += size; } +static void __mptcp_mem_reclaim_partial(struct sock *sk) +{ +#ifdef CONFIG_LOCKDEP + WARN_ON_ONCE(!lockdep_is_held(&sk->sk_lock.slock)); +#endif + __mptcp_update_wmem(sk); + sk_mem_reclaim_partial(sk); +} + static void mptcp_mem_reclaim_partial(struct sock *sk) { struct mptcp_sock *msk = mptcp_sk(sk); @@ -1094,12 +1103,8 @@ static void __mptcp_clean_una(struct sock *sk) msk->recovery = false; out: - if (cleaned) { - if (tcp_under_memory_pressure(sk)) { - __mptcp_update_wmem(sk); - sk_mem_reclaim_partial(sk); - } - } + if (cleaned && tcp_under_memory_pressure(sk)) + __mptcp_mem_reclaim_partial(sk); if (snd_una == READ_ONCE(msk->snd_nxt) && !msk->recovery) { if (mptcp_timer_pending(sk) && !mptcp_data_fin_enabled(msk)) @@ -1179,6 +1184,7 @@ struct mptcp_sendmsg_info { u16 limit; u16 sent; unsigned int flags; + bool data_lock_held; }; static int mptcp_check_allowed_size(struct mptcp_sock *msk, u64 data_seq, @@ -1250,17 +1256,17 @@ static bool __mptcp_alloc_tx_skb(struct sock *sk, struct sock *ssk, gfp_t gfp) return false; } -static bool mptcp_must_reclaim_memory(struct sock *sk, struct sock *ssk) +static bool mptcp_alloc_tx_skb(struct sock *sk, struct sock *ssk, bool data_lock_held) { - return !ssk->sk_tx_skb_cache && - tcp_under_memory_pressure(sk); -} + gfp_t gfp = data_lock_held ? GFP_ATOMIC : sk->sk_allocation; -static bool mptcp_alloc_tx_skb(struct sock *sk, struct sock *ssk) -{ - if (unlikely(mptcp_must_reclaim_memory(sk, ssk))) - mptcp_mem_reclaim_partial(sk); - return __mptcp_alloc_tx_skb(sk, ssk, sk->sk_allocation); + if (unlikely(tcp_under_memory_pressure(sk))) { + if (data_lock_held) + __mptcp_mem_reclaim_partial(sk); + else + mptcp_mem_reclaim_partial(sk); + } + return __mptcp_alloc_tx_skb(sk, ssk, gfp); } /* note: this always recompute the csum on the whole skb, even @@ -1314,6 +1320,10 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk, } } + if (!can_collapse && !ssk->sk_tx_skb_cache && + !mptcp_alloc_tx_skb(sk, ssk, info->data_lock_held)) + return 0; + /* Zero window and all data acked? Probe. */ avail_size = mptcp_check_allowed_size(msk, data_seq, avail_size); if (avail_size == 0) { @@ -1526,15 +1536,6 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags) if (ssk != prev_ssk || !prev_ssk) lock_sock(ssk); - /* keep it simple and always provide a new skb for the - * subflow, even if we will not use it when collapsing - * on the pending one - */ - if (!mptcp_alloc_tx_skb(sk, ssk)) { - mptcp_push_release(sk, ssk, &info); - goto out; - } - ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info); if (ret <= 0) { mptcp_push_release(sk, ssk, &info); @@ -1567,7 +1568,9 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags) static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk) { struct mptcp_sock *msk = mptcp_sk(sk); - struct mptcp_sendmsg_info info; + struct mptcp_sendmsg_info info = { + .data_lock_held = true, + }; struct mptcp_data_frag *dfrag; struct sock *xmit_ssk; int len, copied = 0; @@ -1593,13 +1596,6 @@ static void __mptcp_subflow_push_pending(struct sock *sk, struct sock *ssk) goto out; } - if (unlikely(mptcp_must_reclaim_memory(sk, ssk))) { - __mptcp_update_wmem(sk); - sk_mem_reclaim_partial(sk); - } - if (!__mptcp_alloc_tx_skb(sk, ssk, GFP_ATOMIC)) - goto out; - ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info); if (ret <= 0) goto out; @@ -2405,9 +2401,6 @@ static void __mptcp_retrans(struct sock *sk) info.sent = 0; info.limit = READ_ONCE(msk->csum_enabled) ? dfrag->data_len : dfrag->already_sent; while (info.sent < info.limit) { - if (!mptcp_alloc_tx_skb(sk, ssk)) - break; - ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info); if (ret <= 0) break; -- 2.26.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH mptcp 1/2] mptcp: fix possible divide by zero 2021-08-20 17:44 ` [PATCH mptcp 1/2] mptcp: fix possible divide by zero Paolo Abeni @ 2021-08-20 17:53 ` Mat Martineau 2021-08-24 7:28 ` Matthieu Baerts 1 sibling, 0 replies; 7+ messages in thread From: Mat Martineau @ 2021-08-20 17:53 UTC (permalink / raw) To: Paolo Abeni; +Cc: mptcp On Fri, 20 Aug 2021, Paolo Abeni wrote: > Florian noted that if mptcp_alloc_tx_skb() allocation fails > in __mptcp_push_pending(), we can end-up invoking > mptcp_push_release()/tcp_push() with a zero mss, causing > a divide by 0 error. > I'll start running this in syzkaller now and then follow up later with review comments - thanks! - Mat > This change addresses the issue refactoring the skb allocation > code so that skb allocation always happens after the call > to tcp_send_mss() correctly initialize mss_now. > > As side bonuses we now fill the skb tx cache only when needed, > and this also clean-up a bit the output path. > > Reported-by: Florian Westphal <fw@strlen.de> > Fixes: 724cfd2ee8aa ("mptcp: allocate TX skbs in msk context") > Signed-off-by: Paolo Abeni <pabeni@redhat.com> > --- > net/mptcp/protocol.c | 63 ++++++++++++++++++++------------------------ > 1 file changed, 28 insertions(+), 35 deletions(-) -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH mptcp 1/2] mptcp: fix possible divide by zero 2021-08-20 17:44 ` [PATCH mptcp 1/2] mptcp: fix possible divide by zero Paolo Abeni 2021-08-20 17:53 ` Mat Martineau @ 2021-08-24 7:28 ` Matthieu Baerts 1 sibling, 0 replies; 7+ messages in thread From: Matthieu Baerts @ 2021-08-24 7:28 UTC (permalink / raw) To: mptcp; +Cc: Paolo Abeni Hello On 20/08/2021 19:44, Paolo Abeni wrote: > Florian noted that if mptcp_alloc_tx_skb() allocation fails > in __mptcp_push_pending(), we can end-up invoking > mptcp_push_release()/tcp_push() with a zero mss, causing > a divide by 0 error. > > This change addresses the issue refactoring the skb allocation > code so that skb allocation always happens after the call > to tcp_send_mss() correctly initialize mss_now. > > As side bonuses we now fill the skb tx cache only when needed, > and this also clean-up a bit the output path. For those who might have missed the info, a regression has been introduced by this patch. This is tracked on Github: https://github.com/multipath-tcp/mptcp_net-next/issues/227 (Paolo already shared a patch that seems fixing the issue) Cheers, Matt -- Tessares | Belgium | Hybrid Access Solutions www.tessares.net ^ permalink raw reply [flat|nested] 7+ messages in thread
* [PATCH mptcp 2/2] mptcp: make the locking tx schema more readable 2021-08-20 17:44 [PATCH mptcp 0/2] mptcp: a couple of fix - almost Paolo Abeni 2021-08-20 17:44 ` [PATCH mptcp 1/2] mptcp: fix possible divide by zero Paolo Abeni @ 2021-08-20 17:44 ` Paolo Abeni 2021-08-20 23:02 ` [PATCH mptcp 0/2] mptcp: a couple of fix - almost Mat Martineau 2 siblings, 0 replies; 7+ messages in thread From: Paolo Abeni @ 2021-08-20 17:44 UTC (permalink / raw) To: mptcp Florian noted the locking schema used by __mptcp_push_pending() is hard to follow, let's add some more descriptive comments and drop an unneeded and confusing check. Suggested-by: Florian Westphal <fw@strlen.de> Signed-off-by: Paolo Abeni <pabeni@redhat.com> --- net/mptcp/protocol.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c index 84aa11a0b2d5..cd690794e22b 100644 --- a/net/mptcp/protocol.c +++ b/net/mptcp/protocol.c @@ -1525,15 +1525,19 @@ void __mptcp_push_pending(struct sock *sk, unsigned int flags) mptcp_flush_join_list(msk); ssk = mptcp_subflow_get_send(msk); - /* try to keep the subflow socket lock across - * consecutive xmit on the same socket + /* First check. If the ssk has changed since + * the last round, release prev_ssk */ if (ssk != prev_ssk && prev_ssk) mptcp_push_release(sk, prev_ssk, &info); if (!ssk) goto out; - if (ssk != prev_ssk || !prev_ssk) + /* Need to lock the new subflow only if different + * from the previous one, otherwise we are still + * helding the relevant lock + */ + if (ssk != prev_ssk) lock_sock(ssk); ret = mptcp_sendmsg_frag(sk, ssk, dfrag, &info); -- 2.26.3 ^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH mptcp 0/2] mptcp: a couple of fix - almost 2021-08-20 17:44 [PATCH mptcp 0/2] mptcp: a couple of fix - almost Paolo Abeni 2021-08-20 17:44 ` [PATCH mptcp 1/2] mptcp: fix possible divide by zero Paolo Abeni 2021-08-20 17:44 ` [PATCH mptcp 2/2] mptcp: make the locking tx schema more readable Paolo Abeni @ 2021-08-20 23:02 ` Mat Martineau 2021-08-23 7:16 ` Matthieu Baerts 2 siblings, 1 reply; 7+ messages in thread From: Mat Martineau @ 2021-08-20 23:02 UTC (permalink / raw) To: Paolo Abeni; +Cc: mptcp On Fri, 20 Aug 2021, Paolo Abeni wrote: > This are couple of changes poped-up while investigating > issues/219. They does not address the mentioned issue, > but the first one should fix an actual bug, the other > is more a cleanup, so the target tree is undefined ;) > > Paolo Abeni (2): > mptcp: fix possible divide by zero > mptcp: make the locking tx schema more readable > > net/mptcp/protocol.c | 73 +++++++++++++++++++++----------------------- > 1 file changed, 35 insertions(+), 38 deletions(-) > > -- > 2.26.3 So far my syzkaller setup hasn't seen the div-by-0 again, but it was typically taking days to show up. I'll leave that running over the weekend. Changes look good to me - mptcp_push_release() is now only called from places where info->mss_now is non-zero. Patch 1 for -net, patch 2 for net-next seems appropriate. Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com> -- Mat Martineau Intel ^ permalink raw reply [flat|nested] 7+ messages in thread
* Re: [PATCH mptcp 0/2] mptcp: a couple of fix - almost 2021-08-20 23:02 ` [PATCH mptcp 0/2] mptcp: a couple of fix - almost Mat Martineau @ 2021-08-23 7:16 ` Matthieu Baerts 0 siblings, 0 replies; 7+ messages in thread From: Matthieu Baerts @ 2021-08-23 7:16 UTC (permalink / raw) To: Mat Martineau, Paolo Abeni; +Cc: mptcp Hi Paolo, Florian, Mat, On 21/08/2021 01:02, Mat Martineau wrote: > On Fri, 20 Aug 2021, Paolo Abeni wrote: > >> This are couple of changes poped-up while investigating >> issues/219. They does not address the mentioned issue, >> but the first one should fix an actual bug, the other >> is more a cleanup, so the target tree is undefined ;) > > So far my syzkaller setup hasn't seen the div-by-0 again, but it was > typically taking days to show up. I'll leave that running over the weekend. > > Changes look good to me - mptcp_push_release() is now only called from > places where info->mss_now is non-zero. > > Patch 1 for -net, patch 2 for net-next seems appropriate. Thank you for the patches, the suggestions and the reviews! These two patches are now in our tree (net and net-next) with Mat's RvB tag: - 5d8855f6a71f: mptcp: fix possible divide by zero - Results: 84fc11b83a29..653135eedf64 - 33708631c1fd: mptcp: make the locking tx schema more readable - Results: 653135eedf64..ebac4c6745a4 Builds and tests are now in progress: https://cirrus-ci.com/github/multipath-tcp/mptcp_net-next/export/20210823T071618 https://github.com/multipath-tcp/mptcp_net-next/actions/workflows/build-validation.yml?query=branch:export/20210823T071618 Cheers, Matt -- Tessares | Belgium | Hybrid Access Solutions www.tessares.net ^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2021-08-24 7:28 UTC | newest] Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2021-08-20 17:44 [PATCH mptcp 0/2] mptcp: a couple of fix - almost Paolo Abeni 2021-08-20 17:44 ` [PATCH mptcp 1/2] mptcp: fix possible divide by zero Paolo Abeni 2021-08-20 17:53 ` Mat Martineau 2021-08-24 7:28 ` Matthieu Baerts 2021-08-20 17:44 ` [PATCH mptcp 2/2] mptcp: make the locking tx schema more readable Paolo Abeni 2021-08-20 23:02 ` [PATCH mptcp 0/2] mptcp: a couple of fix - almost Mat Martineau 2021-08-23 7:16 ` Matthieu Baerts
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for NNTP newsgroup(s).