From: Sasha Levin Date: Wed, 3 Apr 2024 15:59:49 +0000 (-0400) Subject: Fixes for 5.10 X-Git-Tag: v6.6.25~18^2~2 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=dc7572bcccafa012a744b4cbfa9b453ad527bee5;p=thirdparty%2Fkernel%2Fstable-queue.git Fixes for 5.10 Signed-off-by: Sasha Levin --- diff --git a/queue-5.10/acpica-debugger-check-status-of-acpi_evaluate_object.patch b/queue-5.10/acpica-debugger-check-status-of-acpi_evaluate_object.patch new file mode 100644 index 00000000000..81c1b0ff8b7 --- /dev/null +++ b/queue-5.10/acpica-debugger-check-status-of-acpi_evaluate_object.patch @@ -0,0 +1,53 @@ +From d6740302dc309e86db8e55fad8d4f8aa1ec99a32 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Mar 2024 21:07:53 +0300 +Subject: ACPICA: debugger: check status of acpi_evaluate_object() in + acpi_db_walk_for_fields() + +From: Nikita Kiryushin + +[ Upstream commit 40e2710860e57411ab57a1529c5a2748abbe8a19 ] + +ACPICA commit 9061cd9aa131205657c811a52a9f8325a040c6c9 + +Errors in acpi_evaluate_object() can lead to incorrect state of buffer. + +This can lead to access to data in previously ACPI_FREEd buffer and +secondary ACPI_FREE to the same buffer later. + +Handle errors in acpi_evaluate_object the same way it is done earlier +with acpi_ns_handle_to_pathname. + +Found by Linux Verification Center (linuxtesting.org) with SVACE. + +Link: https://github.com/acpica/acpica/commit/9061cd9a +Fixes: 5fd033288a86 ("ACPICA: debugger: add command to dump all fields of particular subtype") +Signed-off-by: Nikita Kiryushin +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/acpi/acpica/dbnames.c | 8 ++++++-- + 1 file changed, 6 insertions(+), 2 deletions(-) + +diff --git a/drivers/acpi/acpica/dbnames.c b/drivers/acpi/acpica/dbnames.c +index b91155ea9c343..c9131259f717b 100644 +--- a/drivers/acpi/acpica/dbnames.c ++++ b/drivers/acpi/acpica/dbnames.c +@@ -550,8 +550,12 @@ acpi_db_walk_for_fields(acpi_handle obj_handle, + ACPI_FREE(buffer.pointer); + + buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER; +- acpi_evaluate_object(obj_handle, NULL, NULL, &buffer); +- ++ status = acpi_evaluate_object(obj_handle, NULL, NULL, &buffer); ++ if (ACPI_FAILURE(status)) { ++ acpi_os_printf("Could Not evaluate object %p\n", ++ obj_handle); ++ return (AE_OK); ++ } + /* + * Since this is a field unit, surround the output in braces + */ +-- +2.43.0 + diff --git a/queue-5.10/bpf-protect-against-int-overflow-for-stack-access-si.patch b/queue-5.10/bpf-protect-against-int-overflow-for-stack-access-si.patch new file mode 100644 index 00000000000..e9ef1a5f980 --- /dev/null +++ b/queue-5.10/bpf-protect-against-int-overflow-for-stack-access-si.patch @@ -0,0 +1,53 @@ +From 3fead47bb090f6780106aa06bc68c4e6b99a3c4e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Mar 2024 22:42:45 -0400 +Subject: bpf: Protect against int overflow for stack access size + +From: Andrei Matei + +[ Upstream commit ecc6a2101840177e57c925c102d2d29f260d37c8 ] + +This patch re-introduces protection against the size of access to stack +memory being negative; the access size can appear negative as a result +of overflowing its signed int representation. This should not actually +happen, as there are other protections along the way, but we should +protect against it anyway. One code path was missing such protections +(fixed in the previous patch in the series), causing out-of-bounds array +accesses in check_stack_range_initialized(). This patch causes the +verification of a program with such a non-sensical access size to fail. + +This check used to exist in a more indirect way, but was inadvertendly +removed in a833a17aeac7. + +Fixes: a833a17aeac7 ("bpf: Fix verification of indirect var-off stack access") +Reported-by: syzbot+33f4297b5f927648741a@syzkaller.appspotmail.com +Reported-by: syzbot+aafd0513053a1cbf52ef@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/bpf/CAADnVQLORV5PT0iTAhRER+iLBTkByCYNBYyvBSgjN1T31K+gOw@mail.gmail.com/ +Acked-by: Andrii Nakryiko +Signed-off-by: Andrei Matei +Link: https://lore.kernel.org/r/20240327024245.318299-3-andreimatei1@gmail.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + kernel/bpf/verifier.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c +index fce2345f600f2..25f8a8716e88d 100644 +--- a/kernel/bpf/verifier.c ++++ b/kernel/bpf/verifier.c +@@ -3941,6 +3941,11 @@ static int check_stack_access_within_bounds( + err = check_stack_slot_within_bounds(min_off, state, type); + if (!err && max_off > 0) + err = -EINVAL; /* out of stack access into non-negative offsets */ ++ if (!err && access_size < 0) ++ /* access_size should not be negative (or overflow an int); others checks ++ * along the way should have prevented such an access. ++ */ ++ err = -EFAULT; /* invalid negative access size; integer overflow? */ + + if (err) { + if (tnum_is_const(reg->var_off)) { +-- +2.43.0 + diff --git a/queue-5.10/dm-integrity-fix-out-of-range-warning.patch b/queue-5.10/dm-integrity-fix-out-of-range-warning.patch new file mode 100644 index 00000000000..cf910629f4c --- /dev/null +++ b/queue-5.10/dm-integrity-fix-out-of-range-warning.patch @@ -0,0 +1,47 @@ +From 4e6e34edb955f093eafac54df1017e77b6ac973d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 28 Mar 2024 15:30:39 +0100 +Subject: dm integrity: fix out-of-range warning + +From: Arnd Bergmann + +[ 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 +Reviewed-by: Mikulas Patocka +Reviewed-by: Justin Stitt +Signed-off-by: Mike Snitzer +Signed-off-by: Sasha Levin +--- + 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 62cae34ca3b43..067be1d9f51cb 100644 +--- a/drivers/md/dm-integrity.c ++++ b/drivers/md/dm-integrity.c +@@ -3937,7 +3937,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.10/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch b/queue-5.10/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch new file mode 100644 index 00000000000..6724886a6b0 --- /dev/null +++ b/queue-5.10/ixgbe-avoid-sleeping-allocation-in-ixgbe_ipsec_vf_ad.patch @@ -0,0 +1,75 @@ +From d58c6fe924b7d78d5d3c8a6f4b28530083c0cb08 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 5 Mar 2024 17:02:02 +0100 +Subject: ixgbe: avoid sleeping allocation in ixgbe_ipsec_vf_add_sa() + +From: Przemek Kitszel + +[ 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 +Link: https://lore.kernel.org/intel-wired-lan/db31a0b0-4d9f-4e6b-aed8-88266eb5665c@moroto.mountain +Reviewed-by: Michal Kubiak +Signed-off-by: Przemek Kitszel +Reviewed-by: Shannon Nelson +Tested-by: Pucha Himasekhar Reddy (A Contingent worker at Intel) +Signed-off-by: Tony Nguyen +Signed-off-by: Sasha Levin +--- + 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 319620856cba1..512da34e70a35 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.10/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch b/queue-5.10/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch new file mode 100644 index 00000000000..0a1d3427333 --- /dev/null +++ b/queue-5.10/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch @@ -0,0 +1,53 @@ +From babf989480070833247b497a07218765511c828f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Reviewed-by: Jeremy Cline +Reviewed-by: Krzysztof Kozlowski +Signed-off-by: David S. Miller +Signed-off-by: Sasha Levin +--- + 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 5bfaf06f7be7f..d8002065baaef 100644 +--- a/net/nfc/nci/core.c ++++ b/net/nfc/nci/core.c +@@ -1502,6 +1502,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.10/octeontx2-af-fix-pause-frame-configuration-in-gmp-mo.patch b/queue-5.10/octeontx2-af-fix-pause-frame-configuration-in-gmp-mo.patch new file mode 100644 index 00000000000..595bc3957d0 --- /dev/null +++ b/queue-5.10/octeontx2-af-fix-pause-frame-configuration-in-gmp-mo.patch @@ -0,0 +1,46 @@ +From 295de9d445d4fd9d45dd4c3d51b8e5f1e7c20777 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 26 Mar 2024 10:57:20 +0530 +Subject: Octeontx2-af: fix pause frame configuration in GMP mode + +From: Hariprasad Kelam + +[ Upstream commit 40d4b4807cadd83fb3f46cc8cd67a945b5b25461 ] + +The Octeontx2 MAC block (CGX) has separate data paths (SMU and GMP) for +different speeds, allowing for efficient data transfer. + +The previous patch which added pause frame configuration has a bug due +to which pause frame feature is not working in GMP mode. + +This patch fixes the issue by configurating appropriate registers. + +Fixes: f7e086e754fe ("octeontx2-af: Pause frame configuration at cgx") +Signed-off-by: Hariprasad Kelam +Reviewed-by: Simon Horman +Link: https://lore.kernel.org/r/20240326052720.4441-1-hkelam@marvell.com +Signed-off-by: Paolo Abeni +Signed-off-by: Sasha Levin +--- + drivers/net/ethernet/marvell/octeontx2/af/cgx.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +index 55dfe1a20bc99..7f82baf8e7403 100644 +--- a/drivers/net/ethernet/marvell/octeontx2/af/cgx.c ++++ b/drivers/net/ethernet/marvell/octeontx2/af/cgx.c +@@ -403,6 +403,11 @@ int cgx_lmac_set_pause_frm(void *cgxd, int lmac_id, + if (!cgx || lmac_id >= cgx->lmac_count) + return -ENODEV; + ++ cfg = cgx_read(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL); ++ cfg &= ~CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK; ++ cfg |= rx_pause ? CGX_GMP_GMI_RXX_FRM_CTL_CTL_BCK : 0x0; ++ cgx_write(cgx, lmac_id, CGXX_GMP_GMI_RXX_FRM_CTL, cfg); ++ + cfg = cgx_read(cgx, lmac_id, CGXX_SMUX_RX_FRM_CTL); + cfg &= ~CGX_SMUX_RX_FRM_CTL_CTL_BCK; + cfg |= rx_pause ? CGX_SMUX_RX_FRM_CTL_CTL_BCK : 0x0; +-- +2.43.0 + diff --git a/queue-5.10/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch b/queue-5.10/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch new file mode 100644 index 00000000000..6d64b0f60b8 --- /dev/null +++ b/queue-5.10/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch @@ -0,0 +1,62 @@ +From e2e6c1ea15d971a9a50863782b72e934c2ff46b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ Upstream commit a57345279fd311ba679b8083feb0eec5272c7729 ] + +Add a helper to get attached_sas_addr and device type from disc_resp. + +Suggested-by: John Garry +Signed-off-by: Xingui Yang +Link: https://lore.kernel.org/r/20240307141413.48049-2-yangxingui@huawei.com +Reviewed-by: John Garry +Signed-off-by: Martin K. Petersen +Stable-dep-of: 8e68a458bcf5 ("scsi: libsas: Fix disk not being scanned in after being removed") +Signed-off-by: Sasha Levin +--- + 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 8b061347a8ac7..a673a08c72126 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.10/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch b/queue-5.10/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch new file mode 100644 index 00000000000..4234c2447a3 --- /dev/null +++ b/queue-5.10/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch @@ -0,0 +1,116 @@ +From 1aa0b9877f985f580d3f7d3e43050ed25faca5cd Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 7 Mar 2024 14:14:13 +0000 +Subject: scsi: libsas: Fix disk not being scanned in after being removed + +From: Xingui Yang + +[ 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 +Link: https://lore.kernel.org/r/20240307141413.48049-3-yangxingui@huawei.com +Reviewed-by: John Garry +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + 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 a673a08c72126..2c857ccf33a21 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.10/scsi-libsas-introduce-struct-smp_disc_resp.patch b/queue-5.10/scsi-libsas-introduce-struct-smp_disc_resp.patch new file mode 100644 index 00000000000..e4409e39e3b --- /dev/null +++ b/queue-5.10/scsi-libsas-introduce-struct-smp_disc_resp.patch @@ -0,0 +1,217 @@ +From 36d4f026f1c3be3035578fee0174d23528d57b02 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +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 + +[ 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 +Signed-off-by: Damien Le Moal +Signed-off-by: Martin K. Petersen +Stable-dep-of: 8e68a458bcf5 ("scsi: libsas: Fix disk not being scanned in after being removed") +Signed-off-by: Sasha Levin +--- + 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 8444a4287ac1c..8b061347a8ac7 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 4726c1bbec659..2f73c24d4c9b9 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.10/series b/queue-5.10/series index 7042e1cbe1f..5188f6894d3 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -179,3 +179,13 @@ x86-cpu-enable-stibp-on-amd-if-automatic-ibrs-is-enabled.patch pci-dpc-quirk-pio-log-size-for-intel-ice-lake-root-ports.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 +acpica-debugger-check-status-of-acpi_evaluate_object.patch +bpf-protect-against-int-overflow-for-stack-access-si.patch +octeontx2-af-fix-pause-frame-configuration-in-gmp-mo.patch +dm-integrity-fix-out-of-range-warning.patch diff --git a/queue-5.10/tcp-properly-terminate-timers-for-kernel-sockets.patch b/queue-5.10/tcp-properly-terminate-timers-for-kernel-sockets.patch new file mode 100644 index 00000000000..3faf41d245d --- /dev/null +++ b/queue-5.10/tcp-properly-terminate-timers-for-kernel-sockets.patch @@ -0,0 +1,138 @@ +From f2e5f33585aa22cc27fb1bcec9c6c6f9e5c5f0f3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 22 Mar 2024 13:57:32 +0000 +Subject: tcp: properly terminate timers for kernel sockets + +From: Eric Dumazet + +[ 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 +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 +Tested-by: Josef Bacik +Cc: Tetsuo Handa +Link: https://lore.kernel.org/r/20240322135732.1535772-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + 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 568121fa0965c..f5967805c33fd 100644 +--- a/include/net/inet_connection_sock.h ++++ b/include/net/inet_connection_sock.h +@@ -172,6 +172,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 87ee284ea9cb3..8bcc96bf291c3 100644 +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1681,6 +1681,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 b15c9ad0095a2..6ebe43b4d28f7 100644 +--- a/net/ipv4/inet_connection_sock.c ++++ b/net/ipv4/inet_connection_sock.c +@@ -580,6 +580,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 2e874ec859715..ac6cb2dc60380 100644 +--- a/net/ipv4/tcp.c ++++ b/net/ipv4/tcp.c +@@ -2717,6 +2717,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 +