]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
6.1-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 6 May 2023 07:00:17 +0000 (16:00 +0900)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Sat, 6 May 2023 07:00:17 +0000 (16:00 +0900)
added patches:
asoc-dt-bindings-qcom-lpass-rx-macro-correct-minitems-for-clocks.patch
bus-mhi-host-range-check-chdboff-and-erdboff.patch
bus-mhi-host-remove-duplicate-ee-check-for-syserr.patch
bus-mhi-host-use-mhi_tryset_pm_state-for-setting-fw-error-state.patch
ceph-fix-potential-use-after-free-bug-when-trimming-caps.patch
cxl-hdm-fail-upon-detecting-0-sized-decoders.patch
revert-ubifs-dirty_cow_znode-fix-memleak-in-error-handling-path.patch
ubi-fix-return-value-overwrite-issue-in-try_write_vid_and_data.patch
ubifs-fix-memleak-when-insert_old_idx-failed.patch
ubifs-fix-memory-leak-in-do_rename.patch
ubifs-free-memory-for-tmpfile-name.patch
xfs-don-t-consider-future-format-versions-valid.patch

13 files changed:
queue-6.1/asoc-dt-bindings-qcom-lpass-rx-macro-correct-minitems-for-clocks.patch [new file with mode: 0644]
queue-6.1/bus-mhi-host-range-check-chdboff-and-erdboff.patch [new file with mode: 0644]
queue-6.1/bus-mhi-host-remove-duplicate-ee-check-for-syserr.patch [new file with mode: 0644]
queue-6.1/bus-mhi-host-use-mhi_tryset_pm_state-for-setting-fw-error-state.patch [new file with mode: 0644]
queue-6.1/ceph-fix-potential-use-after-free-bug-when-trimming-caps.patch [new file with mode: 0644]
queue-6.1/cxl-hdm-fail-upon-detecting-0-sized-decoders.patch [new file with mode: 0644]
queue-6.1/revert-ubifs-dirty_cow_znode-fix-memleak-in-error-handling-path.patch [new file with mode: 0644]
queue-6.1/series
queue-6.1/ubi-fix-return-value-overwrite-issue-in-try_write_vid_and_data.patch [new file with mode: 0644]
queue-6.1/ubifs-fix-memleak-when-insert_old_idx-failed.patch [new file with mode: 0644]
queue-6.1/ubifs-fix-memory-leak-in-do_rename.patch [new file with mode: 0644]
queue-6.1/ubifs-free-memory-for-tmpfile-name.patch [new file with mode: 0644]
queue-6.1/xfs-don-t-consider-future-format-versions-valid.patch [new file with mode: 0644]

