All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup
@ 2021-08-31 17:19 Mat Martineau
  2021-08-31 17:19 ` [PATCH net v2 1/2] mptcp: fix possible divide by zero Mat Martineau
                   ` (2 more replies)
  0 siblings, 3 replies; 6+ messages in thread
From: Mat Martineau @ 2021-08-31 17:19 UTC (permalink / raw)
  To: netdev; +Cc: Mat Martineau, davem, kuba, matthieu.baerts, mptcp, pabeni

These are two fixes for the net tree, addressing separate issues.

Patch 1 addresses a divide-by-zero crash seen in syzkaller and also
reported by a user on the netdev list. This changes MPTCP code so
tcp_push() cannot be called with an invalid (0) mss_now value.

Patch 2 fixes a selftest temp file cleanup issue that consumes excessive
disk space when running repeated tests.


v2: Make suggested changes to lockdep check and indentation in patch 1


Matthieu Baerts (1):
  selftests: mptcp: clean tmp files in simult_flows

Paolo Abeni (1):
  mptcp: fix possible divide by zero

 net/mptcp/protocol.c                          | 76 +++++++++----------
 .../selftests/net/mptcp/simult_flows.sh       |  4 +-
 2 files changed, 37 insertions(+), 43 deletions(-)


base-commit: 57f780f1c43362b86fd23d20bd940e2468237716
-- 
2.33.0


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

