aboutsummaryrefslogtreecommitdiffstats
path: root/queue-5.4
diff options
context:
space:
mode:
authorSasha Levin <sashal@kernel.org>2024-04-03 11:59:49 -0400
committerSasha Levin <sashal@kernel.org>2024-04-03 11:59:49 -0400
commite5bbe19aa54d705d7caad5dee7f0a44ee5de817b (patch)
tree1a0f3399903a872fbc14e40cac59362ff48e37f0 /queue-5.4
parentdc7572bcccafa012a744b4cbfa9b453ad527bee5 (diff)
downloadstable-queue-e5bbe19aa54d705d7caad5dee7f0a44ee5de817b.tar.gz
Fixes for 5.4
Signed-off-by: Sasha Levin <sashal@kernel.org>
Diffstat (limited to 'queue-5.4')
-rw-r--r--queue-5.4/dm-integrity-fix-out-of-range-warning.patch47
-rw-r--r--queue-5.4/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch75
-rw-r--r--queue-5.4/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch53
-rw-r--r--queue-5.4/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch62
-rw-r--r--queue-5.4/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch116
-rw-r--r--queue-5.4/scsi-libsas-introduce-struct-smp_disc_resp.patch217
-rw-r--r--queue-5.4/series7
-rw-r--r--queue-5.4/tcp-properly-terminate-timers-for-kernel-sockets.patch138
8 files changed, 715 insertions, 0 deletions
diff --git a/queue-5.4/dm-integrity-fix-out-of-range-warning.patch b/queue-5.4/dm-integrity-fix-out-of-range-warning.patch
new file mode 100644
index 0000000000..ba62749ea7
--- /dev/null
+++ b/queue-5.4/dm-integrity-fix-out-of-range-warning.patch
@@ -0,0 +1,47 @@
+From c95a4bcb7b39f8b05318780bc0df962bece964ad Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 28 Mar 2024 15:30:39 +0100
+Subject: dm integrity: fix out-of-range warning
+
+From: Arnd Bergmann <arnd@arndb.de>
+
+[ Upstream commit 8e91c2342351e0f5ef6c0a704384a7f6fc70c3b2 ]
+
+Depending on the value of CONFIG_HZ, clang complains about a pointless
+comparison:
+
+drivers/md/dm-integrity.c:4085:12: error: result of comparison of
+ constant 42949672950 with expression of type
+ 'unsigned int' is always false
+ [-Werror,-Wtautological-constant-out-of-range-compare]
+ if (val >= (uint64_t)UINT_MAX * 1000 / HZ) {
+
+As the check remains useful for other configurations, shut up the
+warning by adding a second type cast to uint64_t.
+
+Fixes: 468dfca38b1a ("dm integrity: add a bitmap mode")
+Signed-off-by: Arnd Bergmann <arnd@arndb.de>
+Reviewed-by: Mikulas Patocka <mpatocka@redhat.com>
+Reviewed-by: Justin Stitt <justinstitt@google.com>
+Signed-off-by: Mike Snitzer <snitzer@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/md/dm-integrity.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/drivers/md/dm-integrity.c b/drivers/md/dm-integrity.c
+index f3246f7407d61..4b634633b4a5e 100644
+--- a/drivers/md/dm-integrity.c
++++ b/drivers/md/dm-integrity.c
+@@ -3755,7 +3755,7 @@ static int dm_integrity_ctr(struct dm_target *ti, unsigned argc, char **argv)
+ } else if (sscanf(opt_string, "sectors_per_bit:%llu%c", &llval, &dummy) == 1) {
+ log2_sectors_per_bitmap_bit = !llval ? 0 : __ilog2_u64(llval);
+ } else if (sscanf(opt_string, "bitmap_flush_interval:%u%c", &val, &dummy) == 1) {
+- if (val >= (uint64_t)UINT_MAX * 1000 / HZ) {
++ if ((uint64_t)val >= (uint64_t)UINT_MAX * 1000 / HZ) {
+ r = -EINVAL;
+ ti->error = "Invalid bitmap_flush_interval argument";
+ goto bad;
+--
+2.43.0
+
diff --git a/queue-5.4/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch b/queue-5.4/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch
new file mode 100644
index 0000000000..8a0fa24b7d
--- /dev/null
+++ b/queue-5.4/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch
@@ -0,0 +1,75 @@
+From af643bae0299f8f1c1f9eea36caf788a0bfea3ef Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 5 Mar 2024 17:02:02 +0100
+Subject: ixgbe: avoid sleeping allocation in ixgbe_ipsec_vf_add_sa()
+
+From: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+
+[ Upstream commit aec806fb4afba5fe80b09e29351379a4292baa43 ]
+
+Change kzalloc() flags used in ixgbe_ipsec_vf_add_sa() to GFP_ATOMIC, to
+avoid sleeping in IRQ context.
+
+Dan Carpenter, with the help of Smatch, has found following issue:
+The patch eda0333ac293: "ixgbe: add VF IPsec management" from Aug 13,
+2018 (linux-next), leads to the following Smatch static checker
+warning: drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c:917 ixgbe_ipsec_vf_add_sa()
+ warn: sleeping in IRQ context
+
+The call tree that Smatch is worried about is:
+ixgbe_msix_other() <- IRQ handler
+-> ixgbe_msg_task()
+ -> ixgbe_rcv_msg_from_vf()
+ -> ixgbe_ipsec_vf_add_sa()
+
+Fixes: eda0333ac293 ("ixgbe: add VF IPsec management")
+Reported-by: Dan Carpenter <dan.carpenter@linaro.org>
+Link: https://lore.kernel.org/intel-wired-lan/db31a0b0-4d9f-4e6b-aed8-88266eb5665c@moroto.mountain
+Reviewed-by: Michal Kubiak <michal.kubiak@intel.com>
+Signed-off-by: Przemek Kitszel <przemyslaw.kitszel@intel.com>
+Reviewed-by: Shannon Nelson <shannon.nelson@amd.com>
+Tested-by: Pucha Himasekhar Reddy <himasekharx.reddy.pucha@intel.com> (A Contingent worker at Intel)
+Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c | 16 ++++++++--------
+ 1 file changed, 8 insertions(+), 8 deletions(-)
+
+diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+index 5799b434165e0..bd2b0f4466c64 100644
+--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
++++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ipsec.c
+@@ -909,7 +909,13 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
+ goto err_out;
+ }
+
+- xs = kzalloc(sizeof(*xs), GFP_KERNEL);
++ algo = xfrm_aead_get_byname(aes_gcm_name, IXGBE_IPSEC_AUTH_BITS, 1);
++ if (unlikely(!algo)) {
++ err = -ENOENT;
++ goto err_out;
++ }
++
++ xs = kzalloc(sizeof(*xs), GFP_ATOMIC);
+ if (unlikely(!xs)) {
+ err = -ENOMEM;
+ goto err_out;
+@@ -925,14 +931,8 @@ int ixgbe_ipsec_vf_add_sa(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
+ memcpy(&xs->id.daddr.a4, sam->addr, sizeof(xs->id.daddr.a4));
+ xs->xso.dev = adapter->netdev;
+
+- algo = xfrm_aead_get_byname(aes_gcm_name, IXGBE_IPSEC_AUTH_BITS, 1);
+- if (unlikely(!algo)) {
+- err = -ENOENT;
+- goto err_xs;
+- }
+-
+ aead_len = sizeof(*xs->aead) + IXGBE_IPSEC_KEY_BITS / 8;
+- xs->aead = kzalloc(aead_len, GFP_KERNEL);
++ xs->aead = kzalloc(aead_len, GFP_ATOMIC);
+ if (unlikely(!xs->aead)) {
+ err = -ENOMEM;
+ goto err_xs;
+--
+2.43.0
+
diff --git a/queue-5.4/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch b/queue-5.4/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch
new file mode 100644
index 0000000000..75d522663f
--- /dev/null
+++ b/queue-5.4/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch
@@ -0,0 +1,53 @@
+From a41e9545fd4c784af0767cd6dfe6996a548d32d8 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Wed, 20 Mar 2024 09:54:10 +0900
+Subject: nfc: nci: Fix uninit-value in nci_dev_up and nci_ntf_packet
+
+From: Ryosuke Yasuoka <ryasuoka@redhat.com>
+
+[ Upstream commit d24b03535e5eb82e025219c2f632b485409c898f ]
+
+syzbot reported the following uninit-value access issue [1][2]:
+
+nci_rx_work() parses and processes received packet. When the payload
+length is zero, each message type handler reads uninitialized payload
+and KMSAN detects this issue. The receipt of a packet with a zero-size
+payload is considered unexpected, and therefore, such packets should be
+silently discarded.
+
+This patch resolved this issue by checking payload size before calling
+each message type handler codes.
+
+Fixes: 6a2968aaf50c ("NFC: basic NCI protocol implementation")
+Reported-and-tested-by: syzbot+7ea9413ea6749baf5574@syzkaller.appspotmail.com
+Reported-and-tested-by: syzbot+29b5ca705d2e0f4a44d2@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=7ea9413ea6749baf5574 [1]
+Closes: https://syzkaller.appspot.com/bug?extid=29b5ca705d2e0f4a44d2 [2]
+Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com>
+Reviewed-by: Jeremy Cline <jeremy@jcline.org>
+Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ net/nfc/nci/core.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
+index cb2193dec7129..701c3752bda09 100644
+--- a/net/nfc/nci/core.c
++++ b/net/nfc/nci/core.c
+@@ -1499,6 +1499,11 @@ static void nci_rx_work(struct work_struct *work)
+ nfc_send_to_raw_sock(ndev->nfc_dev, skb,
+ RAW_PAYLOAD_NCI, NFC_DIRECTION_RX);
+
++ if (!nci_plen(skb->data)) {
++ kfree_skb(skb);
++ break;
++ }
++
+ /* Process frame */
+ switch (nci_mt(skb->data)) {
+ case NCI_MT_RSP_PKT:
+--
+2.43.0
+
diff --git a/queue-5.4/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch b/queue-5.4/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch
new file mode 100644
index 0000000000..cd53ae1825
--- /dev/null
+++ b/queue-5.4/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch
@@ -0,0 +1,62 @@
+From ef0d8f9db4d00b22a968c7a95002183fccb8728e Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 14:14:12 +0000
+Subject: scsi: libsas: Add a helper sas_get_sas_addr_and_dev_type()
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit a57345279fd311ba679b8083feb0eec5272c7729 ]
+
+Add a helper to get attached_sas_addr and device type from disc_resp.
+
+Suggested-by: John Garry <john.g.garry@oracle.com>
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Link: https://lore.kernel.org/r/20240307141413.48049-2-yangxingui@huawei.com
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 8e68a458bcf5 ("scsi: libsas: Fix disk not being scanned in after being removed")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/libsas/sas_expander.c | 19 ++++++++++++-------
+ 1 file changed, 12 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
+index 09a78db60ac55..91902799b7352 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -1672,6 +1672,16 @@ int sas_discover_root_expander(struct domain_device *dev)
+
+ /* ---------- Domain revalidation ---------- */
+
++static void sas_get_sas_addr_and_dev_type(struct smp_disc_resp *disc_resp,
++ u8 *sas_addr,
++ enum sas_device_type *type)
++{
++ memcpy(sas_addr, disc_resp->disc.attached_sas_addr, SAS_ADDR_SIZE);
++ *type = to_dev_type(&disc_resp->disc);
++ if (*type == SAS_PHY_UNUSED)
++ memset(sas_addr, 0, SAS_ADDR_SIZE);
++}
++
+ static int sas_get_phy_discover(struct domain_device *dev,
+ int phy_id, struct smp_disc_resp *disc_resp)
+ {
+@@ -1725,13 +1735,8 @@ static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
+ return -ENOMEM;
+
+ res = sas_get_phy_discover(dev, phy_id, disc_resp);
+- if (res == 0) {
+- memcpy(sas_addr, disc_resp->disc.attached_sas_addr,
+- SAS_ADDR_SIZE);
+- *type = to_dev_type(&disc_resp->disc);
+- if (*type == 0)
+- memset(sas_addr, 0, SAS_ADDR_SIZE);
+- }
++ if (res == 0)
++ sas_get_sas_addr_and_dev_type(disc_resp, sas_addr, type);
+ kfree(disc_resp);
+ return res;
+ }
+--
+2.43.0
+
diff --git a/queue-5.4/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch b/queue-5.4/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch
new file mode 100644
index 0000000000..727198440c
--- /dev/null
+++ b/queue-5.4/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch
@@ -0,0 +1,116 @@
+From 4f65b7d8406529393017ab6273d143b5aee829ed Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 7 Mar 2024 14:14:13 +0000
+Subject: scsi: libsas: Fix disk not being scanned in after being removed
+
+From: Xingui Yang <yangxingui@huawei.com>
+
+[ Upstream commit 8e68a458bcf5b5cb9c3624598bae28f08251601f ]
+
+As of commit d8649fc1c5e4 ("scsi: libsas: Do discovery on empty PHY to
+update PHY info"), do discovery will send a new SMP_DISCOVER and update
+phy->phy_change_count. We found that if the disk is reconnected and phy
+change_count changes at this time, the disk scanning process will not be
+triggered.
+
+Therefore, call sas_set_ex_phy() to update the PHY info with the results of
+the last query. And because the previous phy info will be used when calling
+sas_unregister_devs_sas_addr(), sas_unregister_devs_sas_addr() should be
+called before sas_set_ex_phy().
+
+Fixes: d8649fc1c5e4 ("scsi: libsas: Do discovery on empty PHY to update PHY info")
+Signed-off-by: Xingui Yang <yangxingui@huawei.com>
+Link: https://lore.kernel.org/r/20240307141413.48049-3-yangxingui@huawei.com
+Reviewed-by: John Garry <john.g.garry@oracle.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/libsas/sas_expander.c | 32 ++++++++++++++++++++----------
+ 1 file changed, 22 insertions(+), 10 deletions(-)
+
+diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
+index 91902799b7352..cf1df38a189c5 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -1998,6 +1998,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
+ struct expander_device *ex = &dev->ex_dev;
+ struct ex_phy *phy = &ex->ex_phy[phy_id];
+ enum sas_device_type type = SAS_PHY_UNUSED;
++ struct smp_disc_resp *disc_resp;
+ u8 sas_addr[SAS_ADDR_SIZE];
+ char msg[80] = "";
+ int res;
+@@ -2009,33 +2010,41 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
+ SAS_ADDR(dev->sas_addr), phy_id, msg);
+
+ memset(sas_addr, 0, SAS_ADDR_SIZE);
+- res = sas_get_phy_attached_dev(dev, phy_id, sas_addr, &type);
++ disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
++ if (!disc_resp)
++ return -ENOMEM;
++
++ res = sas_get_phy_discover(dev, phy_id, disc_resp);
+ switch (res) {
+ case SMP_RESP_NO_PHY:
+ phy->phy_state = PHY_NOT_PRESENT;
+ sas_unregister_devs_sas_addr(dev, phy_id, last);
+- return res;
++ goto out_free_resp;
+ case SMP_RESP_PHY_VACANT:
+ phy->phy_state = PHY_VACANT;
+ sas_unregister_devs_sas_addr(dev, phy_id, last);
+- return res;
++ goto out_free_resp;
+ case SMP_RESP_FUNC_ACC:
+ break;
+ case -ECOMM:
+ break;
+ default:
+- return res;
++ goto out_free_resp;
+ }
+
++ if (res == 0)
++ sas_get_sas_addr_and_dev_type(disc_resp, sas_addr, &type);
++
+ if ((SAS_ADDR(sas_addr) == 0) || (res == -ECOMM)) {
+ phy->phy_state = PHY_EMPTY;
+ sas_unregister_devs_sas_addr(dev, phy_id, last);
+ /*
+- * Even though the PHY is empty, for convenience we discover
+- * the PHY to update the PHY info, like negotiated linkrate.
++ * Even though the PHY is empty, for convenience we update
++ * the PHY info, like negotiated linkrate.
+ */
+- sas_ex_phy_discover(dev, phy_id);
+- return res;
++ if (res == 0)
++ sas_set_ex_phy(dev, phy_id, disc_resp);
++ goto out_free_resp;
+ } else if (SAS_ADDR(sas_addr) == SAS_ADDR(phy->attached_sas_addr) &&
+ dev_type_flutter(type, phy->attached_dev_type)) {
+ struct domain_device *ata_dev = sas_ex_to_ata(dev, phy_id);
+@@ -2047,7 +2056,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
+ action = ", needs recovery";
+ pr_debug("ex %016llx phy%02d broadcast flutter%s\n",
+ SAS_ADDR(dev->sas_addr), phy_id, action);
+- return res;
++ goto out_free_resp;
+ }
+
+ /* we always have to delete the old device when we went here */
+@@ -2056,7 +2065,10 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id,
+ SAS_ADDR(phy->attached_sas_addr));
+ sas_unregister_devs_sas_addr(dev, phy_id, last);
+
+- return sas_discover_new(dev, phy_id);
++ res = sas_discover_new(dev, phy_id);
++out_free_resp:
++ kfree(disc_resp);
++ return res;
+ }
+
+ /**
+--
+2.43.0
+
diff --git a/queue-5.4/scsi-libsas-introduce-struct-smp_disc_resp.patch b/queue-5.4/scsi-libsas-introduce-struct-smp_disc_resp.patch
new file mode 100644
index 0000000000..43c0d748f0
--- /dev/null
+++ b/queue-5.4/scsi-libsas-introduce-struct-smp_disc_resp.patch
@@ -0,0 +1,217 @@
+From 7d999ec184189bfbd157a086f5e863bc7cff1439 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 9 Jun 2022 11:24:54 +0900
+Subject: scsi: libsas: Introduce struct smp_disc_resp
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+
+[ Upstream commit c3752f44604f3bc4f3ce6e169fa32d16943ff70b ]
+
+When compiling with gcc 12, several warnings are thrown by gcc when
+compiling drivers/scsi/libsas/sas_expander.c, e.g.:
+
+In function ‘sas_get_phy_change_count’,
+ inlined from ‘sas_find_bcast_phy.constprop’ at
+drivers/scsi/libsas/sas_expander.c:1737:9:
+drivers/scsi/libsas/sas_expander.c:1697:39: warning: array subscript
+‘struct smp_resp[0]’ is partly outside array bounds of ‘unsigned
+char[56]’ [-Warray-bounds]
+ 1697 | *pcc = disc_resp->disc.change_count;
+ | ~~~~~~~~~~~~~~~^~~~~~~~~~~~~
+
+This is due to the use of the struct smp_resp to aggregate all possible
+response types using a union but allocating a response buffer with a size
+exactly equal to the size of the response type needed. This leads to access
+to fields of struct smp_resp from an allocated memory area that is smaller
+than the size of struct smp_resp.
+
+Fix this by defining struct smp_disc_resp for sas discovery operations.
+Since this structure and the generic struct smp_resp are identical for
+the little endian and big endian archs, move the definition of these
+structures at the end of include/scsi/sas.h to avoid repeating their
+definition.
+
+Link: https://lore.kernel.org/r/20220609022456.409087-2-damien.lemoal@opensource.wdc.com
+Reviewed-by: John Garry <john.garry@huawei.com>
+Signed-off-by: Damien Le Moal <damien.lemoal@opensource.wdc.com>
+Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
+Stable-dep-of: 8e68a458bcf5 ("scsi: libsas: Fix disk not being scanned in after being removed")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ drivers/scsi/libsas/sas_expander.c | 32 +++++++++++++-----------------
+ include/scsi/sas.h | 28 +++++++++++---------------
+ 2 files changed, 26 insertions(+), 34 deletions(-)
+
+diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
+index 173f91ae38f02..09a78db60ac55 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -192,13 +192,13 @@ static enum sas_device_type to_dev_type(struct discover_resp *dr)
+ return dr->attached_dev_type;
+ }
+
+-static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
++static void sas_set_ex_phy(struct domain_device *dev, int phy_id,
++ struct smp_disc_resp *disc_resp)
+ {
+ enum sas_device_type dev_type;
+ enum sas_linkrate linkrate;
+ u8 sas_addr[SAS_ADDR_SIZE];
+- struct smp_resp *resp = rsp;
+- struct discover_resp *dr = &resp->disc;
++ struct discover_resp *dr = &disc_resp->disc;
+ struct sas_ha_struct *ha = dev->port->ha;
+ struct expander_device *ex = &dev->ex_dev;
+ struct ex_phy *phy = &ex->ex_phy[phy_id];
+@@ -215,7 +215,7 @@ static void sas_set_ex_phy(struct domain_device *dev, int phy_id, void *rsp)
+ BUG_ON(!phy->phy);
+ }
+
+- switch (resp->result) {
++ switch (disc_resp->result) {
+ case SMP_RESP_PHY_VACANT:
+ phy->phy_state = PHY_VACANT;
+ break;
+@@ -364,12 +364,13 @@ struct domain_device *sas_ex_to_ata(struct domain_device *ex_dev, int phy_id)
+ }
+
+ #define DISCOVER_REQ_SIZE 16
+-#define DISCOVER_RESP_SIZE 56
++#define DISCOVER_RESP_SIZE sizeof(struct smp_disc_resp)
+
+ static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
+- u8 *disc_resp, int single)
++ struct smp_disc_resp *disc_resp,
++ int single)
+ {
+- struct discover_resp *dr;
++ struct discover_resp *dr = &disc_resp->disc;
+ int res;
+
+ disc_req[9] = single;
+@@ -378,7 +379,6 @@ static int sas_ex_phy_discover_helper(struct domain_device *dev, u8 *disc_req,
+ disc_resp, DISCOVER_RESP_SIZE);
+ if (res)
+ return res;
+- dr = &((struct smp_resp *)disc_resp)->disc;
+ if (memcmp(dev->sas_addr, dr->attached_sas_addr, SAS_ADDR_SIZE) == 0) {
+ pr_notice("Found loopback topology, just ignore it!\n");
+ return 0;
+@@ -392,7 +392,7 @@ int sas_ex_phy_discover(struct domain_device *dev, int single)
+ struct expander_device *ex = &dev->ex_dev;
+ int res = 0;
+ u8 *disc_req;
+- u8 *disc_resp;
++ struct smp_disc_resp *disc_resp;
+
+ disc_req = alloc_smp_req(DISCOVER_REQ_SIZE);
+ if (!disc_req)
+@@ -1673,7 +1673,7 @@ int sas_discover_root_expander(struct domain_device *dev)
+ /* ---------- Domain revalidation ---------- */
+
+ static int sas_get_phy_discover(struct domain_device *dev,
+- int phy_id, struct smp_resp *disc_resp)
++ int phy_id, struct smp_disc_resp *disc_resp)
+ {
+ int res;
+ u8 *disc_req;
+@@ -1689,10 +1689,8 @@ static int sas_get_phy_discover(struct domain_device *dev,
+ disc_resp, DISCOVER_RESP_SIZE);
+ if (res)
+ goto out;
+- else if (disc_resp->result != SMP_RESP_FUNC_ACC) {
++ if (disc_resp->result != SMP_RESP_FUNC_ACC)
+ res = disc_resp->result;
+- goto out;
+- }
+ out:
+ kfree(disc_req);
+ return res;
+@@ -1702,7 +1700,7 @@ static int sas_get_phy_change_count(struct domain_device *dev,
+ int phy_id, int *pcc)
+ {
+ int res;
+- struct smp_resp *disc_resp;
++ struct smp_disc_resp *disc_resp;
+
+ disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
+ if (!disc_resp)
+@@ -1720,19 +1718,17 @@ static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
+ u8 *sas_addr, enum sas_device_type *type)
+ {
+ int res;
+- struct smp_resp *disc_resp;
+- struct discover_resp *dr;
++ struct smp_disc_resp *disc_resp;
+
+ disc_resp = alloc_smp_resp(DISCOVER_RESP_SIZE);
+ if (!disc_resp)
+ return -ENOMEM;
+- dr = &disc_resp->disc;
+
+ res = sas_get_phy_discover(dev, phy_id, disc_resp);
+ if (res == 0) {
+ memcpy(sas_addr, disc_resp->disc.attached_sas_addr,
+ SAS_ADDR_SIZE);
+- *type = to_dev_type(dr);
++ *type = to_dev_type(&disc_resp->disc);
+ if (*type == 0)
+ memset(sas_addr, 0, SAS_ADDR_SIZE);
+ }
+diff --git a/include/scsi/sas.h b/include/scsi/sas.h
+index a5d8ae49198cb..d9a09ca957594 100644
+--- a/include/scsi/sas.h
++++ b/include/scsi/sas.h
+@@ -460,18 +460,6 @@ struct report_phy_sata_resp {
+ __be32 crc;
+ } __attribute__ ((packed));
+
+-struct smp_resp {
+- u8 frame_type;
+- u8 function;
+- u8 result;
+- u8 reserved;
+- union {
+- struct report_general_resp rg;
+- struct discover_resp disc;
+- struct report_phy_sata_resp rps;
+- };
+-} __attribute__ ((packed));
+-
+ #elif defined(__BIG_ENDIAN_BITFIELD)
+ struct sas_identify_frame {
+ /* Byte 0 */
+@@ -691,6 +679,18 @@ struct report_phy_sata_resp {
+ __be32 crc;
+ } __attribute__ ((packed));
+
++#else
++#error "Bitfield order not defined!"
++#endif
++
++struct smp_disc_resp {
++ u8 frame_type;
++ u8 function;
++ u8 result;
++ u8 reserved;
++ struct discover_resp disc;
++} __attribute__ ((packed));
++
+ struct smp_resp {
+ u8 frame_type;
+ u8 function;
+@@ -703,8 +703,4 @@ struct smp_resp {
+ };
+ } __attribute__ ((packed));
+
+-#else
+-#error "Bitfield order not defined!"
+-#endif
+-
+ #endif /* _SAS_H_ */
+--
+2.43.0
+
diff --git a/queue-5.4/series b/queue-5.4/series
index f3c6022f54..fcd14c0326 100644
--- a/queue-5.4/series
+++ b/queue-5.4/series
@@ -126,3 +126,10 @@ scsi-qla2xxx-fix-command-flush-on-cable-pull.patch
x86-cpu-enable-stibp-on-amd-if-automatic-ibrs-is-enabled.patch
scsi-lpfc-correct-size-for-wqe-for-memset.patch
usb-core-fix-deadlock-in-usb_deauthorize_interface.patch
+scsi-libsas-introduce-struct-smp_disc_resp.patch
+scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch
+scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch
+nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch
+ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch
+tcp-properly-terminate-timers-for-kernel-sockets.patch
+dm-integrity-fix-out-of-range-warning.patch
diff --git a/queue-5.4/tcp-properly-terminate-timers-for-kernel-sockets.patch b/queue-5.4/tcp-properly-terminate-timers-for-kernel-sockets.patch
new file mode 100644
index 0000000000..2a6fc69669
--- /dev/null
+++ b/queue-5.4/tcp-properly-terminate-timers-for-kernel-sockets.patch
@@ -0,0 +1,138 @@
+From 73d3fdae1c00ffcdda8e12c222100df6f5980d83 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 22 Mar 2024 13:57:32 +0000
+Subject: tcp: properly terminate timers for kernel sockets
+
+From: Eric Dumazet <edumazet@google.com>
+
+[ Upstream commit 151c9c724d05d5b0dd8acd3e11cb69ef1f2dbada ]
+
+We had various syzbot reports about tcp timers firing after
+the corresponding netns has been dismantled.
+
+Fortunately Josef Bacik could trigger the issue more often,
+and could test a patch I wrote two years ago.
+
+When TCP sockets are closed, we call inet_csk_clear_xmit_timers()
+to 'stop' the timers.
+
+inet_csk_clear_xmit_timers() can be called from any context,
+including when socket lock is held.
+This is the reason it uses sk_stop_timer(), aka del_timer().
+This means that ongoing timers might finish much later.
+
+For user sockets, this is fine because each running timer
+holds a reference on the socket, and the user socket holds
+a reference on the netns.
+
+For kernel sockets, we risk that the netns is freed before
+timer can complete, because kernel sockets do not hold
+reference on the netns.
+
+This patch adds inet_csk_clear_xmit_timers_sync() function
+that using sk_stop_timer_sync() to make sure all timers
+are terminated before the kernel socket is released.
+Modules using kernel sockets close them in their netns exit()
+handler.
+
+Also add sock_not_owned_by_me() helper to get LOCKDEP
+support : inet_csk_clear_xmit_timers_sync() must not be called
+while socket lock is held.
+
+It is very possible we can revert in the future commit
+3a58f13a881e ("net: rds: acquire refcount on TCP sockets")
+which attempted to solve the issue in rds only.
+(net/smc/af_smc.c and net/mptcp/subflow.c have similar code)
+
+We probably can remove the check_net() tests from
+tcp_out_of_resources() and __tcp_close() in the future.
+
+Reported-by: Josef Bacik <josef@toxicpanda.com>
+Closes: https://lore.kernel.org/netdev/20240314210740.GA2823176@perftesting/
+Fixes: 26abe14379f8 ("net: Modify sk_alloc to not reference count the netns of kernel sockets.")
+Fixes: 8a68173691f0 ("net: sk_clone_lock() should only do get_net() if the parent is not a kernel socket")
+Link: https://lore.kernel.org/bpf/CANn89i+484ffqb93aQm1N-tjxxvb3WDKX0EbD7318RwRgsatjw@mail.gmail.com/
+Signed-off-by: Eric Dumazet <edumazet@google.com>
+Tested-by: Josef Bacik <josef@toxicpanda.com>
+Cc: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
+Link: https://lore.kernel.org/r/20240322135732.1535772-1-edumazet@google.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/inet_connection_sock.h | 1 +
+ include/net/sock.h | 7 +++++++
+ net/ipv4/inet_connection_sock.c | 14 ++++++++++++++
+ net/ipv4/tcp.c | 2 ++
+ 4 files changed, 24 insertions(+)
+
+diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
+index 13792c0ef46e3..180ff3ca823a9 100644
+--- a/include/net/inet_connection_sock.h
++++ b/include/net/inet_connection_sock.h
+@@ -176,6 +176,7 @@ void inet_csk_init_xmit_timers(struct sock *sk,
+ void (*delack_handler)(struct timer_list *),
+ void (*keepalive_handler)(struct timer_list *));
+ void inet_csk_clear_xmit_timers(struct sock *sk);
++void inet_csk_clear_xmit_timers_sync(struct sock *sk);
+
+ static inline void inet_csk_schedule_ack(struct sock *sk)
+ {
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 5293f2b65fb55..8d592df7251f8 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1605,6 +1605,13 @@ static inline void sock_owned_by_me(const struct sock *sk)
+ #endif
+ }
+
++static inline void sock_not_owned_by_me(const struct sock *sk)
++{
++#ifdef CONFIG_LOCKDEP
++ WARN_ON_ONCE(lockdep_sock_is_held(sk) && debug_locks);
++#endif
++}
++
+ static inline bool sock_owned_by_user(const struct sock *sk)
+ {
+ sock_owned_by_me(sk);
+diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
+index 374a0c3f39cc1..091999dbef335 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -560,6 +560,20 @@ void inet_csk_clear_xmit_timers(struct sock *sk)
+ }
+ EXPORT_SYMBOL(inet_csk_clear_xmit_timers);
+
++void inet_csk_clear_xmit_timers_sync(struct sock *sk)
++{
++ struct inet_connection_sock *icsk = inet_csk(sk);
++
++ /* ongoing timer handlers need to acquire socket lock. */
++ sock_not_owned_by_me(sk);
++
++ icsk->icsk_pending = icsk->icsk_ack.pending = 0;
++
++ sk_stop_timer_sync(sk, &icsk->icsk_retransmit_timer);
++ sk_stop_timer_sync(sk, &icsk->icsk_delack_timer);
++ sk_stop_timer_sync(sk, &sk->sk_timer);
++}
++
+ void inet_csk_delete_keepalive_timer(struct sock *sk)
+ {
+ sk_stop_timer(sk, &sk->sk_timer);
+diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
+index 8ebcff40bc5ac..ca7863f722187 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -2529,6 +2529,8 @@ void tcp_close(struct sock *sk, long timeout)
+ lock_sock(sk);
+ __tcp_close(sk, timeout);
+ release_sock(sk);
++ if (!sk->sk_net_refcnt)
++ inet_csk_clear_xmit_timers_sync(sk);
+ sock_put(sk);
+ }
+ EXPORT_SYMBOL(tcp_close);
+--
+2.43.0
+