]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
Fixes for 4.19
authorSasha Levin <sashal@kernel.org>
Wed, 3 Apr 2024 15:59:50 +0000 (11:59 -0400)
committerSasha Levin <sashal@kernel.org>
Wed, 3 Apr 2024 15:59:50 +0000 (11:59 -0400)
Signed-off-by: Sasha Levin <sashal@kernel.org>
queue-4.19/mptcp-add-sk_stop_timer_sync-helper.patch [new file with mode: 0644]
queue-4.19/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch [new file with mode: 0644]
queue-4.19/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch [new file with mode: 0644]
queue-4.19/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch [new file with mode: 0644]
queue-4.19/scsi-libsas-introduce-struct-smp_disc_resp.patch [new file with mode: 0644]
queue-4.19/scsi-libsas-stop-hardcoding-sas-address-length.patch [new file with mode: 0644]
queue-4.19/scsi-libsas-use-pr_fmt-fmt.patch [new file with mode: 0644]
queue-4.19/series
queue-4.19/tcp-properly-terminate-timers-for-kernel-sockets.patch [new file with mode: 0644]

diff --git a/queue-4.19/mptcp-add-sk_stop_timer_sync-helper.patch b/queue-4.19/mptcp-add-sk_stop_timer_sync-helper.patch
new file mode 100644 (file)
index 0000000..94fac2f
--- /dev/null
@@ -0,0 +1,57 @@
+From 5f74f96173e3cfa084a07b98e927f8d86bcda30f Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 24 Sep 2020 08:30:01 +0800
+Subject: mptcp: add sk_stop_timer_sync helper
+
+From: Geliang Tang <geliangtang@gmail.com>
+
+[ Upstream commit 08b81d873126b413cda511b1ea1cbb0e99938bbd ]
+
+This patch added a new helper sk_stop_timer_sync, it deactivates a timer
+like sk_stop_timer, but waits for the handler to finish.
+
+Acked-by: Paolo Abeni <pabeni@redhat.com>
+Signed-off-by: Geliang Tang <geliangtang@gmail.com>
+Reviewed-by: Mat Martineau <mathew.j.martineau@linux.intel.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Stable-dep-of: 151c9c724d05 ("tcp: properly terminate timers for kernel sockets")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+---
+ include/net/sock.h | 2 ++
+ net/core/sock.c    | 7 +++++++
+ 2 files changed, 9 insertions(+)
+
+diff --git a/include/net/sock.h b/include/net/sock.h
+index 81888513b3b93..8eea17a41c1ca 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -2194,6 +2194,8 @@ void sk_reset_timer(struct sock *sk, struct timer_list *timer,
+ void sk_stop_timer(struct sock *sk, struct timer_list *timer);
++void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer);
++
+ int __sk_queue_drop_skb(struct sock *sk, struct sk_buff_head *sk_queue,
+                       struct sk_buff *skb, unsigned int flags,
+                       void (*destructor)(struct sock *sk,
+diff --git a/net/core/sock.c b/net/core/sock.c
+index 62d169bcfcfa1..eaa6f1ca414d0 100644
+--- a/net/core/sock.c
++++ b/net/core/sock.c
+@@ -2804,6 +2804,13 @@ void sk_stop_timer(struct sock *sk, struct timer_list* timer)
+ }
+ EXPORT_SYMBOL(sk_stop_timer);
++void sk_stop_timer_sync(struct sock *sk, struct timer_list *timer)
++{
++      if (del_timer_sync(timer))
++              __sock_put(sk);
++}
++EXPORT_SYMBOL(sk_stop_timer_sync);
++
+ void sock_init_data(struct socket *sock, struct sock *sk)
+ {
+       sk_init_common(sk);
+-- 
+2.43.0
+
diff --git a/queue-4.19/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch b/queue-4.19/nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch
new file mode 100644 (file)
index 0000000..88867c1
--- /dev/null
@@ -0,0 +1,53 @@
+From 4564cb60ff13fce62644da4f18d39592f6560092 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 2e885b7a02a15..1f863ccf21211 100644
+--- a/net/nfc/nci/core.c
++++ b/net/nfc/nci/core.c
+@@ -1511,6 +1511,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-4.19/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch b/queue-4.19/scsi-libsas-add-a-helper-sas_get_sas_addr_and_dev_ty.patch
new file mode 100644 (file)
index 0000000..18e8904
--- /dev/null
@@ -0,0 +1,62 @@
+From 67f38b87a3720b72751f38d633893d5a1927f409 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 aaa3bc79517db..8c7c970274c9c 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -1719,6 +1719,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)
+ {
+@@ -1772,13 +1782,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-4.19/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch b/queue-4.19/scsi-libsas-fix-disk-not-being-scanned-in-after-bein.patch
new file mode 100644 (file)
index 0000000..4948f5d
--- /dev/null
@@ -0,0 +1,113 @@
+From cf25330b61d2c9d4a3879e831dfa9c0a7e2411b4 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 8c7c970274c9c..988c0db37458d 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -2046,37 +2046,46 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last)
+       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];
+       int res;
+       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);
+@@ -2088,7 +2097,7 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last)
+                       action = ", needs recovery";
+               SAS_DPRINTK("ex %016llx phy 0x%x 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 */
+@@ -2097,7 +2106,10 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last)
+                   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-4.19/scsi-libsas-introduce-struct-smp_disc_resp.patch b/queue-4.19/scsi-libsas-introduce-struct-smp_disc_resp.patch
new file mode 100644 (file)
index 0000000..6b54c47
--- /dev/null
@@ -0,0 +1,217 @@
+From e7769bc15d1cb9dc507bc0d38a0d8b34fded9bce 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 dd21d1331db31..aaa3bc79517db 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -205,13 +205,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];
+@@ -228,7 +228,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;
+@@ -377,12 +377,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;
+@@ -391,7 +392,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) {
+               sas_printk("Found loopback topology, just ignore it!\n");
+               return 0;
+@@ -405,7 +405,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)
+@@ -1720,7 +1720,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;
+@@ -1736,10 +1736,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;
+@@ -1749,7 +1747,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)
+@@ -1767,19 +1765,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 42a84ef42683a..f3a68b6464f36 100644
+--- a/include/scsi/sas.h
++++ b/include/scsi/sas.h
+@@ -477,18 +477,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 */
+@@ -708,6 +696,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;
+@@ -720,8 +720,4 @@ struct smp_resp {
+       };
+ } __attribute__ ((packed));
+-#else
+-#error "Bitfield order not defined!"
+-#endif
+-
+ #endif /* _SAS_H_ */
+-- 
+2.43.0
+
diff --git a/queue-4.19/scsi-libsas-stop-hardcoding-sas-address-length.patch b/queue-4.19/scsi-libsas-stop-hardcoding-sas-address-length.patch
new file mode 100644 (file)
index 0000000..7a74016
--- /dev/null
@@ -0,0 +1,157 @@
+From 6e6a45a7df69b2b9793a9ca748eb4a1cd8bd1a24 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Fri, 12 Apr 2019 16:57:52 +0800
+Subject: scsi: libsas: Stop hardcoding SAS address length
+
+From: John Garry <john.garry@huawei.com>
+
+[ Upstream commit 7b27c5fe247b4288f41551ced5bf458f58dc77b8 ]
+
+Many times we use 8 for SAS address length, while we already have a macro
+for this - SAS_ADDR_SIZE.
+
+Replace instances of this with the macro. However, don't touch the SAS
+address array sizes sas.h, as these are defined according to the SAS spec.
+
+Some missing whitespaces are also added, and whitespace indentation
+in sas_hash_addr() is also fixed (see sas_hash_addr()).
+
+Signed-off-by: John Garry <john.garry@huawei.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 | 15 +++++------
+ drivers/scsi/libsas/sas_init.c     | 40 ++++++++++++++++--------------
+ include/scsi/libsas.h              |  6 ++---
+ 3 files changed, 32 insertions(+), 29 deletions(-)
+
+diff --git a/drivers/scsi/libsas/sas_expander.c b/drivers/scsi/libsas/sas_expander.c
+index 3e74fe9257617..dd21d1331db31 100644
+--- a/drivers/scsi/libsas/sas_expander.c
++++ b/drivers/scsi/libsas/sas_expander.c
+@@ -1158,7 +1158,7 @@ static int sas_find_sub_addr(struct domain_device *dev, u8 *sub_addr)
+                    phy->attached_dev_type == SAS_FANOUT_EXPANDER_DEVICE) &&
+                   phy->routing_attr == SUBTRACTIVE_ROUTING) {
+-                      memcpy(sub_addr, phy->attached_sas_addr,SAS_ADDR_SIZE);
++                      memcpy(sub_addr, phy->attached_sas_addr, SAS_ADDR_SIZE);
+                       return 1;
+               }
+@@ -1170,7 +1170,7 @@ static int sas_check_level_subtractive_boundary(struct domain_device *dev)
+ {
+       struct expander_device *ex = &dev->ex_dev;
+       struct domain_device *child;
+-      u8 sub_addr[8] = {0, };
++      u8 sub_addr[SAS_ADDR_SIZE] = {0, };
+       list_for_each_entry(child, &ex->children, siblings) {
+               if (child->dev_type != SAS_EDGE_EXPANDER_DEVICE &&
+@@ -1180,7 +1180,7 @@ static int sas_check_level_subtractive_boundary(struct domain_device *dev)
+                       sas_find_sub_addr(child, sub_addr);
+                       continue;
+               } else {
+-                      u8 s2[8];
++                      u8 s2[SAS_ADDR_SIZE];
+                       if (sas_find_sub_addr(child, s2) &&
+                           (SAS_ADDR(sub_addr) != SAS_ADDR(s2))) {
+@@ -1777,10 +1777,11 @@ static int sas_get_phy_attached_dev(struct domain_device *dev, int phy_id,
+       res = sas_get_phy_discover(dev, phy_id, disc_resp);
+       if (res == 0) {
+-              memcpy(sas_addr, disc_resp->disc.attached_sas_addr, 8);
++              memcpy(sas_addr, disc_resp->disc.attached_sas_addr,
++                     SAS_ADDR_SIZE);
+               *type = to_dev_type(dr);
+               if (*type == 0)
+-                      memset(sas_addr, 0, 8);
++                      memset(sas_addr, 0, SAS_ADDR_SIZE);
+       }
+       kfree(disc_resp);
+       return res;
+@@ -2044,10 +2045,10 @@ static int sas_rediscover_dev(struct domain_device *dev, int phy_id, bool last)
+       struct expander_device *ex = &dev->ex_dev;
+       struct ex_phy *phy = &ex->ex_phy[phy_id];
+       enum sas_device_type type = SAS_PHY_UNUSED;
+-      u8 sas_addr[8];
++      u8 sas_addr[SAS_ADDR_SIZE];
+       int res;
+-      memset(sas_addr, 0, 8);
++      memset(sas_addr, 0, SAS_ADDR_SIZE);
+       res = sas_get_phy_attached_dev(dev, phy_id, sas_addr, &type);
+       switch (res) {
+       case SMP_RESP_NO_PHY:
+diff --git a/drivers/scsi/libsas/sas_init.c b/drivers/scsi/libsas/sas_init.c
+index ede0af78144f8..89bdd0c1a779e 100644
+--- a/drivers/scsi/libsas/sas_init.c
++++ b/drivers/scsi/libsas/sas_init.c
+@@ -87,25 +87,27 @@ EXPORT_SYMBOL_GPL(sas_free_task);
+ /*------------ SAS addr hash -----------*/
+ void sas_hash_addr(u8 *hashed, const u8 *sas_addr)
+ {
+-        const u32 poly = 0x00DB2777;
+-        u32     r = 0;
+-        int     i;
+-
+-        for (i = 0; i < 8; i++) {
+-                int b;
+-                for (b = 7; b >= 0; b--) {
+-                        r <<= 1;
+-                        if ((1 << b) & sas_addr[i]) {
+-                                if (!(r & 0x01000000))
+-                                        r ^= poly;
+-                        } else if (r & 0x01000000)
+-                                r ^= poly;
+-                }
+-        }
+-
+-        hashed[0] = (r >> 16) & 0xFF;
+-        hashed[1] = (r >> 8) & 0xFF ;
+-        hashed[2] = r & 0xFF;
++      const u32 poly = 0x00DB2777;
++      u32 r = 0;
++      int i;
++
++      for (i = 0; i < SAS_ADDR_SIZE; i++) {
++              int b;
++
++              for (b = (SAS_ADDR_SIZE - 1); b >= 0; b--) {
++                      r <<= 1;
++                      if ((1 << b) & sas_addr[i]) {
++                              if (!(r & 0x01000000))
++                                      r ^= poly;
++                      } else if (r & 0x01000000) {
++                              r ^= poly;
++                      }
++              }
++      }
++
++      hashed[0] = (r >> 16) & 0xFF;
++      hashed[1] = (r >> 8) & 0xFF;
++      hashed[2] = r & 0xFF;
+ }
+ int sas_register_ha(struct sas_ha_struct *sas_ha)
+diff --git a/include/scsi/libsas.h b/include/scsi/libsas.h
+index 3de3b10da19a9..4c8a89246798d 100644
+--- a/include/scsi/libsas.h
++++ b/include/scsi/libsas.h
+@@ -245,9 +245,9 @@ static inline struct sas_discovery_event *to_sas_discovery_event(struct work_str
+ struct sas_discovery {
+       struct sas_discovery_event disc_work[DISC_NUM_EVENTS];
+       unsigned long    pending;
+-      u8     fanout_sas_addr[8];
+-      u8     eeds_a[8];
+-      u8     eeds_b[8];
++      u8     fanout_sas_addr[SAS_ADDR_SIZE];
++      u8     eeds_a[SAS_ADDR_SIZE];
++      u8     eeds_b[SAS_ADDR_SIZE];
+       int    max_level;
+ };
+-- 
+2.43.0
+
diff --git a/queue-4.19/scsi-libsas-use-pr_fmt-fmt.patch b/queue-4.19/scsi-libsas-use-pr_fmt-fmt.patch
new file mode 100644 (file)
index 0000000..2d7f3bd
--- /dev/null
@@ -0,0 +1,75 @@
+From e4069043e43a4eef4a9c5aa3014e8aef307208f1 Mon Sep 17 00:00:00 2001
+From: Sasha Levin <sashal@kernel.org>
+Date: Thu, 15 Nov 2018 18:20:29 +0800
+Subject: scsi: libsas: Use pr_fmt(fmt)
+
+From: John Garry <john.garry@huawei.com>
+
+[ Upstream commit d188e5db9d274db4c183861438f883c1d74b0f16 ]
+
+In preparation for dropping the libsas printk wrappers, use pr_fmt(fmt)
+declaration to add the framework log prefix - "sas".
+
+Suggested-by: Joe Perches <joe@perches.com>
+Signed-off-by: John Garry <john.garry@huawei.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_ata.c      |  2 +-
+ drivers/scsi/libsas/sas_internal.h | 13 +++++++++++--
+ drivers/scsi/libsas/sas_task.c     |  3 +++
+ 3 files changed, 15 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/libsas/sas_ata.c b/drivers/scsi/libsas/sas_ata.c
+index 685d7a16bcd4c..b6d6020a5345e 100644
+--- a/drivers/scsi/libsas/sas_ata.c
++++ b/drivers/scsi/libsas/sas_ata.c
+@@ -377,7 +377,7 @@ static int sas_ata_printk(const char *level, const struct domain_device *ddev,
+       vaf.fmt = fmt;
+       vaf.va = &args;
+-      r = printk("%ssas: ata%u: %s: %pV",
++      r = printk("%s" SAS_FMT "ata%u: %s: %pV",
+                  level, ap->print_id, dev_name(dev), &vaf);
+       va_end(args);
+diff --git a/drivers/scsi/libsas/sas_internal.h b/drivers/scsi/libsas/sas_internal.h
+index 50e12d662ffe3..94ebf4183717c 100644
+--- a/drivers/scsi/libsas/sas_internal.h
++++ b/drivers/scsi/libsas/sas_internal.h
+@@ -32,9 +32,18 @@
+ #include <scsi/libsas.h>
+ #include <scsi/sas_ata.h>
+-#define sas_printk(fmt, ...) printk(KERN_NOTICE "sas: " fmt, ## __VA_ARGS__)
++#ifdef pr_fmt
++#undef pr_fmt
++#endif
++
++#define SAS_FMT "sas: "
++
++#define pr_fmt(fmt) SAS_FMT fmt
++
++#define sas_printk(fmt, ...) printk(KERN_NOTICE fmt, ## __VA_ARGS__)
++
++#define SAS_DPRINTK(fmt, ...) printk(KERN_DEBUG fmt, ## __VA_ARGS__)
+-#define SAS_DPRINTK(fmt, ...) printk(KERN_DEBUG "sas: " fmt, ## __VA_ARGS__)
+ #define TO_SAS_TASK(_scsi_cmd)  ((void *)(_scsi_cmd)->host_scribble)
+ #define ASSIGN_SAS_TASK(_sc, _t) do { (_sc)->host_scribble = (void *) _t; } while (0)
+diff --git a/drivers/scsi/libsas/sas_task.c b/drivers/scsi/libsas/sas_task.c
+index a78e5bd3e5145..d305c8f90ee9b 100644
+--- a/drivers/scsi/libsas/sas_task.c
++++ b/drivers/scsi/libsas/sas_task.c
+@@ -1,3 +1,6 @@
++
++#include "sas_internal.h"
++
+ #include <linux/kernel.h>
+ #include <linux/export.h>
+ #include <scsi/sas.h>
+-- 
+2.43.0
+
index 7c351cdc8c7a76852f8a1ac1c942035cc2bffc53..ca4f70f1b629395b24b8eb60e6898582d8b9b0b2 100644 (file)
@@ -109,3 +109,11 @@ timers-move-clearing-of-base-timer_running-under-base-lock.patch
 drm-imx-parallel-display-remove-bus-flags-check-in-imx_pd_bridge_atomic_check.patch
 scsi-lpfc-correct-size-for-wqe-for-memset.patch
 usb-core-fix-deadlock-in-usb_deauthorize_interface.patch
+nfc-nci-fix-uninit-value-in-nci_dev_up-and-nci_ntf_p.patch
+mptcp-add-sk_stop_timer_sync-helper.patch
+tcp-properly-terminate-timers-for-kernel-sockets.patch
+scsi-libsas-use-pr_fmt-fmt.patch
+scsi-libsas-stop-hardcoding-sas-address-length.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
diff --git a/queue-4.19/tcp-properly-terminate-timers-for-kernel-sockets.patch b/queue-4.19/tcp-properly-terminate-timers-for-kernel-sockets.patch
new file mode 100644 (file)
index 0000000..de49c75
--- /dev/null
@@ -0,0 +1,138 @@
+From 8bfcfacc2d5a7f117a4466115f6dd9f345688e9e 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 da8a582ab032e..6141fe1932c8f 100644
+--- a/include/net/inet_connection_sock.h
++++ b/include/net/inet_connection_sock.h
+@@ -177,6 +177,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 8eea17a41c1ca..b5a929a4bc74d 100644
+--- a/include/net/sock.h
++++ b/include/net/sock.h
+@@ -1589,6 +1589,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 7392a744c677e..17a900c85aa66 100644
+--- a/net/ipv4/inet_connection_sock.c
++++ b/net/ipv4/inet_connection_sock.c
+@@ -557,6 +557,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 3df973d22295c..54d6058dcb5cc 100644
+--- a/net/ipv4/tcp.c
++++ b/net/ipv4/tcp.c
+@@ -2514,6 +2514,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
+