* [PATCH net v2 1/2] mptcp: fix possible divide by zero
  2021-08-31 17:19 [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup Mat Martineau
@ 2021-08-31 17:19 ` Mat Martineau
  2021-08-31 17:19 ` [PATCH net v2 2/2] selftests: mptcp: clean tmp files in simult_flows Mat Martineau
  2021-09-01 16:09 ` [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup Matthieu Baerts
  2 siblings, 0 replies; 6+ messages in thread
From: Mat Martineau @ 2021-08-31 17:19 UTC (permalink / raw)
  To: netdev
  Cc: Paolo Abeni, davem, kuba, matthieu.baerts, mptcp,
	Florian Westphal, Mat Martineau

From: Paolo Abeni <pabeni@redhat.com>

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 checking if skb collapsing will happen for sure and doing
the skb allocation only after such check. Skb allocation will
now happen only after the call to tcp_send_mss() which
correctly initializes 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.

v1 -> v2:
 - use lockdep_assert_held_once() - Jakub
 - fix indentation - Jakub

Reported-by: Florian Westphal <fw@strlen.de>
Fixes: 724cfd2ee8aa ("mptcp: allocate TX skbs in msk context")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
---
 net/mptcp/protocol.c | 76 ++++++++++++++++++++------------------------
 1 file changed, 35 insertions(+), 41 deletions(-)

diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index a88924947815..c018b591db0b 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -994,6 +994,13 @@ static void mptcp_wmem_uncharge(struct sock *sk, int size)
 	msk->wmem_reserved += size;
 }
 
+static void __mptcp_mem_reclaim_partial(struct sock *sk)
+{
+	lockdep_assert_held_once(&sk->sk_lock.slock);
+	__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);
@@ -1069,12 +1076,8 @@ static void __mptcp_clean_una(struct sock *sk)
 	}
 
 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)) {
 		if (msk->timer_ival && !mptcp_data_fin_enabled(msk))
@@ -1154,6 +1157,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,
@@ -1225,17 +1229,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
@@ -1259,7 +1263,7 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
 	bool zero_window_probe = false;
 	struct mptcp_ext *mpext = NULL;
 	struct sk_buff *skb, *tail;
-	bool can_collapse = false;
+	bool must_collapse = false;
 	int size_bias = 0;
 	int avail_size;
 	size_t ret = 0;
@@ -1279,16 +1283,24 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
 		 * SSN association set here
 		 */
 		mpext = skb_ext_find(skb, SKB_EXT_MPTCP);
-		can_collapse = (info->size_goal - skb->len > 0) &&
-			 mptcp_skb_can_collapse_to(data_seq, skb, mpext);
-		if (!can_collapse) {
+		if (!mptcp_skb_can_collapse_to(data_seq, skb, mpext)) {
 			TCP_SKB_CB(skb)->eor = 1;
-		} else {
+			goto alloc_skb;
+		}
+
+		must_collapse = (info->size_goal - skb->len > 0) &&
+				(skb_shinfo(skb)->nr_frags < sysctl_max_skb_frags);
+		if (must_collapse) {
 			size_bias = skb->len;
 			avail_size = info->size_goal - skb->len;
 		}
 	}
 
+alloc_skb:
+	if (!must_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) {
@@ -1318,7 +1330,6 @@ static int mptcp_sendmsg_frag(struct sock *sk, struct sock *ssk,
 	if (skb == tail) {
 		TCP_SKB_CB(tail)->tcp_flags &= ~TCPHDR_PSH;
 		mpext->data_len += ret;
-		WARN_ON_ONCE(!can_collapse);
 		WARN_ON_ONCE(zero_window_probe);
 		goto out;
 	}
@@ -1470,15 +1481,6 @@ static 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);
@@ -1512,7 +1514,9 @@ static 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;
@@ -1538,13 +1542,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;
@@ -2296,9 +2293,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.33.0


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

* [PATCH net v2 2/2] selftests: mptcp: clean tmp files in simult_flows
  2021-08-31 17:19 [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup Mat Martineau
  2021-08-31 17:19 ` [PATCH net v2 1/2] mptcp: fix possible divide by zero Mat Martineau
@ 2021-08-31 17:19 ` Mat Martineau
  2021-09-01 16:09 ` [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup Matthieu Baerts
  2 siblings, 0 replies; 6+ messages in thread
From: Mat Martineau @ 2021-08-31 17:19 UTC (permalink / raw)
  To: netdev; +Cc: Matthieu Baerts, davem, kuba, mptcp, pabeni, Mat Martineau

From: Matthieu Baerts <matthieu.baerts@tessares.net>

'$cin' and '$sin' variables are local to a function: they are then not
available from the cleanup trap.

Instead, we need to use '$large' and '$small' that are not local and
defined just before setting the trap.

Without this patch, running this script in a loop might cause a:

  write: No space left on device

issue.

Fixes: 1a418cb8e888 ("mptcp: simult flow self-tests")
Acked-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Matthieu Baerts <matthieu.baerts@tessares.net>
Signed-off-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
---
 tools/testing/selftests/net/mptcp/simult_flows.sh | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/tools/testing/selftests/net/mptcp/simult_flows.sh b/tools/testing/selftests/net/mptcp/simult_flows.sh
index fd63ebfe9a2b..910d8126af8f 100755
--- a/tools/testing/selftests/net/mptcp/simult_flows.sh
+++ b/tools/testing/selftests/net/mptcp/simult_flows.sh
@@ -22,8 +22,8 @@ usage() {
 
 cleanup()
 {
-	rm -f "$cin" "$cout"
-	rm -f "$sin" "$sout"
+	rm -f "$cout" "$sout"
+	rm -f "$large" "$small"
 	rm -f "$capout"
 
 	local netns
-- 
2.33.0


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

* Re: [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup
  2021-08-31 17:19 [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup Mat Martineau
  2021-08-31 17:19 ` [PATCH net v2 1/2] mptcp: fix possible divide by zero Mat Martineau
  2021-08-31 17:19 ` [PATCH net v2 2/2] selftests: mptcp: clean tmp files in simult_flows Mat Martineau
@ 2021-09-01 16:09 ` Matthieu Baerts
  2021-09-01 17:16   ` Jakub Kicinski
  2 siblings, 1 reply; 6+ messages in thread
From: Matthieu Baerts @ 2021-09-01 16:09 UTC (permalink / raw)
  To: David S. Miller, Jakub Kicinski; +Cc: mptcp, Mat Martineau, netdev, Paolo Abeni

Hi David, Jakub,

On 31/08/2021 19:19, Mat Martineau wrote:
> These are two fixes for the net tree, addressing separate issues.
> 
> Patch 1 addresses a divide-by-zero crash seen in syzkaller and also
> reported by a user on the netdev list. This changes MPTCP code so
> tcp_push() cannot be called with an invalid (0) mss_now value.
> 
> Patch 2 fixes a selftest temp file cleanup issue that consumes excessive
> disk space when running repeated tests.
> 
> 
> v2: Make suggested changes to lockdep check and indentation in patch 1

We recently noticed this series has been marked as "Not Applicable" on
Patchwork.

It looks like we can apply these patches:

  $ git checkout netdev-net/master # 780aa1209f88
  $ git-pw series apply 539963
  Applying: mptcp: fix possible divide by zero
  Using index info to reconstruct a base tree...
  M       net/mptcp/protocol.c

  Falling back to patching base and 3-way merge...
  Auto-merging net/mptcp/protocol.c

  Applying: selftests: mptcp: clean tmp files in simult_flows

Git auto-resolves conflicts. Is it why it is considered as "Not
Applicable" or did we miss something else?

Do we just need to resend these patches after a rebase?

Thank you for maintaining net!

Cheers,
Matt
-- 
Tessares | Belgium | Hybrid Access Solutions
www.tessares.net

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

* Re: [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup
  2021-09-01 16:09 ` [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup Matthieu Baerts
@ 2021-09-01 17:16   ` Jakub Kicinski
  2021-09-01 17:19     ` Matthieu Baerts
  0 siblings, 1 reply; 6+ messages in thread
From: Jakub Kicinski @ 2021-09-01 17:16 UTC (permalink / raw)
  To: Matthieu Baerts
  Cc: David S. Miller, mptcp, Mat Martineau, netdev, Paolo Abeni

On Wed, 1 Sep 2021 18:09:52 +0200 Matthieu Baerts wrote:
> Hi David, Jakub,
> 
> On 31/08/2021 19:19, Mat Martineau wrote:
> > These are two fixes for the net tree, addressing separate issues.
> > 
> > Patch 1 addresses a divide-by-zero crash seen in syzkaller and also
> > reported by a user on the netdev list. This changes MPTCP code so
> > tcp_push() cannot be called with an invalid (0) mss_now value.
> > 
> > Patch 2 fixes a selftest temp file cleanup issue that consumes excessive
> > disk space when running repeated tests.
> > 
> > 
> > v2: Make suggested changes to lockdep check and indentation in patch 1  
> 
> We recently noticed this series has been marked as "Not Applicable" on
> Patchwork.
> 
> It looks like we can apply these patches:
> 
>   $ git checkout netdev-net/master # 780aa1209f88
>   $ git-pw series apply 539963
>   Applying: mptcp: fix possible divide by zero
>   Using index info to reconstruct a base tree...
>   M       net/mptcp/protocol.c
> 
>   Falling back to patching base and 3-way merge...
>   Auto-merging net/mptcp/protocol.c
> 
>   Applying: selftests: mptcp: clean tmp files in simult_flows
> 
> Git auto-resolves conflicts. Is it why it is considered as "Not
> Applicable" or did we miss something else?

We don't enable 3-way merges for patches applied from the list, usually.

> Do we just need to resend these patches after a rebase?

Yes please.

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

* Re: [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup
  2021-09-01 17:16   ` Jakub Kicinski
@ 2021-09-01 17:19     ` Matthieu Baerts
  0 siblings, 0 replies; 6+ messages in thread
From: Matthieu Baerts @ 2021-09-01 17:19 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: David S. Miller, mptcp, Mat Martineau, netdev, Paolo Abeni

Hi Jakub,

On 01/09/2021 19:16, Jakub Kicinski wrote:
> On Wed, 1 Sep 2021 18:09:52 +0200 Matthieu Baerts wrote:
>> Git auto-resolves conflicts. Is it why it is considered as "Not
>> Applicable" or did we miss something else?
> 
> We don't enable 3-way merges for patches applied from the list, usually.

Thank you for your reply, we didn't know that, that's clearer!

>> Do we just need to resend these patches after a rebase?
> 
> Yes please.

Just did, thank you!

Cheers,
Matt
-- 
Tessares | Belgium | Hybrid Access Solutions
www.tessares.net

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

end of thread, other threads:[~2021-09-01 17:19 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-08-31 17:19 [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup Mat Martineau
2021-08-31 17:19 ` [PATCH net v2 1/2] mptcp: fix possible divide by zero Mat Martineau
2021-08-31 17:19 ` [PATCH net v2 2/2] selftests: mptcp: clean tmp files in simult_flows Mat Martineau
2021-09-01 16:09 ` [PATCH net v2 0/2] mptcp: Prevent tcp_push() crash and selftest temp file buildup Matthieu Baerts
2021-09-01 17:16   ` Jakub Kicinski
2021-09-01 17:19     ` Matthieu Baerts

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.