]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.14
authorSasha Levin <sashal@kernel.org>
Sat, 9 Dec 2023 02:37:02 +0000 (21:37 -0500)
committerSasha Levin <sashal@kernel.org>
Sat, 9 Dec 2023 02:37:02 +0000 (21:37 -0500)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.14/net-hns-fix-fake-link-up-on-xge-port.patch [new file with mode: 0644]
queue-4.14/series
queue-4.14/tcp-do-not-accept-ack-of-bytes-we-never-sent.patch [new file with mode: 0644]

diff --git a/queue-4.14/net-hns-fix-fake-link-up-on-xge-port.patch b/queue-4.14/net-hns-fix-fake-link-up-on-xge-port.patch
new file mode 100644 (file)
index 0000000..29a621f
--- /dev/null
@@ -0,0 +1,74 @@
+From 54b6595a28e0af1a4a89914aa820854aa4f740fd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 4 Dec 2023 22:32:32 +0800
+Subject: net: hns: fix fake link up on xge port
+
+From: Yonglong Liu <liuyonglong@huawei.com>
+
+[ Upstream commit f708aba40f9c1eeb9c7e93ed4863b5f85b09b288 ]
+
+If a xge port just connect with an optical module and no fiber,
+it may have a fake link up because there may be interference on
+the hardware. This patch adds an anti-shake to avoid the problem.
+And the time of anti-shake is base on tests.
+
+Fixes: b917078c1c10 ("net: hns: Add ACPI support to check SFP present")
+Signed-off-by: Yonglong Liu <liuyonglong@huawei.com>
+Signed-off-by: Jijie Shao <shaojijie@huawei.com>
+Reviewed-by: Wojciech Drewek <wojciech.drewek@intel.com>
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ .../net/ethernet/hisilicon/hns/hns_dsaf_mac.c | 29 +++++++++++++++++++
+ 1 file changed, 29 insertions(+)
+
+diff --git a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+index 07e117deeb0f3..e5fbb5119f405 100644
+--- a/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
++++ b/drivers/net/ethernet/hisilicon/hns/hns_dsaf_mac.c
+@@ -70,6 +70,27 @@ static enum mac_mode hns_get_enet_interface(const struct hns_mac_cb *mac_cb)
+       }
+ }
++static u32 hns_mac_link_anti_shake(struct mac_driver *mac_ctrl_drv)
++{
++#define HNS_MAC_LINK_WAIT_TIME 5
++#define HNS_MAC_LINK_WAIT_CNT 40
++
++      u32 link_status = 0;
++      int i;
++
++      if (!mac_ctrl_drv->get_link_status)
++              return link_status;
++
++      for (i = 0; i < HNS_MAC_LINK_WAIT_CNT; i++) {
++              msleep(HNS_MAC_LINK_WAIT_TIME);
++              mac_ctrl_drv->get_link_status(mac_ctrl_drv, &link_status);
++              if (!link_status)
++                      break;
++      }
++
++      return link_status;
++}
++
+ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status)
+ {
+       struct mac_driver *mac_ctrl_drv;
+@@ -87,6 +108,14 @@ void hns_mac_get_link_status(struct hns_mac_cb *mac_cb, u32 *link_status)
+                                                              &sfp_prsnt);
+               if (!ret)
+                       *link_status = *link_status && sfp_prsnt;
++
++              /* for FIBER port, it may have a fake link up.
++               * when the link status changes from down to up, we need to do
++               * anti-shake. the anti-shake time is base on tests.
++               * only FIBER port need to do this.
++               */
++              if (*link_status && !mac_cb->link)
++                      *link_status = hns_mac_link_anti_shake(mac_ctrl_drv);
+       }
+       mac_cb->link = *link_status;
+-- 
+2.42.0
+
index 9bb47917868aa825b01666e965de4162e5dc258d..7baba6b829dbd312040b42ca8d401662d41dd131 100644 (file)
@@ -1,3 +1,5 @@
 tg3-move-the-rt-x_dropped-counters-to-tg3_napi.patch
 tg3-increment-tx_dropped-in-tg3_tso_bug.patch
 drm-amdgpu-correct-chunk_ptr-to-a-pointer-to-chunk.patch