diff --git a/queue-6.1/asoc-dt-bindings-qcom-lpass-rx-macro-correct-minitems-for-clocks.patch b/queue-6.1/asoc-dt-bindings-qcom-lpass-rx-macro-correct-minitems-for-clocks.patch
new file mode 100644 (file)
index 0000000..ccbf1c0
--- /dev/null
@@ -0,0 +1,36 @@
+From 59257015ac8813d2430988aa01c2f4609a60e8e7 Mon Sep 17 00:00:00 2001
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Date: Thu, 30 Mar 2023 09:13:33 +0200
+Subject: ASoC: dt-bindings: qcom,lpass-rx-macro: correct minItems for clocks
+
+From: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+
+commit 59257015ac8813d2430988aa01c2f4609a60e8e7 upstream.
+
+The RX macro codec comes on some platforms in two variants - ADSP
+and ADSP bypassed - thus the clock-names varies from 3 to 5.  The clocks
+must vary as well:
+
+  sc7280-idp.dtb: codec@3200000: clocks: [[202, 8], [202, 7], [203]] is too short
+
+Fixes: 852fda58d99a ("ASoC: qcom: dt-bindings: Update bindings for clocks in lpass digital codes")
+Cc: <stable@vger.kernel.org>
+Acked-by: Rob Herring <robh@kernel.org>
+Signed-off-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
+Link: https://lore.kernel.org/r/20230330071333.24308-1-krzysztof.kozlowski@linaro.org
+Signed-off-by: Mark Brown <broonie@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
++++ b/Documentation/devicetree/bindings/sound/qcom,lpass-rx-macro.yaml
+@@ -27,6 +27,7 @@ properties:
+     const: 0
+   clocks:
++    minItems: 3
+     maxItems: 5
+   clock-names:
diff --git a/queue-6.1/bus-mhi-host-range-check-chdboff-and-erdboff.patch b/queue-6.1/bus-mhi-host-range-check-chdboff-and-erdboff.patch
new file mode 100644 (file)
index 0000000..af87902
--- /dev/null
@@ -0,0 +1,54 @@
+From 6a0c637bfee69a74c104468544d9f2a6579626d0 Mon Sep 17 00:00:00 2001
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Date: Fri, 24 Mar 2023 10:13:04 -0600
+Subject: bus: mhi: host: Range check CHDBOFF and ERDBOFF
+
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+
+commit 6a0c637bfee69a74c104468544d9f2a6579626d0 upstream.
+
+If the value read from the CHDBOFF and ERDBOFF registers is outside the
+range of the MHI register space then an invalid address might be computed
+which later causes a kernel panic.  Range check the read value to prevent
+a crash due to bad data from the device.
+
+Fixes: 6cd330ae76ff ("bus: mhi: core: Add support for ringing channel/event ring doorbells")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Reviewed-by: Pranjal Ramajor Asha Kanojiya <quic_pkanojiy@quicinc.com>
+Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
+Link: https://lore.kernel.org/r/1679674384-27209-1-git-send-email-quic_jhugo@quicinc.com
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bus/mhi/host/init.c |   12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+--- a/drivers/bus/mhi/host/init.c
++++ b/drivers/bus/mhi/host/init.c
+@@ -516,6 +516,12 @@ int mhi_init_mmio(struct mhi_controller
+               return -EIO;
+       }
++      if (val >= mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB)) {
++              dev_err(dev, "CHDB offset: 0x%x is out of range: 0x%zx\n",
++                      val, mhi_cntrl->reg_len - (8 * MHI_DEV_WAKE_DB));
++              return -ERANGE;
++      }
++
+       /* Setup wake db */
+       mhi_cntrl->wake_db = base + val + (8 * MHI_DEV_WAKE_DB);
+       mhi_cntrl->wake_set = false;
+@@ -532,6 +538,12 @@ int mhi_init_mmio(struct mhi_controller
+               return -EIO;
+       }
++      if (val >= mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings)) {
++              dev_err(dev, "ERDB offset: 0x%x is out of range: 0x%zx\n",
++                      val, mhi_cntrl->reg_len - (8 * mhi_cntrl->total_ev_rings));
++              return -ERANGE;
++      }
++
+       /* Setup event db address for each ev_ring */
+       mhi_event = mhi_cntrl->mhi_event;
+       for (i = 0; i < mhi_cntrl->total_ev_rings; i++, val += 8, mhi_event++) {
diff --git a/queue-6.1/bus-mhi-host-remove-duplicate-ee-check-for-syserr.patch b/queue-6.1/bus-mhi-host-remove-duplicate-ee-check-for-syserr.patch
new file mode 100644 (file)
index 0000000..ef6d942
--- /dev/null
@@ -0,0 +1,45 @@
+From d469d9448a0f1a33c175d3280b1542fa0158ad7a Mon Sep 17 00:00:00 2001
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Date: Mon, 10 Apr 2023 09:58:11 -0600
+Subject: bus: mhi: host: Remove duplicate ee check for syserr
+
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+
+commit d469d9448a0f1a33c175d3280b1542fa0158ad7a upstream.
+
+If we detect a system error via intvec, we only process the syserr if the
+current ee is different than the last observed ee.  The reason for this
+check is to prevent bhie from running multiple times, but with the single
+queue handling syserr, that is not possible.
+
+The check can cause an issue with device recovery.  If PBL loads a bad SBL
+via BHI, but that SBL hangs before notifying the host of an ee change,
+then issuing soc_reset to crash the device and retry (after supplying a
+fixed SBL) will not recover the device as the host will observe a PBL->PBL
+transition and not process the syserr.  The device will be stuck until
+either the driver is reloaded, or the host is rebooted.  Instead, remove
+the check so that we can attempt to recover the device.
+
+Fixes: ef2126c4e2ea ("bus: mhi: core: Process execution environment changes serially")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Reviewed-by: Carl Vanderlip <quic_carlv@quicinc.com>
+Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
+Link: https://lore.kernel.org/r/1681142292-27571-2-git-send-email-quic_jhugo@quicinc.com
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bus/mhi/host/main.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/drivers/bus/mhi/host/main.c
++++ b/drivers/bus/mhi/host/main.c
+@@ -503,7 +503,7 @@ irqreturn_t mhi_intvec_threaded_handler(
+       }
+       write_unlock_irq(&mhi_cntrl->pm_lock);
+-      if (pm_state != MHI_PM_SYS_ERR_DETECT || ee == mhi_cntrl->ee)
++      if (pm_state != MHI_PM_SYS_ERR_DETECT)
+               goto exit_intvec;
+       switch (ee) {
diff --git a/queue-6.1/bus-mhi-host-use-mhi_tryset_pm_state-for-setting-fw-error-state.patch b/queue-6.1/bus-mhi-host-use-mhi_tryset_pm_state-for-setting-fw-error-state.patch
new file mode 100644 (file)
index 0000000..88e31d7
--- /dev/null
@@ -0,0 +1,80 @@
+From 1d1493bdc25f498468a606a4ece947d155cfa3a9 Mon Sep 17 00:00:00 2001
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Date: Mon, 10 Apr 2023 09:58:12 -0600
+Subject: bus: mhi: host: Use mhi_tryset_pm_state() for setting fw error state
+
+From: Jeffrey Hugo <quic_jhugo@quicinc.com>
+
+commit 1d1493bdc25f498468a606a4ece947d155cfa3a9 upstream.
+
+If firmware loading fails, the controller's pm_state is updated to
+MHI_PM_FW_DL_ERR unconditionally.  This can corrupt the pm_state as the
+update is not done under the proper lock, and also does not validate
+the state transition.  The firmware loading can fail due to a detected
+syserr, but if MHI_PM_FW_DL_ERR is unconditionally set as the pm_state,
+the handling of the syserr can break when it attempts to transition from
+syserr detect, to syserr process.
+
+By grabbing the lock, we ensure we don't race with some other pm_state
+update.  By using mhi_try_set_pm_state(), we check that the transition
+to MHI_PM_FW_DL_ERR is valid via the state machine logic.  If it is not
+valid, then some other transition is occurring like syserr processing, and
+we assume that will resolve the firmware loading error.
+
+Fixes: 12e050c77be0 ("bus: mhi: core: Move to an error state on any firmware load failure")
+Cc: stable@vger.kernel.org
+Signed-off-by: Jeffrey Hugo <quic_jhugo@quicinc.com>
+Reviewed-by: Carl Vanderlip <quic_carlv@quicinc.com>
+Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
+Link: https://lore.kernel.org/r/1681142292-27571-3-git-send-email-quic_jhugo@quicinc.com
+Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/bus/mhi/host/boot.c |   16 ++++++++++++----
+ 1 file changed, 12 insertions(+), 4 deletions(-)
+
+--- a/drivers/bus/mhi/host/boot.c
++++ b/drivers/bus/mhi/host/boot.c
+@@ -393,6 +393,7 @@ void mhi_fw_load_handler(struct mhi_cont
+ {
+       const struct firmware *firmware = NULL;
+       struct device *dev = &mhi_cntrl->mhi_dev->dev;
++      enum mhi_pm_state new_state;
+       const char *fw_name;
+       void *buf;
+       dma_addr_t dma_addr;
+@@ -510,14 +511,18 @@ error_ready_state:
+       }
+ error_fw_load:
+-      mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
+-      wake_up_all(&mhi_cntrl->state_event);
++      write_lock_irq(&mhi_cntrl->pm_lock);
++      new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
++      write_unlock_irq(&mhi_cntrl->pm_lock);
++      if (new_state == MHI_PM_FW_DL_ERR)
++              wake_up_all(&mhi_cntrl->state_event);
+ }
+ int mhi_download_amss_image(struct mhi_controller *mhi_cntrl)
+ {
+       struct image_info *image_info = mhi_cntrl->fbc_image;
+       struct device *dev = &mhi_cntrl->mhi_dev->dev;
++      enum mhi_pm_state new_state;
+       int ret;
+       if (!image_info)
+@@ -528,8 +533,11 @@ int mhi_download_amss_image(struct mhi_c
+                              &image_info->mhi_buf[image_info->entries - 1]);
+       if (ret) {
+               dev_err(dev, "MHI did not load AMSS, ret:%d\n", ret);
+-              mhi_cntrl->pm_state = MHI_PM_FW_DL_ERR;
+-              wake_up_all(&mhi_cntrl->state_event);
++              write_lock_irq(&mhi_cntrl->pm_lock);
++              new_state = mhi_tryset_pm_state(mhi_cntrl, MHI_PM_FW_DL_ERR);
++              write_unlock_irq(&mhi_cntrl->pm_lock);
++              if (new_state == MHI_PM_FW_DL_ERR)
++                      wake_up_all(&mhi_cntrl->state_event);
+       }
+       return ret;
diff --git a/queue-6.1/ceph-fix-potential-use-after-free-bug-when-trimming-caps.patch b/queue-6.1/ceph-fix-potential-use-after-free-bug-when-trimming-caps.patch
new file mode 100644 (file)
index 0000000..2e4f041
--- /dev/null
@@ -0,0 +1,269 @@
+From aaf67de78807c59c35bafb5003d4fb457c764800 Mon Sep 17 00:00:00 2001
+From: Xiubo Li <xiubli@redhat.com>
+Date: Wed, 19 Apr 2023 10:39:14 +0800
+Subject: ceph: fix potential use-after-free bug when trimming caps
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Xiubo Li <xiubli@redhat.com>
+
+commit aaf67de78807c59c35bafb5003d4fb457c764800 upstream.
+
+When trimming the caps and just after the 'session->s_cap_lock' is
+released in ceph_iterate_session_caps() the cap maybe removed by
+another thread, and when using the stale cap memory in the callbacks
+it will trigger use-after-free crash.
+
+We need to check the existence of the cap just after the 'ci->i_ceph_lock'
+being acquired. And do nothing if it's already removed.
+
+Cc: stable@vger.kernel.org
+Link: https://tracker.ceph.com/issues/43272
+Signed-off-by: Xiubo Li <xiubli@redhat.com>
+Reviewed-by: Luís Henriques <lhenriques@suse.de>
+Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ceph/caps.c       |    2 -
+ fs/ceph/debugfs.c    |   16 +++++++----
+ fs/ceph/mds_client.c |   72 ++++++++++++++++++++++++++++++++-------------------
+ fs/ceph/mds_client.h |    3 --
+ fs/ceph/super.h      |    2 +
+ 5 files changed, 61 insertions(+), 34 deletions(-)
+
+--- a/fs/ceph/caps.c
++++ b/fs/ceph/caps.c
+@@ -430,7 +430,7 @@ void ceph_reservation_status(struct ceph
+  *
+  * Called with i_ceph_lock held.
+  */
+-static struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
++struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci, int mds)
+ {
+       struct ceph_cap *cap;
+       struct rb_node *n = ci->i_caps.rb_node;
+--- a/fs/ceph/debugfs.c
++++ b/fs/ceph/debugfs.c
+@@ -248,14 +248,20 @@ static int metrics_caps_show(struct seq_
+       return 0;
+ }
+-static int caps_show_cb(struct inode *inode, struct ceph_cap *cap, void *p)
++static int caps_show_cb(struct inode *inode, int mds, void *p)
+ {
++      struct ceph_inode_info *ci = ceph_inode(inode);
+       struct seq_file *s = p;
++      struct ceph_cap *cap;
+-      seq_printf(s, "0x%-17llx%-3d%-17s%-17s\n", ceph_ino(inode),
+-                 cap->session->s_mds,
+-                 ceph_cap_string(cap->issued),
+-                 ceph_cap_string(cap->implemented));
++      spin_lock(&ci->i_ceph_lock);
++      cap = __get_cap_for_mds(ci, mds);
++      if (cap)
++              seq_printf(s, "0x%-17llx%-3d%-17s%-17s\n", ceph_ino(inode),
++                         cap->session->s_mds,
++                         ceph_cap_string(cap->issued),
++                         ceph_cap_string(cap->implemented));
++      spin_unlock(&ci->i_ceph_lock);
+       return 0;
+ }
+--- a/fs/ceph/mds_client.c
++++ b/fs/ceph/mds_client.c
+@@ -1632,8 +1632,8 @@ static void cleanup_session_requests(str
+  * Caller must hold session s_mutex.
+  */
+ int ceph_iterate_session_caps(struct ceph_mds_session *session,
+-                            int (*cb)(struct inode *, struct ceph_cap *,
+-                                      void *), void *arg)
++                            int (*cb)(struct inode *, int mds, void *),
++                            void *arg)
+ {
+       struct list_head *p;
+       struct ceph_cap *cap;
+@@ -1645,6 +1645,8 @@ int ceph_iterate_session_caps(struct cep
+       spin_lock(&session->s_cap_lock);
+       p = session->s_caps.next;
+       while (p != &session->s_caps) {
++              int mds;
++
+               cap = list_entry(p, struct ceph_cap, session_caps);
+               inode = igrab(&cap->ci->netfs.inode);
+               if (!inode) {
+@@ -1652,6 +1654,7 @@ int ceph_iterate_session_caps(struct cep
+                       continue;
+               }
+               session->s_cap_iterator = cap;
++              mds = cap->mds;
+               spin_unlock(&session->s_cap_lock);
+               if (last_inode) {
+@@ -1663,7 +1666,7 @@ int ceph_iterate_session_caps(struct cep
+                       old_cap = NULL;
+               }
+-              ret = cb(inode, cap, arg);
++              ret = cb(inode, mds, arg);
+               last_inode = inode;
+               spin_lock(&session->s_cap_lock);
+@@ -1696,20 +1699,25 @@ out:
+       return ret;
+ }
+-static int remove_session_caps_cb(struct inode *inode, struct ceph_cap *cap,
+-                                void *arg)
++static int remove_session_caps_cb(struct inode *inode, int mds, void *arg)
+ {
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       bool invalidate = false;
+-      int iputs;
++      struct ceph_cap *cap;
++      int iputs = 0;
+-      dout("removing cap %p, ci is %p, inode is %p\n",
+-           cap, ci, &ci->netfs.inode);
+       spin_lock(&ci->i_ceph_lock);
+-      iputs = ceph_purge_inode_cap(inode, cap, &invalidate);
++      cap = __get_cap_for_mds(ci, mds);
++      if (cap) {
++              dout(" removing cap %p, ci is %p, inode is %p\n",
++                   cap, ci, &ci->netfs.inode);
++
++              iputs = ceph_purge_inode_cap(inode, cap, &invalidate);
++      }
+       spin_unlock(&ci->i_ceph_lock);
+-      wake_up_all(&ci->i_cap_wq);
++      if (cap)
++              wake_up_all(&ci->i_cap_wq);
+       if (invalidate)
+               ceph_queue_invalidate(inode);
+       while (iputs--)
+@@ -1780,8 +1788,7 @@ enum {
+  *
+  * caller must hold s_mutex.
+  */
+-static int wake_up_session_cb(struct inode *inode, struct ceph_cap *cap,
+-                            void *arg)
++static int wake_up_session_cb(struct inode *inode, int mds, void *arg)
+ {
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       unsigned long ev = (unsigned long)arg;
+@@ -1792,12 +1799,14 @@ static int wake_up_session_cb(struct ino
+               ci->i_requested_max_size = 0;
+               spin_unlock(&ci->i_ceph_lock);
+       } else if (ev == RENEWCAPS) {
+-              if (cap->cap_gen < atomic_read(&cap->session->s_cap_gen)) {
+-                      /* mds did not re-issue stale cap */
+-                      spin_lock(&ci->i_ceph_lock);
++              struct ceph_cap *cap;
++
++              spin_lock(&ci->i_ceph_lock);
++              cap = __get_cap_for_mds(ci, mds);
++              /* mds did not re-issue stale cap */
++              if (cap && cap->cap_gen < atomic_read(&cap->session->s_cap_gen))
+                       cap->issued = cap->implemented = CEPH_CAP_PIN;
+-                      spin_unlock(&ci->i_ceph_lock);
+-              }
++              spin_unlock(&ci->i_ceph_lock);
+       } else if (ev == FORCE_RO) {
+       }
+       wake_up_all(&ci->i_cap_wq);
+@@ -1959,16 +1968,22 @@ out:
+  * Yes, this is a bit sloppy.  Our only real goal here is to respond to
+  * memory pressure from the MDS, though, so it needn't be perfect.
+  */
+-static int trim_caps_cb(struct inode *inode, struct ceph_cap *cap, void *arg)
++static int trim_caps_cb(struct inode *inode, int mds, void *arg)
+ {
+       int *remaining = arg;
+       struct ceph_inode_info *ci = ceph_inode(inode);
+       int used, wanted, oissued, mine;
++      struct ceph_cap *cap;
+       if (*remaining <= 0)
+               return -1;
+       spin_lock(&ci->i_ceph_lock);
++      cap = __get_cap_for_mds(ci, mds);
++      if (!cap) {
++              spin_unlock(&ci->i_ceph_lock);
++              return 0;
++      }
+       mine = cap->issued | cap->implemented;
+       used = __ceph_caps_used(ci);
+       wanted = __ceph_caps_file_wanted(ci);
+@@ -3911,26 +3926,22 @@ out_unlock:
+ /*
+  * Encode information about a cap for a reconnect with the MDS.
+  */
+-static int reconnect_caps_cb(struct inode *inode, struct ceph_cap *cap,
+-                        void *arg)
++static int reconnect_caps_cb(struct inode *inode, int mds, void *arg)
+ {
+       union {
+               struct ceph_mds_cap_reconnect v2;
+               struct ceph_mds_cap_reconnect_v1 v1;
+       } rec;
+-      struct ceph_inode_info *ci = cap->ci;
++      struct ceph_inode_info *ci = ceph_inode(inode);
+       struct ceph_reconnect_state *recon_state = arg;
+       struct ceph_pagelist *pagelist = recon_state->pagelist;
+       struct dentry *dentry;
++      struct ceph_cap *cap;
+       char *path;
+-      int pathlen = 0, err;
++      int pathlen = 0, err = 0;
+       u64 pathbase;
+       u64 snap_follows;
+-      dout(" adding %p ino %llx.%llx cap %p %lld %s\n",
+-           inode, ceph_vinop(inode), cap, cap->cap_id,
+-           ceph_cap_string(cap->issued));
+-
+       dentry = d_find_primary(inode);
+       if (dentry) {
+               /* set pathbase to parent dir when msg_version >= 2 */
+@@ -3947,6 +3958,15 @@ static int reconnect_caps_cb(struct inod
+       }
+       spin_lock(&ci->i_ceph_lock);
++      cap = __get_cap_for_mds(ci, mds);
++      if (!cap) {
++              spin_unlock(&ci->i_ceph_lock);
++              goto out_err;
++      }
++      dout(" adding %p ino %llx.%llx cap %p %lld %s\n",
++           inode, ceph_vinop(inode), cap, cap->cap_id,
++           ceph_cap_string(cap->issued));
++
+       cap->seq = 0;        /* reset cap seq */
+       cap->issue_seq = 0;  /* and issue_seq */
+       cap->mseq = 0;       /* and migrate_seq */
+--- a/fs/ceph/mds_client.h
++++ b/fs/ceph/mds_client.h
+@@ -541,8 +541,7 @@ extern void ceph_flush_cap_releases(stru
+ extern void ceph_queue_cap_reclaim_work(struct ceph_mds_client *mdsc);
+ extern void ceph_reclaim_caps_nr(struct ceph_mds_client *mdsc, int nr);
+ extern int ceph_iterate_session_caps(struct ceph_mds_session *session,
+-                                   int (*cb)(struct inode *,
+-                                             struct ceph_cap *, void *),
++                                   int (*cb)(struct inode *, int mds, void *),
+                                    void *arg);
+ extern void ceph_mdsc_pre_umount(struct ceph_mds_client *mdsc);
+--- a/fs/ceph/super.h
++++ b/fs/ceph/super.h
+@@ -1190,6 +1190,8 @@ extern void ceph_kick_flushing_caps(stru
+                                   struct ceph_mds_session *session);
+ void ceph_kick_flushing_inode_caps(struct ceph_mds_session *session,
+                                  struct ceph_inode_info *ci);
++extern struct ceph_cap *__get_cap_for_mds(struct ceph_inode_info *ci,
++                                        int mds);
+ extern struct ceph_cap *ceph_get_cap_for_mds(struct ceph_inode_info *ci,
+                                            int mds);
+ extern void ceph_take_cap_refs(struct ceph_inode_info *ci, int caps,
diff --git a/queue-6.1/cxl-hdm-fail-upon-detecting-0-sized-decoders.patch b/queue-6.1/cxl-hdm-fail-upon-detecting-0-sized-decoders.patch
new file mode 100644 (file)
index 0000000..6a0cc22
--- /dev/null
@@ -0,0 +1,64 @@
+From 7701c8bef4f14bd9f7940c6ed0e6a73584115a96 Mon Sep 17 00:00:00 2001
+From: Dan Williams <dan.j.williams@intel.com>
+Date: Fri, 14 Apr 2023 11:53:55 -0700
+Subject: cxl/hdm: Fail upon detecting 0-sized decoders
+
+From: Dan Williams <dan.j.williams@intel.com>
+
+commit 7701c8bef4f14bd9f7940c6ed0e6a73584115a96 upstream.
+
+Decoders committed with 0-size lead to later crashes on shutdown as
+__cxl_dpa_release() assumes a 'struct resource' has been established in
+the in 'cxlds->dpa_res'. Just fail the driver load in this instance
+since there are deeper problems with the enumeration or the setup when
+this happens.
+
+Fixes: 9c57cde0dcbd ("cxl/hdm: Enumerate allocated DPA")
+Cc: <stable@vger.kernel.org>
+Reviewed-by: Dave Jiang <dave.jiang@intel.com>
+Reviewed-by: Alison Schofield <alison.schofield@intel.com>
+Link: https://lore.kernel.org/r/168149843516.792294.11872242648319572632.stgit@dwillia2-xfh.jf.intel.com
+Signed-off-by: Dan Williams <dan.j.williams@intel.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/cxl/core/hdm.c |   15 ++++++++++++---
+ 1 file changed, 12 insertions(+), 3 deletions(-)
+
+--- a/drivers/cxl/core/hdm.c
++++ b/drivers/cxl/core/hdm.c
+@@ -214,8 +214,11 @@ static int __cxl_dpa_reserve(struct cxl_
+       lockdep_assert_held_write(&cxl_dpa_rwsem);
+-      if (!len)
+-              goto success;
++      if (!len) {
++              dev_warn(dev, "decoder%d.%d: empty reservation attempted\n",
++                       port->id, cxled->cxld.id);
++              return -EINVAL;
++      }
+       if (cxled->dpa_res) {
+               dev_dbg(dev, "decoder%d.%d: existing allocation %pr assigned\n",
+@@ -268,7 +271,6 @@ static int __cxl_dpa_reserve(struct cxl_
+               cxled->mode = CXL_DECODER_MIXED;
+       }
+-success:
+       port->hdm_end++;
+       get_device(&cxled->cxld.dev);
+       return 0;
+@@ -727,6 +729,13 @@ static int init_hdm_decoder(struct cxl_p
+                                port->id, cxld->id);
+                       return -ENXIO;
+               }
++
++              if (size == 0) {
++                      dev_warn(&port->dev,
++                               "decoder%d.%d: Committed with zero size\n",
++                               port->id, cxld->id);
++                      return -ENXIO;
++              }
+               port->commit_end = cxld->id;
+       } else {
+               /* unless / until type-2 drivers arrive, assume type-3 */
diff --git a/queue-6.1/revert-ubifs-dirty_cow_znode-fix-memleak-in-error-handling-path.patch b/queue-6.1/revert-ubifs-dirty_cow_znode-fix-memleak-in-error-handling-path.patch
new file mode 100644 (file)
index 0000000..c83244d
--- /dev/null
@@ -0,0 +1,47 @@
+From 7d01cb27f6aebc54efbe28d8961a973b8f795b13 Mon Sep 17 00:00:00 2001
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+Date: Wed, 1 Mar 2023 20:29:18 +0800
+Subject: Revert "ubifs: dirty_cow_znode: Fix memleak in error handling path"
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+commit 7d01cb27f6aebc54efbe28d8961a973b8f795b13 upstream.
+
+This reverts commit 122deabfe1428 (ubifs: dirty_cow_znode: Fix memleak
+in error handling path).
+After commit 122deabfe1428 applied, if insert_old_idx() failed, old
+index neither exists in TNC nor in old-index tree. Which means that
+old index node could be overwritten in layout_leb_in_gaps(), then
+ubifs image will be corrupted in power-cut.
+
+Fixes: 122deabfe1428 (ubifs: dirty_cow_znode: Fix memleak ... path)
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ubifs/tnc.c |    9 +--------
+ 1 file changed, 1 insertion(+), 8 deletions(-)
+
+--- a/fs/ubifs/tnc.c
++++ b/fs/ubifs/tnc.c
+@@ -267,18 +267,11 @@ static struct ubifs_znode *dirty_cow_zno
+       if (zbr->len) {
+               err = insert_old_idx(c, zbr->lnum, zbr->offs);
+               if (unlikely(err))
+-                      /*
+-                       * Obsolete znodes will be freed by tnc_destroy_cnext()
+-                       * or free_obsolete_znodes(), copied up znodes should
+-                       * be added back to tnc and freed by
+-                       * ubifs_destroy_tnc_subtree().
+-                       */
+-                      goto out;
++                      return ERR_PTR(err);
+               err = add_idx_dirt(c, zbr->lnum, zbr->len);
+       } else
+               err = 0;
+-out:
+       zbr->znode = zn;
+       zbr->lnum = 0;
+       zbr->offs = 0;
index a55a506869a2b7bc21078a770955a0b16aa30bc9..42353fa35ed81ef23335f5b0d16d6fa8a307f17b 100644 (file)
@@ -99,3 +99,15 @@ swsmu-amdgpu_smu-fix-the-wrong-if-condition.patch
 drm-amd-pm-re-enable-the-gfx-imu-when-smu-resume.patch
 iommu-amd-fix-guest-virtual-apic-table-root-pointer-configuration-in-irte.patch
 risc-v-align-sbi-probe-implementation-with-spec.patch
+revert-ubifs-dirty_cow_znode-fix-memleak-in-error-handling-path.patch
+ubifs-fix-memleak-when-insert_old_idx-failed.patch
+ubi-fix-return-value-overwrite-issue-in-try_write_vid_and_data.patch
+ubifs-free-memory-for-tmpfile-name.patch
+ubifs-fix-memory-leak-in-do_rename.patch
+ceph-fix-potential-use-after-free-bug-when-trimming-caps.patch
+xfs-don-t-consider-future-format-versions-valid.patch
+cxl-hdm-fail-upon-detecting-0-sized-decoders.patch
+bus-mhi-host-remove-duplicate-ee-check-for-syserr.patch
+bus-mhi-host-use-mhi_tryset_pm_state-for-setting-fw-error-state.patch
+bus-mhi-host-range-check-chdboff-and-erdboff.patch
+asoc-dt-bindings-qcom-lpass-rx-macro-correct-minitems-for-clocks.patch
diff --git a/queue-6.1/ubi-fix-return-value-overwrite-issue-in-try_write_vid_and_data.patch b/queue-6.1/ubi-fix-return-value-overwrite-issue-in-try_write_vid_and_data.patch
new file mode 100644 (file)
index 0000000..95c3d55
--- /dev/null
@@ -0,0 +1,63 @@
+From 31a149d5c13c4cbcf97de3435817263a2d8c9d6e Mon Sep 17 00:00:00 2001
+From: Wang YanQing <udknight@gmail.com>
+Date: Tue, 28 Mar 2023 23:35:34 +0800
+Subject: ubi: Fix return value overwrite issue in try_write_vid_and_data()
+
+From: Wang YanQing <udknight@gmail.com>
+
+commit 31a149d5c13c4cbcf97de3435817263a2d8c9d6e upstream.
+
+The commit 2d78aee426d8 ("UBI: simplify LEB write and atomic LEB change code")
+adds helper function, try_write_vid_and_data(), to simplify the code, but this
+helper function has bug, it will return 0 (success) when ubi_io_write_vid_hdr()
+or the ubi_io_write_data() return error number (-EIO, etc), because the return
+value of ubi_wl_put_peb() will overwrite the original return value.
+
+This issue will cause unexpected data loss issue, because the caller of this
+function and UBIFS willn't know the data is lost.
+
+Fixes: 2d78aee426d8 ("UBI: simplify LEB write and atomic LEB change code")
+Cc: stable@vger.kernel.org
+Signed-off-by: Wang YanQing <udknight@gmail.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/mtd/ubi/eba.c |   19 ++++++++++++++-----
+ 1 file changed, 14 insertions(+), 5 deletions(-)
+
+--- a/drivers/mtd/ubi/eba.c
++++ b/drivers/mtd/ubi/eba.c
+@@ -946,7 +946,7 @@ static int try_write_vid_and_data(struct
+                                 int offset, int len)
+ {
+       struct ubi_device *ubi = vol->ubi;
+-      int pnum, opnum, err, vol_id = vol->vol_id;
++      int pnum, opnum, err, err2, vol_id = vol->vol_id;
+       pnum = ubi_wl_get_peb(ubi);
+       if (pnum < 0) {
+@@ -981,10 +981,19 @@ static int try_write_vid_and_data(struct
+ out_put:
+       up_read(&ubi->fm_eba_sem);
+-      if (err && pnum >= 0)
+-              err = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
+-      else if (!err && opnum >= 0)
+-              err = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0);
++      if (err && pnum >= 0) {
++              err2 = ubi_wl_put_peb(ubi, vol_id, lnum, pnum, 1);
++              if (err2) {
++                      ubi_warn(ubi, "failed to return physical eraseblock %d, error %d",
++                               pnum, err2);
++              }
++      } else if (!err && opnum >= 0) {
++              err2 = ubi_wl_put_peb(ubi, vol_id, lnum, opnum, 0);
++              if (err2) {
++                      ubi_warn(ubi, "failed to return physical eraseblock %d, error %d",
++                               opnum, err2);
++              }
++      }
+       return err;
+ }
diff --git a/queue-6.1/ubifs-fix-memleak-when-insert_old_idx-failed.patch b/queue-6.1/ubifs-fix-memleak-when-insert_old_idx-failed.patch
new file mode 100644 (file)
index 0000000..e0e29c3
--- /dev/null
@@ -0,0 +1,222 @@
+From b5fda08ef213352ac2df7447611eb4d383cce929 Mon Sep 17 00:00:00 2001
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+Date: Wed, 1 Mar 2023 20:29:19 +0800
+Subject: ubifs: Fix memleak when insert_old_idx() failed
+
+From: Zhihao Cheng <chengzhihao1@huawei.com>
+
+commit b5fda08ef213352ac2df7447611eb4d383cce929 upstream.
+
+Following process will cause a memleak for copied up znode:
+
+dirty_cow_znode
+  zn = copy_znode(c, znode);
+  err = insert_old_idx(c, zbr->lnum, zbr->offs);
+  if (unlikely(err))
+     return ERR_PTR(err);   // No one refers to zn.
+
+Fetch a reproducer in [Link].
+
+Function copy_znode() is split into 2 parts: resource allocation
+and znode replacement, insert_old_idx() is split in similar way,
+so resource cleanup could be done in error handling path without
+corrupting metadata(mem & disk).
+It's okay that old index inserting is put behind of add_idx_dirt(),
+old index is used in layout_leb_in_gaps(), so the two processes do
+not depend on each other.
+
+Link: https://bugzilla.kernel.org/show_bug.cgi?id=216705
+Fixes: 1e51764a3c2a ("UBIFS: add new flash file system")
+Cc: stable@vger.kernel.org
+Signed-off-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ubifs/tnc.c |  137 ++++++++++++++++++++++++++++++++++++---------------------
+ 1 file changed, 87 insertions(+), 50 deletions(-)
+
+--- a/fs/ubifs/tnc.c
++++ b/fs/ubifs/tnc.c
+@@ -44,6 +44,33 @@ enum {
+       NOT_ON_MEDIA = 3,
+ };
++static void do_insert_old_idx(struct ubifs_info *c,
++                            struct ubifs_old_idx *old_idx)
++{
++      struct ubifs_old_idx *o;
++      struct rb_node **p, *parent = NULL;
++
++      p = &c->old_idx.rb_node;
++      while (*p) {
++              parent = *p;
++              o = rb_entry(parent, struct ubifs_old_idx, rb);
++              if (old_idx->lnum < o->lnum)
++                      p = &(*p)->rb_left;
++              else if (old_idx->lnum > o->lnum)
++                      p = &(*p)->rb_right;
++              else if (old_idx->offs < o->offs)
++                      p = &(*p)->rb_left;
++              else if (old_idx->offs > o->offs)
++                      p = &(*p)->rb_right;
++              else {
++                      ubifs_err(c, "old idx added twice!");
++                      kfree(old_idx);
++              }
++      }
++      rb_link_node(&old_idx->rb, parent, p);
++      rb_insert_color(&old_idx->rb, &c->old_idx);
++}
++
+ /**
+  * insert_old_idx - record an index node obsoleted since the last commit start.
+  * @c: UBIFS file-system description object
+@@ -69,35 +96,15 @@ enum {
+  */
+ static int insert_old_idx(struct ubifs_info *c, int lnum, int offs)
+ {
+-      struct ubifs_old_idx *old_idx, *o;
+-      struct rb_node **p, *parent = NULL;
++      struct ubifs_old_idx *old_idx;
+       old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);
+       if (unlikely(!old_idx))
+               return -ENOMEM;
+       old_idx->lnum = lnum;
+       old_idx->offs = offs;
++      do_insert_old_idx(c, old_idx);
+-      p = &c->old_idx.rb_node;
+-      while (*p) {
+-              parent = *p;
+-              o = rb_entry(parent, struct ubifs_old_idx, rb);
+-              if (lnum < o->lnum)
+-                      p = &(*p)->rb_left;
+-              else if (lnum > o->lnum)
+-                      p = &(*p)->rb_right;
+-              else if (offs < o->offs)
+-                      p = &(*p)->rb_left;
+-              else if (offs > o->offs)
+-                      p = &(*p)->rb_right;
+-              else {
+-                      ubifs_err(c, "old idx added twice!");
+-                      kfree(old_idx);
+-                      return 0;
+-              }
+-      }
+-      rb_link_node(&old_idx->rb, parent, p);
+-      rb_insert_color(&old_idx->rb, &c->old_idx);
+       return 0;
+ }
+@@ -199,23 +206,6 @@ static struct ubifs_znode *copy_znode(st
+       __set_bit(DIRTY_ZNODE, &zn->flags);
+       __clear_bit(COW_ZNODE, &zn->flags);
+-      ubifs_assert(c, !ubifs_zn_obsolete(znode));
+-      __set_bit(OBSOLETE_ZNODE, &znode->flags);
+-
+-      if (znode->level != 0) {
+-              int i;
+-              const int n = zn->child_cnt;
+-
+-              /* The children now have new parent */
+-              for (i = 0; i < n; i++) {
+-                      struct ubifs_zbranch *zbr = &zn->zbranch[i];
+-
+-                      if (zbr->znode)
+-                              zbr->znode->parent = zn;
+-              }
+-      }
+-
+-      atomic_long_inc(&c->dirty_zn_cnt);
+       return zn;
+ }
+@@ -234,6 +224,42 @@ static int add_idx_dirt(struct ubifs_inf
+ }
+ /**
++ * replace_znode - replace old znode with new znode.
++ * @c: UBIFS file-system description object
++ * @new_zn: new znode
++ * @old_zn: old znode
++ * @zbr: the branch of parent znode
++ *
++ * Replace old znode with new znode in TNC.
++ */
++static void replace_znode(struct ubifs_info *c, struct ubifs_znode *new_zn,
++                        struct ubifs_znode *old_zn, struct ubifs_zbranch *zbr)
++{
++      ubifs_assert(c, !ubifs_zn_obsolete(old_zn));
++      __set_bit(OBSOLETE_ZNODE, &old_zn->flags);
++
++      if (old_zn->level != 0) {
++              int i;
++              const int n = new_zn->child_cnt;
++
++              /* The children now have new parent */
++              for (i = 0; i < n; i++) {
++                      struct ubifs_zbranch *child = &new_zn->zbranch[i];
++
++                      if (child->znode)
++                              child->znode->parent = new_zn;
++              }
++      }
++
++      zbr->znode = new_zn;
++      zbr->lnum = 0;
++      zbr->offs = 0;
++      zbr->len = 0;
++
++      atomic_long_inc(&c->dirty_zn_cnt);
++}
++
++/**
+  * dirty_cow_znode - ensure a znode is not being committed.
+  * @c: UBIFS file-system description object
+  * @zbr: branch of znode to check
+@@ -265,21 +291,32 @@ static struct ubifs_znode *dirty_cow_zno
+               return zn;
+       if (zbr->len) {
+-              err = insert_old_idx(c, zbr->lnum, zbr->offs);
+-              if (unlikely(err))
+-                      return ERR_PTR(err);
++              struct ubifs_old_idx *old_idx;
++
++              old_idx = kmalloc(sizeof(struct ubifs_old_idx), GFP_NOFS);
++              if (unlikely(!old_idx)) {
++                      err = -ENOMEM;
++                      goto out;
++              }
++              old_idx->lnum = zbr->lnum;
++              old_idx->offs = zbr->offs;
++
+               err = add_idx_dirt(c, zbr->lnum, zbr->len);
+-      } else
+-              err = 0;
++              if (err) {
++                      kfree(old_idx);
++                      goto out;
++              }
+-      zbr->znode = zn;
+-      zbr->lnum = 0;
+-      zbr->offs = 0;
+-      zbr->len = 0;
++              do_insert_old_idx(c, old_idx);
++      }
++
++      replace_znode(c, zn, znode, zbr);
+-      if (unlikely(err))
+-              return ERR_PTR(err);
+       return zn;
++
++out:
++      kfree(zn);
++      return ERR_PTR(err);
+ }
+ /**
diff --git a/queue-6.1/ubifs-fix-memory-leak-in-do_rename.patch b/queue-6.1/ubifs-fix-memory-leak-in-do_rename.patch
new file mode 100644 (file)
index 0000000..0e7c069
--- /dev/null
@@ -0,0 +1,75 @@
+From 3a36d20e012903f45714df2731261fdefac900cb Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?M=C3=A5rten=20Lindahl?= <marten.lindahl@axis.com>
+Date: Thu, 30 Mar 2023 16:40:59 +0200
+Subject: ubifs: Fix memory leak in do_rename
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mårten Lindahl <marten.lindahl@axis.com>
+
+commit 3a36d20e012903f45714df2731261fdefac900cb upstream.
+
+If renaming a file in an encrypted directory, function
+fscrypt_setup_filename allocates memory for a file name. This name is
+never used, and before returning to the caller the memory for it is not
+freed.
+
+When running kmemleak on it we see that it is registered as a leak. The
+report below is triggered by a simple program 'rename' that renames a
+file in an encrypted directory:
+
+  unreferenced object 0xffff888101502840 (size 32):
+    comm "rename", pid 9404, jiffies 4302582475 (age 435.735s)
+    backtrace:
+      __kmem_cache_alloc_node
+      __kmalloc
+      fscrypt_setup_filename
+      do_rename
+      ubifs_rename
+      vfs_rename
+      do_renameat2
+
+To fix this we can remove the call to fscrypt_setup_filename as it's not
+needed.
+
+Fixes: 278d9a243635f26 ("ubifs: Rename whiteout atomically")
+Reported-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ubifs/dir.c |    6 ------
+ 1 file changed, 6 deletions(-)
+
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -358,7 +358,6 @@ static struct inode *create_whiteout(str
+       umode_t mode = S_IFCHR | WHITEOUT_MODE;
+       struct inode *inode;
+       struct ubifs_info *c = dir->i_sb->s_fs_info;
+-      struct fscrypt_name nm;
+       /*
+        * Create an inode('nlink = 1') for whiteout without updating journal,
+@@ -369,10 +368,6 @@ static struct inode *create_whiteout(str
+       dbg_gen("dent '%pd', mode %#hx in dir ino %lu",
+               dentry, mode, dir->i_ino);
+-      err = fscrypt_setup_filename(dir, &dentry->d_name, 0, &nm);
+-      if (err)
+-              return ERR_PTR(err);
+-
+       inode = ubifs_new_inode(c, dir, mode, false);
+       if (IS_ERR(inode)) {
+               err = PTR_ERR(inode);
+@@ -395,7 +390,6 @@ out_inode:
+       make_bad_inode(inode);
+       iput(inode);
+ out_free:
+-      fscrypt_free_filename(&nm);
+       ubifs_err(c, "cannot create whiteout file, error %d", err);
+       return ERR_PTR(err);
+ }
diff --git a/queue-6.1/ubifs-free-memory-for-tmpfile-name.patch b/queue-6.1/ubifs-free-memory-for-tmpfile-name.patch
new file mode 100644 (file)
index 0000000..b82a3de
--- /dev/null
@@ -0,0 +1,52 @@
+From 1fb815b38bb31d6af9bd0540b8652a0d6fe6cfd3 Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?M=C3=A5rten=20Lindahl?= <marten.lindahl@axis.com>
+Date: Thu, 30 Mar 2023 11:32:14 +0200
+Subject: ubifs: Free memory for tmpfile name
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+From: Mårten Lindahl <marten.lindahl@axis.com>
+
+commit 1fb815b38bb31d6af9bd0540b8652a0d6fe6cfd3 upstream.
+
+When opening a ubifs tmpfile on an encrypted directory, function
+fscrypt_setup_filename allocates memory for the name that is to be
+stored in the directory entry, but after the name has been copied to the
+directory entry inode, the memory is not freed.
+
+When running kmemleak on it we see that it is registered as a leak. The
+report below is triggered by a simple program 'tmpfile' just opening a
+tmpfile:
+
+  unreferenced object 0xffff88810178f380 (size 32):
+    comm "tmpfile", pid 509, jiffies 4294934744 (age 1524.742s)
+    backtrace:
+      __kmem_cache_alloc_node
+      __kmalloc
+      fscrypt_setup_filename
+      ubifs_tmpfile
+      vfs_tmpfile
+      path_openat
+
+Free this memory after it has been copied to the inode.
+
+Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com>
+Reviewed-by: Zhihao Cheng <chengzhihao1@huawei.com>
+Cc: stable@vger.kernel.org
+Signed-off-by: Richard Weinberger <richard@nod.at>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ubifs/dir.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/fs/ubifs/dir.c
++++ b/fs/ubifs/dir.c
+@@ -492,6 +492,7 @@ static int ubifs_tmpfile(struct user_nam
+       unlock_2_inodes(dir, inode);
+       ubifs_release_budget(c, &req);
++      fscrypt_free_filename(&nm);
+       return finish_open_simple(file, 0);
diff --git a/queue-6.1/xfs-don-t-consider-future-format-versions-valid.patch b/queue-6.1/xfs-don-t-consider-future-format-versions-valid.patch
new file mode 100644 (file)
index 0000000..6e58347
--- /dev/null
@@ -0,0 +1,61 @@
+From aa88019851a85df80cb77f143758b13aee09e3d9 Mon Sep 17 00:00:00 2001
+From: Dave Chinner <dchinner@redhat.com>
+Date: Wed, 12 Apr 2023 15:48:50 +1000
+Subject: xfs: don't consider future format versions valid
+
+From: Dave Chinner <dchinner@redhat.com>
+
+commit aa88019851a85df80cb77f143758b13aee09e3d9 upstream.
+
+In commit fe08cc504448 we reworked the valid superblock version
+checks. If it is a V5 filesystem, it is always valid, then we
+checked if the version was less than V4 (reject) and then checked
+feature fields in the V4 flags to determine if it was valid.
+
+What we missed was that if the version is not V4 at this point,
+we shoudl reject the fs. i.e. the check current treats V6+
+filesystems as if it was a v4 filesystem. Fix this.
+
+cc: stable@vger.kernel.org
+Fixes: fe08cc504448 ("xfs: open code sb verifier feature checks")
+Signed-off-by: Dave Chinner <dchinner@redhat.com>
+Reviewed-by: Darrick J. Wong <djwong@kernel.org>
+Signed-off-by: Dave Chinner <david@fromorbit.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/xfs/libxfs/xfs_sb.c |   11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+--- a/fs/xfs/libxfs/xfs_sb.c
++++ b/fs/xfs/libxfs/xfs_sb.c
+@@ -72,7 +72,8 @@ xfs_sb_validate_v5_features(
+ }
+ /*
+- * We support all XFS versions newer than a v4 superblock with V2 directories.
++ * We current support XFS v5 formats with known features and v4 superblocks with
++ * at least V2 directories.
+  */
+ bool
+ xfs_sb_good_version(
+@@ -86,16 +87,16 @@ xfs_sb_good_version(
+       if (xfs_sb_is_v5(sbp))
+               return xfs_sb_validate_v5_features(sbp);
++      /* versions prior to v4 are not supported */
++      if (XFS_SB_VERSION_NUM(sbp) != XFS_SB_VERSION_4)
++              return false;
++
+       /* We must not have any unknown v4 feature bits set */
+       if ((sbp->sb_versionnum & ~XFS_SB_VERSION_OKBITS) ||
+           ((sbp->sb_versionnum & XFS_SB_VERSION_MOREBITSBIT) &&
+            (sbp->sb_features2 & ~XFS_SB_VERSION2_OKBITS)))
+               return false;
+-      /* versions prior to v4 are not supported */
+-      if (XFS_SB_VERSION_NUM(sbp) < XFS_SB_VERSION_4)
+-              return false;
+-
+       /* V4 filesystems need v2 directories and unwritten extents */
+       if (!(sbp->sb_versionnum & XFS_SB_VERSION_DIRV2BIT))
+               return false;