]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 5.4
authorSasha Levin <sashal@kernel.org>
Sat, 10 Sep 2022 23:50:46 +0000 (19:50 -0400)
committerSasha Levin <sashal@kernel.org>
Sat, 10 Sep 2022 23:50:46 +0000 (19:50 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
19 files changed:
queue-5.4/afs-use-the-operation-issue-time-instead-of-the-repl.patch [new file with mode: 0644]
queue-5.4/arm-dts-imx6qdl-kontron-samx6i-remove-duplicated-nod.patch [new file with mode: 0644]
queue-5.4/i40e-fix-kernel-crash-during-module-removal.patch [new file with mode: 0644]
queue-5.4/ipv6-sr-fix-out-of-bounds-read-when-setting-hmac-dat.patch [new file with mode: 0644]
queue-5.4/netfilter-br_netfilter-drop-dst-references-before-se.patch [new file with mode: 0644]
queue-5.4/netfilter-nf_conntrack_irc-fix-forged-ip-logic.patch [new file with mode: 0644]
queue-5.4/nvme-tcp-fix-uaf-when-detecting-digest-errors.patch [new file with mode: 0644]
queue-5.4/rdma-cma-fix-arguments-order-in-net-device-validatio.patch [new file with mode: 0644]
queue-5.4/rdma-hns-fix-supported-page-size.patch [new file with mode: 0644]
queue-5.4/rdma-mlx5-set-local-port-to-one-when-accessing-count.patch [new file with mode: 0644]
queue-5.4/rdma-siw-pass-a-pointer-to-virt_to_page.patch [new file with mode: 0644]
queue-5.4/regulator-core-clean-up-on-enable-failure.patch [new file with mode: 0644]
queue-5.4/rxrpc-fix-an-insufficiently-large-sglist-in-rxkad_ve.patch [new file with mode: 0644]
queue-5.4/sch_sfb-also-store-skb-len-before-calling-child-enqu.patch [new file with mode: 0644]
queue-5.4/sch_sfb-don-t-assume-the-skb-is-still-around-after-e.patch [new file with mode: 0644]
queue-5.4/series
queue-5.4/soc-brcmstb-pm-arm-fix-refcount-leak-and-__iomem-lea.patch [new file with mode: 0644]
queue-5.4/tcp-fix-early-etimedout-after-spurious-non-sack-rto.patch [new file with mode: 0644]
queue-5.4/tipc-fix-shift-wrapping-bug-in-map_get.patch [new file with mode: 0644]

diff --git a/queue-5.4/afs-use-the-operation-issue-time-instead-of-the-repl.patch b/queue-5.4/afs-use-the-operation-issue-time-instead-of-the-repl.patch
new file mode 100644 (file)
index 0000000..c4c26fc
--- /dev/null
@@ -0,0 +1,125 @@
+From decc4ca6fdf4c02d12ee1a5f690dca07cbb6b686 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Aug 2022 13:16:42 +0100
+Subject: afs: Use the operation issue time instead of the reply time for
+ callbacks
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 7903192c4b4a82d792cb0dc5e2779a2efe60d45b ]
+
+rxrpc and kafs between them try to use the receive timestamp on the first
+data packet (ie. the one with sequence number 1) as a base from which to
+calculate the time at which callback promise and lock expiration occurs.
+
+However, we don't know how long it took for the server to send us the reply
+from it having completed the basic part of the operation - it might then,
+for instance, have to send a bunch of a callback breaks, depending on the
+particular operation.
+
+Fix this by using the time at which the operation is issued on the client
+as a base instead.  That should never be longer than the server's idea of
+the expiry time.
+
+Fixes: 781070551c26 ("afs: Fix calculation of callback expiry time")
+Fixes: 2070a3e44962 ("rxrpc: Allow the reply time to be obtained on a client call")
+Suggested-by: Jeffrey E Altman <jaltman@auristor.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ fs/afs/flock.c     | 2 +-
+ fs/afs/fsclient.c  | 2 +-
+ fs/afs/internal.h  | 3 +--
+ fs/afs/rxrpc.c     | 7 +------
+ fs/afs/yfsclient.c | 3 +--
+ 5 files changed, 5 insertions(+), 12 deletions(-)
+
+diff --git a/fs/afs/flock.c b/fs/afs/flock.c
+index d5e5a6ddc8478..0fa05998a24d2 100644
+--- a/fs/afs/flock.c
++++ b/fs/afs/flock.c
+@@ -75,7 +75,7 @@ void afs_lock_op_done(struct afs_call *call)
+       if (call->error == 0) {
+               spin_lock(&vnode->lock);
+               trace_afs_flock_ev(vnode, NULL, afs_flock_timestamp, 0);
+-              vnode->locked_at = call->reply_time;
++              vnode->locked_at = call->issue_time;
+               afs_schedule_lock_extension(vnode);
+               spin_unlock(&vnode->lock);
+       }
+diff --git a/fs/afs/fsclient.c b/fs/afs/fsclient.c
+index 5c2729fc07e52..254580b1dc74c 100644
+--- a/fs/afs/fsclient.c
++++ b/fs/afs/fsclient.c
+@@ -136,7 +136,7 @@ static void xdr_decode_AFSFetchStatus(const __be32 **_bp,
+ static time64_t xdr_decode_expiry(struct afs_call *call, u32 expiry)
+ {
+-      return ktime_divns(call->reply_time, NSEC_PER_SEC) + expiry;
++      return ktime_divns(call->issue_time, NSEC_PER_SEC) + expiry;
+ }
+ static void xdr_decode_AFSCallBack(const __be32 **_bp,
+diff --git a/fs/afs/internal.h b/fs/afs/internal.h
+index c3ad582f9fd0e..8d6582713fe72 100644
+--- a/fs/afs/internal.h
++++ b/fs/afs/internal.h
+@@ -159,7 +159,6 @@ struct afs_call {
+       bool                    need_attention; /* T if RxRPC poked us */
+       bool                    async;          /* T if asynchronous */
+       bool                    upgrade;        /* T to request service upgrade */
+-      bool                    have_reply_time; /* T if have got reply_time */
+       bool                    intr;           /* T if interruptible */
+       bool                    unmarshalling_error; /* T if an unmarshalling error occurred */
+       u16                     service_id;     /* Actual service ID (after upgrade) */
+@@ -173,7 +172,7 @@ struct afs_call {
+               } __attribute__((packed));
+               __be64          tmp64;
+       };
+-      ktime_t                 reply_time;     /* Time of first reply packet */
++      ktime_t                 issue_time;     /* Time of issue of operation */
+ };
+ struct afs_call_type {
+diff --git a/fs/afs/rxrpc.c b/fs/afs/rxrpc.c
+index 6adab30a83993..49fcce6529a60 100644
+--- a/fs/afs/rxrpc.c
++++ b/fs/afs/rxrpc.c
+@@ -428,6 +428,7 @@ void afs_make_call(struct afs_addr_cursor *ac, struct afs_call *call, gfp_t gfp)
+       if (call->max_lifespan)
+               rxrpc_kernel_set_max_life(call->net->socket, rxcall,
+                                         call->max_lifespan);
++      call->issue_time = ktime_get_real();
+       /* send the request */
+       iov[0].iov_base = call->request;
+@@ -532,12 +533,6 @@ static void afs_deliver_to_call(struct afs_call *call)
+                       return;
+               }
+-              if (!call->have_reply_time &&
+-                  rxrpc_kernel_get_reply_time(call->net->socket,
+-                                              call->rxcall,
+-                                              &call->reply_time))
+-                      call->have_reply_time = true;
+-
+               ret = call->type->deliver(call);
+               state = READ_ONCE(call->state);
+               if (ret == 0 && call->unmarshalling_error)
+diff --git a/fs/afs/yfsclient.c b/fs/afs/yfsclient.c
+index 3b19b009452a2..fa85b359f325b 100644
+--- a/fs/afs/yfsclient.c
++++ b/fs/afs/yfsclient.c
+@@ -241,8 +241,7 @@ static void xdr_decode_YFSCallBack(const __be32 **_bp,
+       struct afs_callback *cb = &scb->callback;
+       ktime_t cb_expiry;
+-      cb_expiry = call->reply_time;
+-      cb_expiry = ktime_add(cb_expiry, xdr_to_u64(x->expiration_time) * 100);
++      cb_expiry = ktime_add(call->issue_time, xdr_to_u64(x->expiration_time) * 100);
+       cb->expires_at  = ktime_divns(cb_expiry, NSEC_PER_SEC);
+       scb->have_cb    = true;
+       *_bp += xdr_size(x);
+-- 
+2.35.1
+
diff --git a/queue-5.4/arm-dts-imx6qdl-kontron-samx6i-remove-duplicated-nod.patch b/queue-5.4/arm-dts-imx6qdl-kontron-samx6i-remove-duplicated-nod.patch
new file mode 100644 (file)
index 0000000..d2ec961
--- /dev/null
@@ -0,0 +1,44 @@
+From 17cf8476b1d14d2e27588129937727e0c9030479 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 26 Jul 2022 15:05:21 +0200
+Subject: ARM: dts: imx6qdl-kontron-samx6i: remove duplicated node
+
+From: Marco Felsch <m.felsch@pengutronix.de>
+
+[ Upstream commit 204f67d86f55dd4fa757ed04757d7273f71a169c ]
+
+The regulator node 'regulator-3p3v-s0' was dupplicated. Remove it to
+clean the DTS.
+
+Fixes: 2a51f9dae13d ("ARM: dts: imx6qdl-kontron-samx6i: Add iMX6-based Kontron SMARC-sAMX6i module")
+Signed-off-by: Marco Felsch <m.felsch@pengutronix.de>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi | 10 ----------
+ 1 file changed, 10 deletions(-)
+
+diff --git a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi
+index eea317b41020d..5e454a694b78a 100644
+--- a/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi
++++ b/arch/arm/boot/dts/imx6qdl-kontron-samx6i.dtsi
+@@ -51,16 +51,6 @@
+               vin-supply = <&reg_3p3v_s5>;
+       };
+-      reg_3p3v_s0: regulator-3p3v-s0 {
+-              compatible = "regulator-fixed";
+-              regulator-name = "V_3V3_S0";
+-              regulator-min-microvolt = <3300000>;
+-              regulator-max-microvolt = <3300000>;
+-              regulator-always-on;
+-              regulator-boot-on;
+-              vin-supply = <&reg_3p3v_s5>;
+-      };
+-
+       reg_3p3v_s5: regulator-3p3v-s5 {
+               compatible = "regulator-fixed";
+               regulator-name = "V_3V3_S5";
+-- 
+2.35.1
+
diff --git a/queue-5.4/i40e-fix-kernel-crash-during-module-removal.patch b/queue-5.4/i40e-fix-kernel-crash-during-module-removal.patch
new file mode 100644 (file)
index 0000000..b220627
--- /dev/null
@@ -0,0 +1,106 @@
+From 5b784530727826bde63fa60c449774d85f5bb53f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 16 Aug 2022 18:22:30 +0200
+Subject: i40e: Fix kernel crash during module removal
+
+From: Ivan Vecera <ivecera@redhat.com>
+
+[ Upstream commit fb8396aeda5872369a8ed6d2301e2c86e303c520 ]
+
+The driver incorrectly frees client instance and subsequent
+i40e module removal leads to kernel crash.
+
+Reproducer:
+1. Do ethtool offline test followed immediately by another one
+host# ethtool -t eth0 offline; ethtool -t eth0 offline
+2. Remove recursively irdma module that also removes i40e module
+host# modprobe -r irdma
+
+Result:
+[ 8675.035651] i40e 0000:3d:00.0 eno1: offline testing starting
+[ 8675.193774] i40e 0000:3d:00.0 eno1: testing finished
+[ 8675.201316] i40e 0000:3d:00.0 eno1: offline testing starting
+[ 8675.358921] i40e 0000:3d:00.0 eno1: testing finished
+[ 8675.496921] i40e 0000:3d:00.0: IRDMA hardware initialization FAILED init_state=2 status=-110
+[ 8686.188955] i40e 0000:3d:00.1: i40e_ptp_stop: removed PHC on eno2
+[ 8686.943890] i40e 0000:3d:00.1: Deleted LAN device PF1 bus=0x3d dev=0x00 func=0x01
+[ 8686.952669] i40e 0000:3d:00.0: i40e_ptp_stop: removed PHC on eno1
+[ 8687.761787] BUG: kernel NULL pointer dereference, address: 0000000000000030
+[ 8687.768755] #PF: supervisor read access in kernel mode
+[ 8687.773895] #PF: error_code(0x0000) - not-present page
+[ 8687.779034] PGD 0 P4D 0
+[ 8687.781575] Oops: 0000 [#1] PREEMPT SMP NOPTI
+[ 8687.785935] CPU: 51 PID: 172891 Comm: rmmod Kdump: loaded Tainted: G        W I        5.19.0+ #2
+[ 8687.794800] Hardware name: Intel Corporation S2600WFD/S2600WFD, BIOS SE5C620.86B.0X.02.0001.051420190324 05/14/2019
+[ 8687.805222] RIP: 0010:i40e_lan_del_device+0x13/0xb0 [i40e]
+[ 8687.810719] Code: d4 84 c0 0f 84 b8 25 01 00 e9 9c 25 01 00 41 bc f4 ff ff ff eb 91 90 0f 1f 44 00 00 41 54 55 53 48 8b 87 58 08 00 00 48 89 fb <48> 8b 68 30 48 89 ef e8 21 8a 0f d5 48 89 ef e8 a9 78 0f d5 48 8b
+[ 8687.829462] RSP: 0018:ffffa604072efce0 EFLAGS: 00010202
+[ 8687.834689] RAX: 0000000000000000 RBX: ffff8f43833b2000 RCX: 0000000000000000
+[ 8687.841821] RDX: 0000000000000000 RSI: ffff8f4b0545b298 RDI: ffff8f43833b2000
+[ 8687.848955] RBP: ffff8f43833b2000 R08: 0000000000000001 R09: 0000000000000000
+[ 8687.856086] R10: 0000000000000000 R11: 000ffffffffff000 R12: ffff8f43833b2ef0
+[ 8687.863218] R13: ffff8f43833b2ef0 R14: ffff915103966000 R15: ffff8f43833b2008
+[ 8687.870342] FS:  00007f79501c3740(0000) GS:ffff8f4adffc0000(0000) knlGS:0000000000000000
+[ 8687.878427] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
+[ 8687.884174] CR2: 0000000000000030 CR3: 000000014276e004 CR4: 00000000007706e0
+[ 8687.891306] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000
+[ 8687.898441] DR3: 0000000000000000 DR6: 00000000fffe0ff0 DR7: 0000000000000400
+[ 8687.905572] PKRU: 55555554
+[ 8687.908286] Call Trace:
+[ 8687.910737]  <TASK>
+[ 8687.912843]  i40e_remove+0x2c0/0x330 [i40e]
+[ 8687.917040]  pci_device_remove+0x33/0xa0
+[ 8687.920962]  device_release_driver_internal+0x1aa/0x230
+[ 8687.926188]  driver_detach+0x44/0x90
+[ 8687.929770]  bus_remove_driver+0x55/0xe0
+[ 8687.933693]  pci_unregister_driver+0x2a/0xb0
+[ 8687.937967]  i40e_exit_module+0xc/0xf48 [i40e]
+
+Two offline tests cause IRDMA driver failure (ETIMEDOUT) and this
+failure is indicated back to i40e_client_subtask() that calls
+i40e_client_del_instance() to free client instance referenced
+by pf->cinst and sets this pointer to NULL. During the module
+removal i40e_remove() calls i40e_lan_del_device() that dereferences
+pf->cinst that is NULL -> crash.
+Do not remove client instance when client open callbacks fails and
+just clear __I40E_CLIENT_INSTANCE_OPENED bit. The driver also needs
+to take care about this situation (when netdev is up and client
+is NOT opened) in i40e_notify_client_of_netdev_close() and
+calls client close callback only when __I40E_CLIENT_INSTANCE_OPENED
+is set.
+
+Fixes: 0ef2d5afb12d ("i40e: KISS the client interface")
+Signed-off-by: Ivan Vecera <ivecera@redhat.com>
+Tested-by: Helena Anna Dubel <helena.anna.dubel@intel.com>
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/i40e/i40e_client.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/drivers/net/ethernet/intel/i40e/i40e_client.c b/drivers/net/ethernet/intel/i40e/i40e_client.c
+index 5706abb3c0eaa..10125b02d1543 100644
+--- a/drivers/net/ethernet/intel/i40e/i40e_client.c
++++ b/drivers/net/ethernet/intel/i40e/i40e_client.c
+@@ -178,6 +178,10 @@ void i40e_notify_client_of_netdev_close(struct i40e_vsi *vsi, bool reset)
+                       "Cannot locate client instance close routine\n");
+               return;
+       }
++      if (!test_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state)) {
++              dev_dbg(&pf->pdev->dev, "Client is not open, abort close\n");
++              return;
++      }
+       cdev->client->ops->close(&cdev->lan_info, cdev->client, reset);
+       clear_bit(__I40E_CLIENT_INSTANCE_OPENED, &cdev->state);
+       i40e_client_release_qvlist(&cdev->lan_info);
+@@ -376,7 +380,6 @@ void i40e_client_subtask(struct i40e_pf *pf)
+                               /* Remove failed client instance */
+                               clear_bit(__I40E_CLIENT_INSTANCE_OPENED,
+                                         &cdev->state);
+-                              i40e_client_del_instance(pf);
+                               return;
+                       }
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.4/ipv6-sr-fix-out-of-bounds-read-when-setting-hmac-dat.patch b/queue-5.4/ipv6-sr-fix-out-of-bounds-read-when-setting-hmac-dat.patch
new file mode 100644 (file)
index 0000000..257ab99
--- /dev/null
@@ -0,0 +1,78 @@
+From 3370a74823afb22dc0a0709d8d7427a07aefb477 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Sep 2022 10:45:06 +0100
+Subject: ipv6: sr: fix out-of-bounds read when setting HMAC data.
+
+From: David Lebrun <dlebrun@google.com>
+
+[ Upstream commit 84a53580c5d2138c7361c7c3eea5b31827e63b35 ]
+
+The SRv6 layer allows defining HMAC data that can later be used to sign IPv6
+Segment Routing Headers. This configuration is realised via netlink through
+four attributes: SEG6_ATTR_HMACKEYID, SEG6_ATTR_SECRET, SEG6_ATTR_SECRETLEN and
+SEG6_ATTR_ALGID. Because the SECRETLEN attribute is decoupled from the actual
+length of the SECRET attribute, it is possible to provide invalid combinations
+(e.g., secret = "", secretlen = 64). This case is not checked in the code and
+with an appropriately crafted netlink message, an out-of-bounds read of up
+to 64 bytes (max secret length) can occur past the skb end pointer and into
+skb_shared_info:
+
+Breakpoint 1, seg6_genl_sethmac (skb=<optimized out>, info=<optimized out>) at net/ipv6/seg6.c:208
+208            memcpy(hinfo->secret, secret, slen);
+(gdb) bt
+ #0  seg6_genl_sethmac (skb=<optimized out>, info=<optimized out>) at net/ipv6/seg6.c:208
+ #1  0xffffffff81e012e9 in genl_family_rcv_msg_doit (skb=skb@entry=0xffff88800b1f9f00, nlh=nlh@entry=0xffff88800b1b7600,
+    extack=extack@entry=0xffffc90000ba7af0, ops=ops@entry=0xffffc90000ba7a80, hdrlen=4, net=0xffffffff84237580 <init_net>, family=<optimized out>,
+    family=<optimized out>) at net/netlink/genetlink.c:731
+ #2  0xffffffff81e01435 in genl_family_rcv_msg (extack=0xffffc90000ba7af0, nlh=0xffff88800b1b7600, skb=0xffff88800b1f9f00,
+    family=0xffffffff82fef6c0 <seg6_genl_family>) at net/netlink/genetlink.c:775
+ #3  genl_rcv_msg (skb=0xffff88800b1f9f00, nlh=0xffff88800b1b7600, extack=0xffffc90000ba7af0) at net/netlink/genetlink.c:792
+ #4  0xffffffff81dfffc3 in netlink_rcv_skb (skb=skb@entry=0xffff88800b1f9f00, cb=cb@entry=0xffffffff81e01350 <genl_rcv_msg>)
+    at net/netlink/af_netlink.c:2501
+ #5  0xffffffff81e00919 in genl_rcv (skb=0xffff88800b1f9f00) at net/netlink/genetlink.c:803
+ #6  0xffffffff81dff6ae in netlink_unicast_kernel (ssk=0xffff888010eec800, skb=0xffff88800b1f9f00, sk=0xffff888004aed000)
+    at net/netlink/af_netlink.c:1319
+ #7  netlink_unicast (ssk=ssk@entry=0xffff888010eec800, skb=skb@entry=0xffff88800b1f9f00, portid=portid@entry=0, nonblock=<optimized out>)
+    at net/netlink/af_netlink.c:1345
+ #8  0xffffffff81dff9a4 in netlink_sendmsg (sock=<optimized out>, msg=0xffffc90000ba7e48, len=<optimized out>) at net/netlink/af_netlink.c:1921
+...
+(gdb) p/x ((struct sk_buff *)0xffff88800b1f9f00)->head + ((struct sk_buff *)0xffff88800b1f9f00)->end
+$1 = 0xffff88800b1b76c0
+(gdb) p/x secret
+$2 = 0xffff88800b1b76c0
+(gdb) p slen
+$3 = 64 '@'
+
+The OOB data can then be read back from userspace by dumping HMAC state. This
+commit fixes this by ensuring SECRETLEN cannot exceed the actual length of
+SECRET.
+
+Reported-by: Lucas Leong <wmliang.tw@gmail.com>
+Tested: verified that EINVAL is correctly returned when secretlen > len(secret)
+Fixes: 4f4853dc1c9c1 ("ipv6: sr: implement API to control SR HMAC structure")
+Signed-off-by: David Lebrun <dlebrun@google.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv6/seg6.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/ipv6/seg6.c b/net/ipv6/seg6.c
+index 75421a472d25a..f5c448c276fef 100644
+--- a/net/ipv6/seg6.c
++++ b/net/ipv6/seg6.c
+@@ -125,6 +125,11 @@ static int seg6_genl_sethmac(struct sk_buff *skb, struct genl_info *info)
+               goto out_unlock;
+       }
++      if (slen > nla_len(info->attrs[SEG6_ATTR_SECRET])) {
++              err = -EINVAL;
++              goto out_unlock;
++      }
++
+       if (hinfo) {
+               err = seg6_hmac_info_del(net, hmackeyid);
+               if (err)
+-- 
+2.35.1
+
diff --git a/queue-5.4/netfilter-br_netfilter-drop-dst-references-before-se.patch b/queue-5.4/netfilter-br_netfilter-drop-dst-references-before-se.patch
new file mode 100644 (file)
index 0000000..5d7ee8b
--- /dev/null
@@ -0,0 +1,96 @@
+From 24654f2f97d3243bec0a5fa236c1278cdfa65276 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 30 Aug 2022 22:36:03 -0700
+Subject: netfilter: br_netfilter: Drop dst references before setting.
+
+From: Harsh Modi <harshmodi@google.com>
+
+[ Upstream commit d047283a7034140ea5da759a494fd2274affdd46 ]
+
+The IPv6 path already drops dst in the daddr changed case, but the IPv4
+path does not. This change makes the two code paths consistent.
+
+Further, it is possible that there is already a metadata_dst allocated from
+ingress that might already be attached to skbuff->dst while following
+the bridge path. If it is not released before setting a new
+metadata_dst, it will be leaked. This is similar to what is done in
+bpf_set_tunnel_key() or ip6_route_input().
+
+It is important to note that the memory being leaked is not the dst
+being set in the bridge code, but rather memory allocated from some
+other code path that is not being freed correctly before the skb dst is
+overwritten.
+
+An example of the leakage fixed by this commit found using kmemleak:
+
+unreferenced object 0xffff888010112b00 (size 256):
+  comm "softirq", pid 0, jiffies 4294762496 (age 32.012s)
+  hex dump (first 32 bytes):
+    00 00 00 00 00 00 00 00 80 16 f1 83 ff ff ff ff  ................
+    e1 4e f6 82 ff ff ff ff 00 00 00 00 00 00 00 00  .N..............
+  backtrace:
+    [<00000000d79567ea>] metadata_dst_alloc+0x1b/0xe0
+    [<00000000be113e13>] udp_tun_rx_dst+0x174/0x1f0
+    [<00000000a36848f4>] geneve_udp_encap_recv+0x350/0x7b0
+    [<00000000d4afb476>] udp_queue_rcv_one_skb+0x380/0x560
+    [<00000000ac064aea>] udp_unicast_rcv_skb+0x75/0x90
+    [<000000009a8ee8c5>] ip_protocol_deliver_rcu+0xd8/0x230
+    [<00000000ef4980bb>] ip_local_deliver_finish+0x7a/0xa0
+    [<00000000d7533c8c>] __netif_receive_skb_one_core+0x89/0xa0
+    [<00000000a879497d>] process_backlog+0x93/0x190
+    [<00000000e41ade9f>] __napi_poll+0x28/0x170
+    [<00000000b4c0906b>] net_rx_action+0x14f/0x2a0
+    [<00000000b20dd5d4>] __do_softirq+0xf4/0x305
+    [<000000003a7d7e15>] __irq_exit_rcu+0xc3/0x140
+    [<00000000968d39a2>] sysvec_apic_timer_interrupt+0x9e/0xc0
+    [<000000009e920794>] asm_sysvec_apic_timer_interrupt+0x16/0x20
+    [<000000008942add0>] native_safe_halt+0x13/0x20
+
+Florian Westphal says: "Original code was likely fine because nothing
+ever did set a skb->dst entry earlier than bridge in those days."
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Signed-off-by: Harsh Modi <harshmodi@google.com>
+Acked-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/bridge/br_netfilter_hooks.c | 2 ++
+ net/bridge/br_netfilter_ipv6.c  | 1 +
+ 2 files changed, 3 insertions(+)
+
+diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
+index 19726d81025d5..01e33724d10c3 100644
+--- a/net/bridge/br_netfilter_hooks.c
++++ b/net/bridge/br_netfilter_hooks.c
+@@ -384,6 +384,7 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
+                               /* - Bridged-and-DNAT'ed traffic doesn't
+                                *   require ip_forwarding. */
+                               if (rt->dst.dev == dev) {
++                                      skb_dst_drop(skb);
+                                       skb_dst_set(skb, &rt->dst);
+                                       goto bridged_dnat;
+                               }
+@@ -413,6 +414,7 @@ static int br_nf_pre_routing_finish(struct net *net, struct sock *sk, struct sk_
+                       kfree_skb(skb);
+                       return 0;
+               }
++              skb_dst_drop(skb);
+               skb_dst_set_noref(skb, &rt->dst);
+       }
+diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c
+index e4e0c836c3f51..6b07f30675bb0 100644
+--- a/net/bridge/br_netfilter_ipv6.c
++++ b/net/bridge/br_netfilter_ipv6.c
+@@ -197,6 +197,7 @@ static int br_nf_pre_routing_finish_ipv6(struct net *net, struct sock *sk, struc
+                       kfree_skb(skb);
+                       return 0;
+               }
++              skb_dst_drop(skb);
+               skb_dst_set_noref(skb, &rt->dst);
+       }
+-- 
+2.35.1
+
diff --git a/queue-5.4/netfilter-nf_conntrack_irc-fix-forged-ip-logic.patch b/queue-5.4/netfilter-nf_conntrack_irc-fix-forged-ip-logic.patch
new file mode 100644 (file)
index 0000000..e69015b
--- /dev/null
@@ -0,0 +1,43 @@
+From 007d4abd83d5130049ad9c6b67758e801a727eb0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 26 Aug 2022 14:56:58 +1000
+Subject: netfilter: nf_conntrack_irc: Fix forged IP logic
+
+From: David Leadbeater <dgl@dgl.cx>
+
+[ Upstream commit 0efe125cfb99e6773a7434f3463f7c2fa28f3a43 ]
+
+Ensure the match happens in the right direction, previously the
+destination used was the server, not the NAT host, as the comment
+shows the code intended.
+
+Additionally nf_nat_irc uses port 0 as a signal and there's no valid way
+it can appear in a DCC message, so consider port 0 also forged.
+
+Fixes: 869f37d8e48f ("[NETFILTER]: nf_conntrack/nf_nat: add IRC helper port")
+Signed-off-by: David Leadbeater <dgl@dgl.cx>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/netfilter/nf_conntrack_irc.c | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/net/netfilter/nf_conntrack_irc.c b/net/netfilter/nf_conntrack_irc.c
+index e40988a2f22fb..26245419ef4a9 100644
+--- a/net/netfilter/nf_conntrack_irc.c
++++ b/net/netfilter/nf_conntrack_irc.c
+@@ -185,8 +185,9 @@ static int help(struct sk_buff *skb, unsigned int protoff,
+                       /* dcc_ip can be the internal OR external (NAT'ed) IP */
+                       tuple = &ct->tuplehash[dir].tuple;
+-                      if (tuple->src.u3.ip != dcc_ip &&
+-                          tuple->dst.u3.ip != dcc_ip) {
++                      if ((tuple->src.u3.ip != dcc_ip &&
++                           ct->tuplehash[!dir].tuple.dst.u3.ip != dcc_ip) ||
++                          dcc_port == 0) {
+                               net_warn_ratelimited("Forged DCC command from %pI4: %pI4:%u\n",
+                                                    &tuple->src.u3.ip,
+                                                    &dcc_ip, dcc_port);
+-- 
+2.35.1
+
diff --git a/queue-5.4/nvme-tcp-fix-uaf-when-detecting-digest-errors.patch b/queue-5.4/nvme-tcp-fix-uaf-when-detecting-digest-errors.patch
new file mode 100644 (file)
index 0000000..22d65b4
--- /dev/null
@@ -0,0 +1,39 @@
+From d2bbe1474f187aba39cd7a692ee2852fdd230746 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Sep 2022 13:54:17 +0300
+Subject: nvme-tcp: fix UAF when detecting digest errors
+
+From: Sagi Grimberg <sagi@grimberg.me>
+
+[ Upstream commit 160f3549a907a50e51a8518678ba2dcf2541abea ]
+
+We should also bail from the io_work loop when we set rd_enabled to true,
+so we don't attempt to read data from the socket when the TCP stream is
+already out-of-sync or corrupted.
+
+Fixes: 3f2304f8c6d6 ("nvme-tcp: add NVMe over TCP host driver")
+Reported-by: Daniel Wagner <dwagner@suse.de>
+Signed-off-by: Sagi Grimberg <sagi@grimberg.me>
+Reviewed-by: Daniel Wagner <dwagner@suse.de>
+Signed-off-by: Christoph Hellwig <hch@lst.de>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/nvme/host/tcp.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
+index 2a27ac9aedbaa..3169859cd3906 100644
+--- a/drivers/nvme/host/tcp.c
++++ b/drivers/nvme/host/tcp.c
+@@ -1074,7 +1074,7 @@ static void nvme_tcp_io_work(struct work_struct *w)
+               if (result > 0)
+                       pending = true;
+-              if (!pending)
++              if (!pending || !queue->rd_enabled)
+                       return;
+       } while (!time_after(jiffies, deadline)); /* quota is exhausted */
+-- 
+2.35.1
+
diff --git a/queue-5.4/rdma-cma-fix-arguments-order-in-net-device-validatio.patch b/queue-5.4/rdma-cma-fix-arguments-order-in-net-device-validatio.patch
new file mode 100644 (file)
index 0000000..8d3960b
--- /dev/null
@@ -0,0 +1,48 @@
+From af9d402a30d3a74776510bf05f92e8a79ab25332 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 23 Aug 2022 13:51:50 +0300
+Subject: RDMA/cma: Fix arguments order in net device validation
+
+From: Michael Guralnik <michaelgur@nvidia.com>
+
+[ Upstream commit 27cfde795a96aef1e859a5480489944b95421e46 ]
+
+Fix the order of source and destination addresses when resolving the
+route between server and client to validate use of correct net device.
+
+The reverse order we had so far didn't actually validate the net device
+as the server would try to resolve the route to itself, thus always
+getting the server's net device.
+
+The issue was discovered when running cm applications on a single host
+between 2 interfaces with same subnet and source based routing rules.
+When resolving the reverse route the source based route rules were
+ignored.
+
+Fixes: f887f2ac87c2 ("IB/cma: Validate routing of incoming requests")
+Link: https://lore.kernel.org/r/1c1ec2277a131d277ebcceec987fd338d35b775f.1661251872.git.leonro@nvidia.com
+Signed-off-by: Michael Guralnik <michaelgur@nvidia.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/core/cma.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
+index de7df5ab06f3b..cf174aa7fe25b 100644
+--- a/drivers/infiniband/core/cma.c
++++ b/drivers/infiniband/core/cma.c
+@@ -1719,8 +1719,8 @@ cma_ib_id_from_event(struct ib_cm_id *cm_id,
+               }
+               if (!validate_net_dev(*net_dev,
+-                               (struct sockaddr *)&req->listen_addr_storage,
+-                               (struct sockaddr *)&req->src_addr_storage)) {
++                               (struct sockaddr *)&req->src_addr_storage,
++                               (struct sockaddr *)&req->listen_addr_storage)) {
+                       id_priv = ERR_PTR(-EHOSTUNREACH);
+                       goto err;
+               }
+-- 
+2.35.1
+
diff --git a/queue-5.4/rdma-hns-fix-supported-page-size.patch b/queue-5.4/rdma-hns-fix-supported-page-size.patch
new file mode 100644 (file)
index 0000000..9347ea0
--- /dev/null
@@ -0,0 +1,37 @@
+From 6e8f3c212ad4bd29d39d579e0cd64686ddbf5ae9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Aug 2022 18:50:18 +0800
+Subject: RDMA/hns: Fix supported page size
+
+From: Chengchang Tang <tangchengchang@huawei.com>
+
+[ Upstream commit 55af9d498556f0860eb89ffa7677e8d73f6f643f ]
+
+The supported page size for hns is (4K, 128M), not (4K, 2G).
+
+Fixes: cfc85f3e4b7f ("RDMA/hns: Add profile support for hip08 driver")
+Link: https://lore.kernel.org/r/20220829105021.1427804-2-liangwenpeng@huawei.com
+Signed-off-by: Chengchang Tang <tangchengchang@huawei.com>
+Signed-off-by: Wenpeng Liang <liangwenpeng@huawei.com>
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/hns/hns_roce_hw_v2.h | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+index 76a14db7028dd..b9ab3ca3079c7 100644
+--- a/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
++++ b/drivers/infiniband/hw/hns/hns_roce_hw_v2.h
+@@ -89,7 +89,7 @@
+ #define HNS_ROCE_V2_SCCC_ENTRY_SZ             32
+ #define HNS_ROCE_V2_QPC_TIMER_ENTRY_SZ                PAGE_SIZE
+ #define HNS_ROCE_V2_CQC_TIMER_ENTRY_SZ                PAGE_SIZE
+-#define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED               0xFFFFF000
++#define HNS_ROCE_V2_PAGE_SIZE_SUPPORTED               0xFFFF000
+ #define HNS_ROCE_V2_MAX_INNER_MTPT_NUM                2
+ #define HNS_ROCE_INVALID_LKEY                 0x100
+ #define HNS_ROCE_CMQ_TX_TIMEOUT                       30000
+-- 
+2.35.1
+
diff --git a/queue-5.4/rdma-mlx5-set-local-port-to-one-when-accessing-count.patch b/queue-5.4/rdma-mlx5-set-local-port-to-one-when-accessing-count.patch
new file mode 100644 (file)
index 0000000..877c33b
--- /dev/null
@@ -0,0 +1,53 @@
+From cf525c2d340016f83c285fc76d4cf7cf22a04e22 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 29 Aug 2022 12:02:28 +0300
+Subject: RDMA/mlx5: Set local port to one when accessing counters
+
+From: Chris Mi <cmi@nvidia.com>
+
+[ Upstream commit 74b30b3ad5cec95d2647e796d10137438a098bc1 ]
+
+When accessing Ports Performance Counters Register (PPCNT),
+local port must be one if it is Function-Per-Port HCA that
+HCA_CAP.num_ports is 1.
+
+The offending patch can change the local port to other values
+when accessing PPCNT after enabling switchdev mode. The following
+syndrome will be printed:
+
+ # cat /sys/class/infiniband/rdmap4s0f0/ports/2/counters/*
+ # dmesg
+ mlx5_core 0000:04:00.0: mlx5_cmd_check:756:(pid 12450): ACCESS_REG(0x805) op_mod(0x1) failed, status bad parameter(0x3), syndrome (0x1e5585)
+
+Fix it by setting local port to one for Function-Per-Port HCA.
+
+Fixes: 210b1f78076f ("IB/mlx5: When not in dual port RoCE mode, use provided port as native")
+Reviewed-by: Mark Bloch <mbloch@nvidia.com>
+Signed-off-by: Chris Mi <cmi@nvidia.com>
+Link: https://lore.kernel.org/r/6c5086c295c76211169e58dbd610fb0402360bab.1661763459.git.leonro@nvidia.com
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/hw/mlx5/mad.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+diff --git a/drivers/infiniband/hw/mlx5/mad.c b/drivers/infiniband/hw/mlx5/mad.c
+index 348c1df69cdc6..3897a3ce02ad0 100644
+--- a/drivers/infiniband/hw/mlx5/mad.c
++++ b/drivers/infiniband/hw/mlx5/mad.c
+@@ -219,6 +219,12 @@ static int process_pma_cmd(struct mlx5_ib_dev *dev, u8 port_num,
+               mdev = dev->mdev;
+               mdev_port_num = 1;
+       }
++      if (MLX5_CAP_GEN(dev->mdev, num_ports) == 1) {
++              /* set local port to one for Function-Per-Port HCA. */
++              mdev = dev->mdev;
++              mdev_port_num = 1;
++      }
++
+       /* Declaring support of extended counters */
+       if (in_mad->mad_hdr.attr_id == IB_PMA_CLASS_PORT_INFO) {
+               struct ib_class_port_info cpi = {};
+-- 
+2.35.1
+
diff --git a/queue-5.4/rdma-siw-pass-a-pointer-to-virt_to_page.patch b/queue-5.4/rdma-siw-pass-a-pointer-to-virt_to_page.patch
new file mode 100644 (file)
index 0000000..d6b17ec
--- /dev/null
@@ -0,0 +1,88 @@
+From 02999a608970339a3eec7618d807285804037152 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 2 Sep 2022 23:59:18 +0200
+Subject: RDMA/siw: Pass a pointer to virt_to_page()
+
+From: Linus Walleij <linus.walleij@linaro.org>
+
+[ Upstream commit 0d1b756acf60da5004c1e20ca4462f0c257bf6e1 ]
+
+Functions that work on a pointer to virtual memory such as
+virt_to_pfn() and users of that function such as
+virt_to_page() are supposed to pass a pointer to virtual
+memory, ideally a (void *) or other pointer. However since
+many architectures implement virt_to_pfn() as a macro,
+this function becomes polymorphic and accepts both a
+(unsigned long) and a (void *).
+
+If we instead implement a proper virt_to_pfn(void *addr)
+function the following happens (occurred on arch/arm):
+
+drivers/infiniband/sw/siw/siw_qp_tx.c:32:23: warning: incompatible
+  integer to pointer conversion passing 'dma_addr_t' (aka 'unsigned int')
+  to parameter of type 'const void *' [-Wint-conversion]
+drivers/infiniband/sw/siw/siw_qp_tx.c:32:37: warning: passing argument
+  1 of 'virt_to_pfn' makes pointer from integer without a cast
+  [-Wint-conversion]
+drivers/infiniband/sw/siw/siw_qp_tx.c:538:36: warning: incompatible
+  integer to pointer conversion passing 'unsigned long long'
+  to parameter of type 'const void *' [-Wint-conversion]
+
+Fix this with an explicit cast. In one case where the SIW
+SGE uses an unaligned u64 we need a double cast modifying the
+virtual address (va) to a platform-specific uintptr_t before
+casting to a (void *).
+
+Fixes: b9be6f18cf9e ("rdma/siw: transmit path")
+Cc: linux-rdma@vger.kernel.org
+Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
+Link: https://lore.kernel.org/r/20220902215918.603761-1-linus.walleij@linaro.org
+Signed-off-by: Leon Romanovsky <leon@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/infiniband/sw/siw/siw_qp_tx.c | 18 ++++++++++++++----
+ 1 file changed, 14 insertions(+), 4 deletions(-)
+
+diff --git a/drivers/infiniband/sw/siw/siw_qp_tx.c b/drivers/infiniband/sw/siw/siw_qp_tx.c
+index 424918eb1cd4a..5e6d96bd2eb12 100644
+--- a/drivers/infiniband/sw/siw/siw_qp_tx.c
++++ b/drivers/infiniband/sw/siw/siw_qp_tx.c
+@@ -29,7 +29,7 @@ static struct page *siw_get_pblpage(struct siw_mem *mem, u64 addr, int *idx)
+       dma_addr_t paddr = siw_pbl_get_buffer(pbl, offset, NULL, idx);
+       if (paddr)
+-              return virt_to_page(paddr);
++              return virt_to_page((void *)paddr);
+       return NULL;
+ }
+@@ -523,13 +523,23 @@ static int siw_tx_hdt(struct siw_iwarp_tx *c_tx, struct socket *s)
+                                       kunmap(p);
+                               }
+                       } else {
+-                              u64 va = sge->laddr + sge_off;
++                              /*
++                               * Cast to an uintptr_t to preserve all 64 bits
++                               * in sge->laddr.
++                               */
++                              uintptr_t va = (uintptr_t)(sge->laddr + sge_off);
+-                              page_array[seg] = virt_to_page(va & PAGE_MASK);
++                              /*
++                               * virt_to_page() takes a (void *) pointer
++                               * so cast to a (void *) meaning it will be 64
++                               * bits on a 64 bit platform and 32 bits on a
++                               * 32 bit platform.
++                               */
++                              page_array[seg] = virt_to_page((void *)(va & PAGE_MASK));
+                               if (do_crc)
+                                       crypto_shash_update(
+                                               c_tx->mpa_crc_hd,
+-                                              (void *)(uintptr_t)va,
++                                              (void *)va,
+                                               plen);
+                       }
+-- 
+2.35.1
+
diff --git a/queue-5.4/regulator-core-clean-up-on-enable-failure.patch b/queue-5.4/regulator-core-clean-up-on-enable-failure.patch
new file mode 100644 (file)
index 0000000..0c8a3e7
--- /dev/null
@@ -0,0 +1,72 @@
+From 9550bbd2c21a5bc8385d1227948b5a8e3549c521 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 19 Aug 2022 14:43:36 -0500
+Subject: regulator: core: Clean up on enable failure
+
+From: Andrew Halaney <ahalaney@redhat.com>
+
+[ Upstream commit c32f1ebfd26bece77141257864ed7b4720da1557 ]
+
+If regulator_enable() fails, enable_count is incremented still.
+A consumer, assuming no matching regulator_disable() is necessary on
+failure, will then get this error message upon regulator_put()
+since enable_count is non-zero:
+
+    [    1.277418] WARNING: CPU: 3 PID: 1 at drivers/regulator/core.c:2304 _regulator_put.part.0+0x168/0x170
+
+The consumer could try to fix this in their driver by cleaning up on
+error from regulator_enable() (i.e. call regulator_disable()), but that
+results in the following since regulator_enable() failed and didn't
+increment user_count:
+
+    [    1.258112] unbalanced disables for vreg_l17c
+    [    1.262606] WARNING: CPU: 4 PID: 1 at drivers/regulator/core.c:2899 _regulator_disable+0xd4/0x190
+
+Fix this by decrementing enable_count upon failure to enable.
+
+With this in place, just the reason for failure to enable is printed
+as expected and developers can focus on the root cause of their issue
+instead of thinking their usage of the regulator consumer api is
+incorrect. For example, in my case:
+
+    [    1.240426] vreg_l17c: invalid input voltage found
+
+Fixes: 5451781dadf8 ("regulator: core: Only count load for enabled consumers")
+Signed-off-by: Andrew Halaney <ahalaney@redhat.com>
+Reviewed-by: Douglas Anderson <dianders@chromium.org>
+Reviewed-by: Brian Masney <bmasney@redhat.com>
+Link: https://lore.kernel.org/r/20220819194336.382740-1-ahalaney@redhat.com
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/regulator/core.c | 9 +++++++--
+ 1 file changed, 7 insertions(+), 2 deletions(-)
+
+diff --git a/drivers/regulator/core.c b/drivers/regulator/core.c
+index ae2addadb36f2..6ba3f6e7ea4f8 100644
+--- a/drivers/regulator/core.c
++++ b/drivers/regulator/core.c
+@@ -2486,13 +2486,18 @@ static int _regulator_do_enable(struct regulator_dev *rdev)
+  */
+ static int _regulator_handle_consumer_enable(struct regulator *regulator)
+ {
++      int ret;
+       struct regulator_dev *rdev = regulator->rdev;
+       lockdep_assert_held_once(&rdev->mutex.base);
+       regulator->enable_count++;
+-      if (regulator->uA_load && regulator->enable_count == 1)
+-              return drms_uA_update(rdev);
++      if (regulator->uA_load && regulator->enable_count == 1) {
++              ret = drms_uA_update(rdev);
++              if (ret)
++                      regulator->enable_count--;
++              return ret;
++      }
+       return 0;
+ }
+-- 
+2.35.1
+
diff --git a/queue-5.4/rxrpc-fix-an-insufficiently-large-sglist-in-rxkad_ve.patch b/queue-5.4/rxrpc-fix-an-insufficiently-large-sglist-in-rxkad_ve.patch
new file mode 100644 (file)
index 0000000..5bb0b53
--- /dev/null
@@ -0,0 +1,58 @@
+From 149b7fc156dc96affd5027ac403fcc9da26cb698 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 24 Aug 2022 22:39:28 +0100
+Subject: rxrpc: Fix an insufficiently large sglist in rxkad_verify_packet_2()
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 0d40f728e28393a8817d1fcae923dfa3409e488c ]
+
+rxkad_verify_packet_2() has a small stack-allocated sglist of 4 elements,
+but if that isn't sufficient for the number of fragments in the socket
+buffer, we try to allocate an sglist large enough to hold all the
+fragments.
+
+However, for large packets with a lot of fragments, this isn't sufficient
+and we need at least one additional fragment.
+
+The problem manifests as skb_to_sgvec() returning -EMSGSIZE and this then
+getting returned by userspace.  Most of the time, this isn't a problem as
+rxrpc sets a limit of 5692, big enough for 4 jumbo subpackets to be glued
+together; occasionally, however, the server will ignore the reported limit
+and give a packet that's a lot bigger - say 19852 bytes with ->nr_frags
+being 7.  skb_to_sgvec() then tries to return a "zeroth" fragment that
+seems to occur before the fragments counted by ->nr_frags and we hit the
+end of the sglist too early.
+
+Note that __skb_to_sgvec() also has an skb_walk_frags() loop that is
+recursive up to 24 deep.  I'm not sure if I need to take account of that
+too - or if there's an easy way of counting those frags too.
+
+Fix this by counting an extra frag and allocating a larger sglist based on
+that.
+
+Fixes: d0d5c0cd1e71 ("rxrpc: Use skb_unshare() rather than skb_cow_data()")
+Reported-by: Marc Dionne <marc.dionne@auristor.com>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: linux-afs@lists.infradead.org
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/rxrpc/rxkad.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/rxrpc/rxkad.c b/net/rxrpc/rxkad.c
+index 52a24d4ef5d8a..2ba61971f6231 100644
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -451,7 +451,7 @@ static int rxkad_verify_packet_2(struct rxrpc_call *call, struct sk_buff *skb,
+        * directly into the target buffer.
+        */
+       sg = _sg;
+-      nsg = skb_shinfo(skb)->nr_frags;
++      nsg = skb_shinfo(skb)->nr_frags + 1;
+       if (nsg <= 4) {
+               nsg = 4;
+       } else {
+-- 
+2.35.1
+
diff --git a/queue-5.4/sch_sfb-also-store-skb-len-before-calling-child-enqu.patch b/queue-5.4/sch_sfb-also-store-skb-len-before-calling-child-enqu.patch
new file mode 100644 (file)
index 0000000..1b6648f
--- /dev/null
@@ -0,0 +1,52 @@
+From c6f4f1fb8c6989643bafbfd753a2c6d5fe37a80c Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 5 Sep 2022 21:21:36 +0200
+Subject: sch_sfb: Also store skb len before calling child enqueue
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@toke.dk>
+
+[ Upstream commit 2f09707d0c972120bf794cfe0f0c67e2c2ddb252 ]
+
+Cong Wang noticed that the previous fix for sch_sfb accessing the queued
+skb after enqueueing it to a child qdisc was incomplete: the SFB enqueue
+function was also calling qdisc_qstats_backlog_inc() after enqueue, which
+reads the pkt len from the skb cb field. Fix this by also storing the skb
+len, and using the stored value to increment the backlog after enqueueing.
+
+Fixes: 9efd23297cca ("sch_sfb: Don't assume the skb is still around after enqueueing to child")
+Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Acked-by: Cong Wang <cong.wang@bytedance.com>
+Link: https://lore.kernel.org/r/20220905192137.965549-1-toke@toke.dk
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_sfb.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
+index 085fe06da2a68..3aa6b4dcb1c8e 100644
+--- a/net/sched/sch_sfb.c
++++ b/net/sched/sch_sfb.c
+@@ -281,6 +281,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+ {
+       struct sfb_sched_data *q = qdisc_priv(sch);
++      unsigned int len = qdisc_pkt_len(skb);
+       struct Qdisc *child = q->qdisc;
+       struct tcf_proto *fl;
+       struct sfb_skb_cb cb;
+@@ -403,7 +404,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+       memcpy(&cb, sfb_skb_cb(skb), sizeof(cb));
+       ret = qdisc_enqueue(skb, child, to_free);
+       if (likely(ret == NET_XMIT_SUCCESS)) {
+-              qdisc_qstats_backlog_inc(sch, skb);
++              sch->qstats.backlog += len;
+               sch->q.qlen++;
+               increment_qlen(&cb, q);
+       } else if (net_xmit_drop_count(ret)) {
+-- 
+2.35.1
+
diff --git a/queue-5.4/sch_sfb-don-t-assume-the-skb-is-still-around-after-e.patch b/queue-5.4/sch_sfb-don-t-assume-the-skb-is-still-around-after-e.patch
new file mode 100644 (file)
index 0000000..9a15c84
--- /dev/null
@@ -0,0 +1,82 @@
+From 00a2d64f513d6c242b3a0b83bda745289016def0 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Aug 2022 23:52:18 +0200
+Subject: sch_sfb: Don't assume the skb is still around after enqueueing to
+ child
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Toke Høiland-Jørgensen <toke@toke.dk>
+
+[ Upstream commit 9efd23297cca530bb35e1848665805d3fcdd7889 ]
+
+The sch_sfb enqueue() routine assumes the skb is still alive after it has
+been enqueued into a child qdisc, using the data in the skb cb field in the
+increment_qlen() routine after enqueue. However, the skb may in fact have
+been freed, causing a use-after-free in this case. In particular, this
+happens if sch_cake is used as a child of sfb, and the GSO splitting mode
+of CAKE is enabled (in which case the skb will be split into segments and
+the original skb freed).
+
+Fix this by copying the sfb cb data to the stack before enqueueing the skb,
+and using this stack copy in increment_qlen() instead of the skb pointer
+itself.
+
+Reported-by: zdi-disclosures@trendmicro.com # ZDI-CAN-18231
+Fixes: e13e02a3c68d ("net_sched: SFB flow scheduler")
+Signed-off-by: Toke Høiland-Jørgensen <toke@toke.dk>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/sched/sch_sfb.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/net/sched/sch_sfb.c b/net/sched/sch_sfb.c
+index 4074c50ac3d73..085fe06da2a68 100644
+--- a/net/sched/sch_sfb.c
++++ b/net/sched/sch_sfb.c
+@@ -135,15 +135,15 @@ static void increment_one_qlen(u32 sfbhash, u32 slot, struct sfb_sched_data *q)
+       }
+ }
+-static void increment_qlen(const struct sk_buff *skb, struct sfb_sched_data *q)
++static void increment_qlen(const struct sfb_skb_cb *cb, struct sfb_sched_data *q)
+ {
+       u32 sfbhash;
+-      sfbhash = sfb_hash(skb, 0);
++      sfbhash = cb->hashes[0];
+       if (sfbhash)
+               increment_one_qlen(sfbhash, 0, q);
+-      sfbhash = sfb_hash(skb, 1);
++      sfbhash = cb->hashes[1];
+       if (sfbhash)
+               increment_one_qlen(sfbhash, 1, q);
+ }
+@@ -283,6 +283,7 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+       struct sfb_sched_data *q = qdisc_priv(sch);
+       struct Qdisc *child = q->qdisc;
+       struct tcf_proto *fl;
++      struct sfb_skb_cb cb;
+       int i;
+       u32 p_min = ~0;
+       u32 minqlen = ~0;
+@@ -399,11 +400,12 @@ static int sfb_enqueue(struct sk_buff *skb, struct Qdisc *sch,
+       }
+ enqueue:
++      memcpy(&cb, sfb_skb_cb(skb), sizeof(cb));
+       ret = qdisc_enqueue(skb, child, to_free);
+       if (likely(ret == NET_XMIT_SUCCESS)) {
+               qdisc_qstats_backlog_inc(sch, skb);
+               sch->q.qlen++;
+-              increment_qlen(skb, q);
++              increment_qlen(&cb, q);
+       } else if (net_xmit_drop_count(ret)) {
+               q->stats.childdrop++;
+               qdisc_qstats_drop(sch);
+-- 
+2.35.1
+
index 59b434f621ace9fcfd78670c877721bfa28451c5..68fd4e129d9d6fc246db298c98cfc4cfa9ad8865 100644 (file)
@@ -86,3 +86,21 @@ cgroup-optimize-single-thread-migration.patch
 cgroup-elide-write-locking-threadgroup_rwsem-when-up.patch
 cgroup-fix-threadgroup_rwsem-cpus_read_lock-deadlock.patch
 smb3-missing-inode-locks-in-punch-hole.patch
+arm-dts-imx6qdl-kontron-samx6i-remove-duplicated-nod.patch
+regulator-core-clean-up-on-enable-failure.patch
+rdma-cma-fix-arguments-order-in-net-device-validatio.patch
+soc-brcmstb-pm-arm-fix-refcount-leak-and-__iomem-lea.patch
+rdma-hns-fix-supported-page-size.patch
+netfilter-br_netfilter-drop-dst-references-before-se.patch
+netfilter-nf_conntrack_irc-fix-forged-ip-logic.patch
+rxrpc-fix-an-insufficiently-large-sglist-in-rxkad_ve.patch
+afs-use-the-operation-issue-time-instead-of-the-repl.patch
+sch_sfb-don-t-assume-the-skb-is-still-around-after-e.patch
+tipc-fix-shift-wrapping-bug-in-map_get.patch
+i40e-fix-kernel-crash-during-module-removal.patch
+rdma-siw-pass-a-pointer-to-virt_to_page.patch
+ipv6-sr-fix-out-of-bounds-read-when-setting-hmac-dat.patch
+rdma-mlx5-set-local-port-to-one-when-accessing-count.patch
+nvme-tcp-fix-uaf-when-detecting-digest-errors.patch
+tcp-fix-early-etimedout-after-spurious-non-sack-rto.patch
+sch_sfb-also-store-skb-len-before-calling-child-enqu.patch
diff --git a/queue-5.4/soc-brcmstb-pm-arm-fix-refcount-leak-and-__iomem-lea.patch b/queue-5.4/soc-brcmstb-pm-arm-fix-refcount-leak-and-__iomem-lea.patch
new file mode 100644 (file)
index 0000000..e819cb6
--- /dev/null
@@ -0,0 +1,163 @@
+From f46a463c904a0e3e20dfed360161172f37229fbd Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Jul 2022 09:56:20 +0800
+Subject: soc: brcmstb: pm-arm: Fix refcount leak and __iomem leak bugs
+
+From: Liang He <windhl@126.com>
+
+[ Upstream commit 1085f5080647f0c9f357c270a537869191f7f2a1 ]
+
+In brcmstb_pm_probe(), there are two kinds of leak bugs:
+
+(1) we need to add of_node_put() when for_each__matching_node() breaks
+(2) we need to add iounmap() for each iomap in fail path
+
+Fixes: 0b741b8234c8 ("soc: bcm: brcmstb: Add support for S2/S3/S5 suspend states (ARM)")
+Signed-off-by: Liang He <windhl@126.com>
+Link: https://lore.kernel.org/r/20220707015620.306468-1-windhl@126.com
+Signed-off-by: Florian Fainelli <f.fainelli@gmail.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/soc/bcm/brcmstb/pm/pm-arm.c | 50 ++++++++++++++++++++++-------
+ 1 file changed, 39 insertions(+), 11 deletions(-)
+
+diff --git a/drivers/soc/bcm/brcmstb/pm/pm-arm.c b/drivers/soc/bcm/brcmstb/pm/pm-arm.c
+index c6ec7d95bcfcc..722fd54e537cf 100644
+--- a/drivers/soc/bcm/brcmstb/pm/pm-arm.c
++++ b/drivers/soc/bcm/brcmstb/pm/pm-arm.c
+@@ -681,13 +681,14 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
+       const struct of_device_id *of_id = NULL;
+       struct device_node *dn;
+       void __iomem *base;
+-      int ret, i;
++      int ret, i, s;
+       /* AON ctrl registers */
+       base = brcmstb_ioremap_match(aon_ctrl_dt_ids, 0, NULL);
+       if (IS_ERR(base)) {
+               pr_err("error mapping AON_CTRL\n");
+-              return PTR_ERR(base);
++              ret = PTR_ERR(base);
++              goto aon_err;
+       }
+       ctrl.aon_ctrl_base = base;
+@@ -697,8 +698,10 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
+               /* Assume standard offset */
+               ctrl.aon_sram = ctrl.aon_ctrl_base +
+                                    AON_CTRL_SYSTEM_DATA_RAM_OFS;
++              s = 0;
+       } else {
+               ctrl.aon_sram = base;
++              s = 1;
+       }
+       writel_relaxed(0, ctrl.aon_sram + AON_REG_PANIC);
+@@ -708,7 +711,8 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
+                                    (const void **)&ddr_phy_data);
+       if (IS_ERR(base)) {
+               pr_err("error mapping DDR PHY\n");
+-              return PTR_ERR(base);
++              ret = PTR_ERR(base);
++              goto ddr_phy_err;
+       }
+       ctrl.support_warm_boot = ddr_phy_data->supports_warm_boot;
+       ctrl.pll_status_offset = ddr_phy_data->pll_status_offset;
+@@ -728,17 +732,20 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
+       for_each_matching_node(dn, ddr_shimphy_dt_ids) {
+               i = ctrl.num_memc;
+               if (i >= MAX_NUM_MEMC) {
++                      of_node_put(dn);
+                       pr_warn("too many MEMCs (max %d)\n", MAX_NUM_MEMC);
+                       break;
+               }
+               base = of_io_request_and_map(dn, 0, dn->full_name);
+               if (IS_ERR(base)) {
++                      of_node_put(dn);
+                       if (!ctrl.support_warm_boot)
+                               break;
+                       pr_err("error mapping DDR SHIMPHY %d\n", i);
+-                      return PTR_ERR(base);
++                      ret = PTR_ERR(base);
++                      goto ddr_shimphy_err;
+               }
+               ctrl.memcs[i].ddr_shimphy_base = base;
+               ctrl.num_memc++;
+@@ -749,14 +756,18 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
+       for_each_matching_node(dn, brcmstb_memc_of_match) {
+               base = of_iomap(dn, 0);
+               if (!base) {
++                      of_node_put(dn);
+                       pr_err("error mapping DDR Sequencer %d\n", i);
+-                      return -ENOMEM;
++                      ret = -ENOMEM;
++                      goto brcmstb_memc_err;
+               }
+               of_id = of_match_node(brcmstb_memc_of_match, dn);
+               if (!of_id) {
+                       iounmap(base);
+-                      return -EINVAL;
++                      of_node_put(dn);
++                      ret = -EINVAL;
++                      goto brcmstb_memc_err;
+               }
+               ddr_seq_data = of_id->data;
+@@ -776,21 +787,24 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
+       dn = of_find_matching_node(NULL, sram_dt_ids);
+       if (!dn) {
+               pr_err("SRAM not found\n");
+-              return -EINVAL;
++              ret = -EINVAL;
++              goto brcmstb_memc_err;
+       }
+       ret = brcmstb_init_sram(dn);
+       of_node_put(dn);
+       if (ret) {
+               pr_err("error setting up SRAM for PM\n");
+-              return ret;
++              goto brcmstb_memc_err;
+       }
+       ctrl.pdev = pdev;
+       ctrl.s3_params = kmalloc(sizeof(*ctrl.s3_params), GFP_KERNEL);
+-      if (!ctrl.s3_params)
+-              return -ENOMEM;
++      if (!ctrl.s3_params) {
++              ret = -ENOMEM;
++              goto s3_params_err;
++      }
+       ctrl.s3_params_pa = dma_map_single(&pdev->dev, ctrl.s3_params,
+                                          sizeof(*ctrl.s3_params),
+                                          DMA_TO_DEVICE);
+@@ -810,7 +824,21 @@ static int brcmstb_pm_probe(struct platform_device *pdev)
+ out:
+       kfree(ctrl.s3_params);
+-
++s3_params_err:
++      iounmap(ctrl.boot_sram);
++brcmstb_memc_err:
++      for (i--; i >= 0; i--)
++              iounmap(ctrl.memcs[i].ddr_ctrl);
++ddr_shimphy_err:
++      for (i = 0; i < ctrl.num_memc; i++)
++              iounmap(ctrl.memcs[i].ddr_shimphy_base);
++
++      iounmap(ctrl.memcs[0].ddr_phy_base);
++ddr_phy_err:
++      iounmap(ctrl.aon_ctrl_base);
++      if (s)
++              iounmap(ctrl.aon_sram);
++aon_err:
+       pr_warn("PM: initialization failed with code %d\n", ret);
+       return ret;
+-- 
+2.35.1
+
diff --git a/queue-5.4/tcp-fix-early-etimedout-after-spurious-non-sack-rto.patch b/queue-5.4/tcp-fix-early-etimedout-after-spurious-non-sack-rto.patch
new file mode 100644 (file)
index 0000000..ef2196b
--- /dev/null
@@ -0,0 +1,129 @@
+From a6f11e72c6cb7e5f4c631299c9ce20f31bfe67da Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Sat, 3 Sep 2022 08:10:23 -0400
+Subject: tcp: fix early ETIMEDOUT after spurious non-SACK RTO
+
+From: Neal Cardwell <ncardwell@google.com>
+
+[ Upstream commit 686dc2db2a0fdc1d34b424ec2c0a735becd8d62b ]
+
+Fix a bug reported and analyzed by Nagaraj Arankal, where the handling
+of a spurious non-SACK RTO could cause a connection to fail to clear
+retrans_stamp, causing a later RTO to very prematurely time out the
+connection with ETIMEDOUT.
+
+Here is the buggy scenario, expanding upon Nagaraj Arankal's excellent
+report:
+
+(*1) Send one data packet on a non-SACK connection
+
+(*2) Because no ACK packet is received, the packet is retransmitted
+     and we enter CA_Loss; but this retransmission is spurious.
+
+(*3) The ACK for the original data is received. The transmitted packet
+     is acknowledged.  The TCP timestamp is before the retrans_stamp,
+     so tcp_may_undo() returns true, and tcp_try_undo_loss() returns
+     true without changing state to Open (because tcp_is_sack() is
+     false), and tcp_process_loss() returns without calling
+     tcp_try_undo_recovery().  Normally after undoing a CA_Loss
+     episode, tcp_fastretrans_alert() would see that the connection
+     has returned to CA_Open and fall through and call
+     tcp_try_to_open(), which would set retrans_stamp to 0.  However,
+     for non-SACK connections we hold the connection in CA_Loss, so do
+     not fall through to call tcp_try_to_open() and do not set
+     retrans_stamp to 0. So retrans_stamp is (erroneously) still
+     non-zero.
+
+     At this point the first "retransmission event" has passed and
+     been recovered from. Any future retransmission is a completely
+     new "event". However, retrans_stamp is erroneously still
+     set. (And we are still in CA_Loss, which is correct.)
+
+(*4) After 16 minutes (to correspond with tcp_retries2=15), a new data
+     packet is sent. Note: No data is transmitted between (*3) and
+     (*4) and we disabled keep alives.
+
+     The socket's timeout SHOULD be calculated from this point in
+     time, but instead it's calculated from the prior "event" 16
+     minutes ago (step (*2)).
+
+(*5) Because no ACK packet is received, the packet is retransmitted.
+
+(*6) At the time of the 2nd retransmission, the socket returns
+     ETIMEDOUT, prematurely, because retrans_stamp is (erroneously)
+     too far in the past (set at the time of (*2)).
+
+This commit fixes this bug by ensuring that we reuse in
+tcp_try_undo_loss() the same careful logic for non-SACK connections
+that we have in tcp_try_undo_recovery(). To avoid duplicating logic,
+we factor out that logic into a new
+tcp_is_non_sack_preventing_reopen() helper and call that helper from
+both undo functions.
+
+Fixes: da34ac7626b5 ("tcp: only undo on partial ACKs in CA_Loss")
+Reported-by: Nagaraj Arankal <nagaraj.p.arankal@hpe.com>
+Link: https://lore.kernel.org/all/SJ0PR84MB1847BE6C24D274C46A1B9B0EB27A9@SJ0PR84MB1847.NAMPRD84.PROD.OUTLOOK.COM/
+Signed-off-by: Neal Cardwell <ncardwell@google.com>
+Signed-off-by: Yuchung Cheng <ycheng@google.com>
+Reviewed-by: Eric Dumazet <edumazet@google.com>
+Link: https://lore.kernel.org/r/20220903121023.866900-1-ncardwell.kernel@gmail.com
+Signed-off-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/ipv4/tcp_input.c | 25 ++++++++++++++++++-------
+ 1 file changed, 18 insertions(+), 7 deletions(-)
+
+diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
+index ff10edc85d648..0ebba83dbe220 100644
+--- a/net/ipv4/tcp_input.c
++++ b/net/ipv4/tcp_input.c
+@@ -2384,6 +2384,21 @@ static inline bool tcp_may_undo(const struct tcp_sock *tp)
+       return tp->undo_marker && (!tp->undo_retrans || tcp_packet_delayed(tp));
+ }
++static bool tcp_is_non_sack_preventing_reopen(struct sock *sk)
++{
++      struct tcp_sock *tp = tcp_sk(sk);
++
++      if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) {
++              /* Hold old state until something *above* high_seq
++               * is ACKed. For Reno it is MUST to prevent false
++               * fast retransmits (RFC2582). SACK TCP is safe. */
++              if (!tcp_any_retrans_done(sk))
++                      tp->retrans_stamp = 0;
++              return true;
++      }
++      return false;
++}
++
+ /* People celebrate: "We love our President!" */
+ static bool tcp_try_undo_recovery(struct sock *sk)
+ {
+@@ -2406,14 +2421,8 @@ static bool tcp_try_undo_recovery(struct sock *sk)
+       } else if (tp->rack.reo_wnd_persist) {
+               tp->rack.reo_wnd_persist--;
+       }
+-      if (tp->snd_una == tp->high_seq && tcp_is_reno(tp)) {
+-              /* Hold old state until something *above* high_seq
+-               * is ACKed. For Reno it is MUST to prevent false
+-               * fast retransmits (RFC2582). SACK TCP is safe. */
+-              if (!tcp_any_retrans_done(sk))
+-                      tp->retrans_stamp = 0;
++      if (tcp_is_non_sack_preventing_reopen(sk))
+               return true;
+-      }
+       tcp_set_ca_state(sk, TCP_CA_Open);
+       tp->is_sack_reneg = 0;
+       return false;
+@@ -2449,6 +2458,8 @@ static bool tcp_try_undo_loss(struct sock *sk, bool frto_undo)
+                       NET_INC_STATS(sock_net(sk),
+                                       LINUX_MIB_TCPSPURIOUSRTOS);
+               inet_csk(sk)->icsk_retransmits = 0;
++              if (tcp_is_non_sack_preventing_reopen(sk))
++                      return true;
+               if (frto_undo || tcp_is_sack(tp)) {
+                       tcp_set_ca_state(sk, TCP_CA_Open);
+                       tp->is_sack_reneg = 0;
+-- 
+2.35.1
+
diff --git a/queue-5.4/tipc-fix-shift-wrapping-bug-in-map_get.patch b/queue-5.4/tipc-fix-shift-wrapping-bug-in-map_get.patch
new file mode 100644 (file)
index 0000000..4ba7225
--- /dev/null
@@ -0,0 +1,36 @@
+From 2d8d40822d1def87825c590f9853fbfcd86ba2f9 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 31 Aug 2022 17:47:56 +0300
+Subject: tipc: fix shift wrapping bug in map_get()
+
+From: Dan Carpenter <dan.carpenter@oracle.com>
+
+[ Upstream commit e2b224abd9bf45dcb55750479fc35970725a430b ]
+
+There is a shift wrapping bug in this code so anything thing above
+31 will return false.
+
+Fixes: 35c55c9877f8 ("tipc: add neighbor monitoring framework")
+Signed-off-by: Dan Carpenter <dan.carpenter@oracle.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/tipc/monitor.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/net/tipc/monitor.c b/net/tipc/monitor.c
+index e7155a7743001..0b9ad3b5ff18a 100644
+--- a/net/tipc/monitor.c
++++ b/net/tipc/monitor.c
+@@ -130,7 +130,7 @@ static void map_set(u64 *up_map, int i, unsigned int v)
+ static int map_get(u64 up_map, int i)
+ {
+-      return (up_map & (1 << i)) >> i;
++      return (up_map & (1ULL << i)) >> i;
+ }
+ static struct tipc_peer *peer_prev(struct tipc_peer *peer)
+-- 
+2.35.1
+