]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.19-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Feb 2022 18:07:33 +0000 (19:07 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 3 Feb 2022 18:07:33 +0000 (19:07 +0100)
added patches:
tcp-fix-possible-socket-leaks-in-internal-pacing-mode.patch

queue-4.19/series
queue-4.19/tcp-fix-possible-socket-leaks-in-internal-pacing-mode.patch [new file with mode: 0644]

index dc2ea36fc40e466c28d941dda614c46153500e17..f035102131d412e3453e0f3df4b0275987c20bb3 100644 (file)
@@ -45,3 +45,4 @@ ipv4-raw-lock-the-socket-in-raw_bind.patch
 ipv4-tcp-send-zero-ipid-in-synack-messages.patch
 netfilter-nat-remove-l4-protocol-port-rovers.patch
 netfilter-nat-limit-port-clash-resolution-attempts.patch
+tcp-fix-possible-socket-leaks-in-internal-pacing-mode.patch
diff --git a/queue-4.19/tcp-fix-possible-socket-leaks-in-internal-pacing-mode.patch b/queue-4.19/tcp-fix-possible-socket-leaks-in-internal-pacing-mode.patch
new file mode 100644 (file)
index 0000000..9938a82
--- /dev/null
@@ -0,0 +1,104 @@
+From eric.dumazet@gmail.com  Thu Feb  3 18:59:23 2022
+From: Eric Dumazet <eric.dumazet@gmail.com>
+Date: Mon, 31 Jan 2022 10:26:03 -0800
+Subject: tcp: fix possible socket leaks in internal pacing mode
+To: "David S . Miller" <davem@davemloft.net>, Jakub Kicinski <kuba@kernel.org>
+Cc: netdev <netdev@vger.kernel.org>, Eric Dumazet <edumazet@google.com>, Eric Dumazet <eric.dumazet@gmail.com>, Jason Xing <kerneljasonxing@gmail.com>, Zhang Changzhong <zhangchangzhong@huawei.com>, liweishi <liweishi@kuaishou.com>, Shujin Li <lishujin@kuaishou.com>, Neal Cardwell <ncardwell@google.com>, Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+Message-ID: <20220131182603.3804056-1-eric.dumazet@gmail.com>
+
+
+From: Eric Dumazet <edumazet@google.com>
+
+This patch is addressing an issue in stable linux-4.19 only.
+
+In linux-4.20, TCP stack adopted EDT (Earliest Departure
+Time) model and this issue was incidentally fixed.
+
+Issue at hand was an extra sock_hold() from tcp_internal_pacing()
+in paths not using tcp_xmit_retransmit_queue()
+
+Jason Xing reported this leak and provided a patch stopping
+the extra sock_hold() to happen.
+
+This patch is more complete and makes sure to avoid
+unnecessary extra delays, by reprogramming the high
+resolution timer.
+
+Fixes: 73a6bab5aa2a ("tcp: switch pacing timer to softirq based hrtimer")
+Reference: https://lore.kernel.org/all/CANn89i+7-wE4xr5D9DpH+N-xkL1SB8oVghCKgz+CT5eG1ODQhA@mail.gmail.com/
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Jason Xing <kerneljasonxing@gmail.com>
+Reported-by: Zhang Changzhong <zhangchangzhong@huawei.com>
+Cc: liweishi <liweishi@kuaishou.com>
+Cc: Shujin Li <lishujin@kuaishou.com>
+Cc: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/ipv4/tcp_output.c |   31 +++++++++++++++++++++++--------
+ 1 file changed, 23 insertions(+), 8 deletions(-)
+
+--- a/net/ipv4/tcp_output.c
++++ b/net/ipv4/tcp_output.c
+@@ -968,6 +968,8 @@ enum hrtimer_restart tcp_pace_kick(struc
+ static void tcp_internal_pacing(struct sock *sk, const struct sk_buff *skb)
+ {
++      struct tcp_sock *tp = tcp_sk(sk);
++      ktime_t expire, now;
+       u64 len_ns;
+       u32 rate;
+@@ -979,12 +981,28 @@ static void tcp_internal_pacing(struct s
+       len_ns = (u64)skb->len * NSEC_PER_SEC;
+       do_div(len_ns, rate);
+-      hrtimer_start(&tcp_sk(sk)->pacing_timer,
+-                    ktime_add_ns(ktime_get(), len_ns),
++      now = ktime_get();
++      /* If hrtimer is already armed, then our caller has not
++       * used tcp_pacing_check().
++       */
++      if (unlikely(hrtimer_is_queued(&tp->pacing_timer))) {
++              expire = hrtimer_get_softexpires(&tp->pacing_timer);
++              if (ktime_after(expire, now))
++                      now = expire;
++              if (hrtimer_try_to_cancel(&tp->pacing_timer) == 1)
++                      __sock_put(sk);
++      }
++      hrtimer_start(&tp->pacing_timer, ktime_add_ns(now, len_ns),
+                     HRTIMER_MODE_ABS_PINNED_SOFT);
+       sock_hold(sk);
+ }
++static bool tcp_pacing_check(const struct sock *sk)
++{
++      return tcp_needs_internal_pacing(sk) &&
++             hrtimer_is_queued(&tcp_sk(sk)->pacing_timer);
++}
++
+ static void tcp_update_skb_after_send(struct tcp_sock *tp, struct sk_buff *skb)
+ {
+       skb->skb_mstamp = tp->tcp_mstamp;
+@@ -2121,6 +2139,9 @@ static int tcp_mtu_probe(struct sock *sk
+       if (!tcp_can_coalesce_send_queue_head(sk, probe_size))
+               return -1;
++      if (tcp_pacing_check(sk))
++              return -1;
++
+       /* We're allowed to probe.  Build it now. */
+       nskb = sk_stream_alloc_skb(sk, probe_size, GFP_ATOMIC, false);
+       if (!nskb)
+@@ -2194,12 +2215,6 @@ static int tcp_mtu_probe(struct sock *sk
+       return -1;
+ }
+-static bool tcp_pacing_check(const struct sock *sk)
+-{
+-      return tcp_needs_internal_pacing(sk) &&
+-             hrtimer_is_queued(&tcp_sk(sk)->pacing_timer);
+-}
+-
+ /* TCP Small Queues :
+  * Control number of packets in qdisc/devices to two packets / or ~1 ms.
+  * (These limits are doubled for retransmits)