+net-hns-fix-fake-link-up-on-xge-port.patch
+tcp-do-not-accept-ack-of-bytes-we-never-sent.patch
diff --git a/queue-4.14/tcp-do-not-accept-ack-of-bytes-we-never-sent.patch b/queue-4.14/tcp-do-not-accept-ack-of-bytes-we-never-sent.patch
new file mode 100644 (file)
index 0000000..15fe7ff
--- /dev/null
@@ -0,0 +1,106 @@
+From 933bae48f20a7bd8e7936ddd35b78396ca0e48fe Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Dec 2023 16:18:41 +0000
+Subject: tcp: do not accept ACK of bytes we never sent
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 3d501dd326fb1c73f1b8206d4c6e1d7b15c07e27 ]
+
+This patch is based on a detailed report and ideas from Yepeng Pan
+and Christian Rossow.
+
+ACK seq validation is currently following RFC 5961 5.2 guidelines:
+
+   The ACK value is considered acceptable only if
+   it is in the range of ((SND.UNA - MAX.SND.WND) <= SEG.ACK <=
+   SND.NXT).  All incoming segments whose ACK value doesn't satisfy the
+   above condition MUST be discarded and an ACK sent back.  It needs to
+   be noted that RFC 793 on page 72 (fifth check) says: "If the ACK is a
+   duplicate (SEG.ACK < SND.UNA), it can be ignored.  If the ACK
+   acknowledges something not yet sent (SEG.ACK > SND.NXT) then send an
+   ACK, drop the segment, and return".  The "ignored" above implies that
+   the processing of the incoming data segment continues, which means
+   the ACK value is treated as acceptable.  This mitigation makes the
+   ACK check more stringent since any ACK < SND.UNA wouldn't be
+   accepted, instead only ACKs that are in the range ((SND.UNA -
+   MAX.SND.WND) <= SEG.ACK <= SND.NXT) get through.
+
+This can be refined for new (and possibly spoofed) flows,
+by not accepting ACK for bytes that were never sent.
+
+This greatly improves TCP security at a little cost.
+
+I added a Fixes: tag to make sure this patch will reach stable trees,
+even if the 'blamed' patch was adhering to the RFC.
+
+tp->bytes_acked was added in linux-4.2
+
+Following packetdrill test (courtesy of Yepeng Pan) shows
+the issue at hand:
+
+0 socket(..., SOCK_STREAM, IPPROTO_TCP) = 3
++0 setsockopt(3, SOL_SOCKET, SO_REUSEADDR, [1], 4) = 0
++0 bind(3, ..., ...) = 0
++0 listen(3, 1024) = 0
+
+// ---------------- Handshake ------------------- //
+
+// when window scale is set to 14 the window size can be extended to
+// 65535 * (2^14) = 1073725440. Linux would accept an ACK packet
+// with ack number in (Server_ISN+1-1073725440. Server_ISN+1)
+// ,though this ack number acknowledges some data never
+// sent by the server.
+
++0 < S 0:0(0) win 65535 <mss 1400,nop,wscale 14>
++0 > S. 0:0(0) ack 1 <...>
++0 < . 1:1(0) ack 1 win 65535
++0 accept(3, ..., ...) = 4
+
+// For the established connection, we send an ACK packet,
+// the ack packet uses ack number 1 - 1073725300 + 2^32,
+// where 2^32 is used to wrap around.
+// Note: we used 1073725300 instead of 1073725440 to avoid possible
+// edge cases.
+// 1 - 1073725300 + 2^32 = 3221241997
+
+// Oops, old kernels happily accept this packet.
++0 < . 1:1001(1000) ack 3221241997 win 65535
+
+// After the kernel fix the following will be replaced by a challenge ACK,
+// and prior malicious frame would be dropped.
++0 > . 1:1(0) ack 1001
+
+Fixes: 354e4aa391ed ("tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation")
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Reported-by: Yepeng Pan <yepeng.pan@cispa.de>
+Reported-by: Christian Rossow <rossow@cispa.de>
+Acked-by: Neal Cardwell <ncardwell@google.com>
+Link: https://lore.kernel.org/r/20231205161841.2702925-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index e65daf71a52d7..a83b2457ad5fe 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -3643,8 +3643,12 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
+        * then we can probably ignore it.
+        */
+       if (before(ack, prior_snd_una)) {
++              u32 max_window;
++
++              /* do not accept ACK for bytes we never sent. */
++              max_window = min_t(u64, tp->max_window, tp->bytes_acked);
+               /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */
+-              if (before(ack, prior_snd_una - tp->max_window)) {
++              if (before(ack, prior_snd_una - max_window)) {
+                       if (!(flag & FLAG_NO_CHALLENGE_ACK))
+                               tcp_send_challenge_ack(sk, skb);
+                       return -1;
+-- 
+2.42.0
+