]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
5.15-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Apr 2026 11:29:14 +0000 (13:29 +0200)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 23 Apr 2026 11:29:14 +0000 (13:29 +0200)
added patches:
arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-to-0.81v.patch
arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-up-to-0.85v.patch
arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch
fs-ocfs2-fix-comments-mentioning-i_mutex.patch
mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch
mptcp-fix-lock-class-name-family-in-pm_nl_create_listen_socket.patch
netdevsim-fix-memory-leak-of-nsim_dev-fa_cookie.patch
netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch
ocfs2-add-inline-inode-consistency-check-to-ocfs2_validate_inode_block.patch
ocfs2-fix-out-of-bounds-write-in-ocfs2_write_end_inline.patch
ocfs2-fix-possible-deadlock-between-unlink-and-dio_end_io_write.patch
ocfs2-validate-inline-data-i_size-during-inode-read.patch
powerpc64-bpf-do-not-increment-tailcall-count-when-prog-is-null.patch
revert-arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch
rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch
rxrpc-fix-key-quota-calculation-for-multitoken-keys.patch
rxrpc-reject-undecryptable-rxkad-response-tickets.patch
tty-n_gsm-fix-deadlock-and-link-starvation-in-outgoing-data-path.patch
xen-netfront-handle-null-returned-by-xdp_convert_buff_to_frame.patch
xfrm-clear-trailing-padding-in-build_polexpire.patch

21 files changed:
queue-5.15/arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-to-0.81v.patch [new file with mode: 0644]
queue-5.15/arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-up-to-0.85v.patch [new file with mode: 0644]
queue-5.15/arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch [new file with mode: 0644]
queue-5.15/fs-ocfs2-fix-comments-mentioning-i_mutex.patch [new file with mode: 0644]
queue-5.15/mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch [new file with mode: 0644]
queue-5.15/mptcp-fix-lock-class-name-family-in-pm_nl_create_listen_socket.patch [new file with mode: 0644]
queue-5.15/netdevsim-fix-memory-leak-of-nsim_dev-fa_cookie.patch [new file with mode: 0644]
queue-5.15/netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch [new file with mode: 0644]
queue-5.15/ocfs2-add-inline-inode-consistency-check-to-ocfs2_validate_inode_block.patch [new file with mode: 0644]
queue-5.15/ocfs2-fix-out-of-bounds-write-in-ocfs2_write_end_inline.patch [new file with mode: 0644]
queue-5.15/ocfs2-fix-possible-deadlock-between-unlink-and-dio_end_io_write.patch [new file with mode: 0644]
queue-5.15/ocfs2-validate-inline-data-i_size-during-inode-read.patch [new file with mode: 0644]
queue-5.15/powerpc64-bpf-do-not-increment-tailcall-count-when-prog-is-null.patch [new file with mode: 0644]
queue-5.15/revert-arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch [new file with mode: 0644]
queue-5.15/rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch [new file with mode: 0644]
queue-5.15/rxrpc-fix-key-quota-calculation-for-multitoken-keys.patch [new file with mode: 0644]
queue-5.15/rxrpc-reject-undecryptable-rxkad-response-tickets.patch [new file with mode: 0644]
queue-5.15/series
queue-5.15/tty-n_gsm-fix-deadlock-and-link-starvation-in-outgoing-data-path.patch [new file with mode: 0644]
queue-5.15/xen-netfront-handle-null-returned-by-xdp_convert_buff_to_frame.patch [new file with mode: 0644]
queue-5.15/xfrm-clear-trailing-padding-in-build_polexpire.patch [new file with mode: 0644]

diff --git a/queue-5.15/arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-to-0.81v.patch b/queue-5.15/arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-to-0.81v.patch
new file mode 100644 (file)
index 0000000..8d2c8d3
--- /dev/null
@@ -0,0 +1,36 @@
+From stable+bounces-236109-greg=kroah.com@vger.kernel.org Mon Apr 13 16:22:47 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 10:20:55 -0400
+Subject: arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage to 0.81V
+To: stable@vger.kernel.org
+Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>, Martin Kepplinger <martin.kepplinger@puri.sm>, Shawn Guo <shawnguo@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413142057.2909222-2-sashal@kernel.org>
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+[ Upstream commit 94b91e3ca6688fafd6a5dd70bd89fe9d3aee88da ]
+
+0.8V is outside of the operating voltage specified for imx8mq, see
+chapter 3.1.4 "Operating ranges" of the IMX8MDQLQCEC document.
+
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Signed-off-by: Martin Kepplinger <martin.kepplinger@puri.sm>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: 511f76bf1dce ("arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage up to 0.85V")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -706,7 +706,7 @@
+                               regulator-ramp-delay = <1250>;
+                               rohm,dvs-run-voltage = <880000>;
+                               rohm,dvs-idle-voltage = <820000>;
+-                              rohm,dvs-suspend-voltage = <800000>;
++                              rohm,dvs-suspend-voltage = <810000>;
+                               regulator-always-on;
+                       };
diff --git a/queue-5.15/arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-up-to-0.85v.patch b/queue-5.15/arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-up-to-0.85v.patch
new file mode 100644 (file)
index 0000000..cb1a2f3
--- /dev/null
@@ -0,0 +1,41 @@
+From stable+bounces-236111-greg=kroah.com@vger.kernel.org Mon Apr 13 16:22:52 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 10:20:57 -0400
+Subject: arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage up to 0.85V
+To: stable@vger.kernel.org
+Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>, Frank Li <Frank.Li@nxp.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413142057.2909222-4-sashal@kernel.org>
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+[ Upstream commit 511f76bf1dce5acf8907b65a7d1bc8f7e7c0d637 ]
+
+The minimal voltage of VDD_SOC sourced from BUCK1 is 0.81V, which
+is the currently set value. However, BD71837 only guarantees accuracy
+of ±0.01V, and this still doesn't factor other reasons for actual
+voltage to slightly drop in, resulting in the possibility of running
+out of the operational range.
+
+Bump the voltage up to 0.85V, which should give enough headroom.
+
+Cc: stable@vger.kernel.org
+Fixes: 8f0216b006e5 ("arm64: dts: Add a device tree for the Librem 5 phone")
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -706,7 +706,7 @@
+                               regulator-ramp-delay = <1250>;
+                               rohm,dvs-run-voltage = <900000>;
+                               rohm,dvs-idle-voltage = <850000>;
+-                              rohm,dvs-suspend-voltage = <810000>;
++                              rohm,dvs-suspend-voltage = <850000>;
+                               regulator-always-on;
+                       };
diff --git a/queue-5.15/arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch b/queue-5.15/arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch
new file mode 100644 (file)
index 0000000..eee850e
--- /dev/null
@@ -0,0 +1,116 @@
+From stable+bounces-236108-greg=kroah.com@vger.kernel.org Mon Apr 13 16:27:58 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 10:20:54 -0400
+Subject: arm64: dts: imx8mq-librem5: Set the DVS voltages lower
+To: stable@vger.kernel.org
+Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>, Martin Kepplinger <martin.kepplinger@puri.sm>, Shawn Guo <shawnguo@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413142057.2909222-1-sashal@kernel.org>
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+[ Upstream commit c24a9b698fb02cd0723fa8375abab07f94b97b10 ]
+
+They're still in the operating range according to i.MX 8M Quad
+datasheet. There's some headroom added over minimal values to
+account for voltage drop.
+
+Operational ranges (min - typ - max [selected]):
+ - VDD_SOC (BUCK1): 0.81 - 0.9 - 0.99 [0.88]
+ - VDD_ARM (BUCK2): 0.81 - 0.9 - 1.05 [0.84] (1000MHz)
+                    0.90 - 1.0 - 1.05 [0.93] (1500MHz)
+ - VDD_GPU (BUCK3): 0.81 - 0.9 - 1.05 [0.85] (800MHz)
+                    0.90 - 1.0 - 1.05 [ -- ] (1000MHz)
+ - VDD_VPU (BUCK4): 0.81 - 0.9 - 1.05 [ -- ] (550/500/588MHz)
+                    0.90 - 1.0 - 1.05 [0.93] (660/600/800MHz)
+
+Idle power consumption doesn't appear to be influenced much,
+but a simple load test (`cat /dev/urandom | pigz - > /dev/null`
+combined with running Animatch) seems to show about 0.3W of
+difference.
+
+Care is advised, as there may be differences between each
+units in how low can they be undervolted - in my experience,
+reaching that point usually makes the phone fail to boot.
+In my case, it appears that my Birch phone can go down the most.
+
+This is a somewhat conservative set of values that I've seen
+working well on all my devices; I haven't tried very hard to
+optimize it, so more experiments are welcome.
+
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Signed-off-by: Martin Kepplinger <martin.kepplinger@puri.sm>
+Signed-off-by: Shawn Guo <shawnguo@kernel.org>
+Stable-dep-of: 511f76bf1dce ("arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage up to 0.85V")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts |    2 -
+ arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi   |   22 ++++++++++++++------
+ 2 files changed, 17 insertions(+), 7 deletions(-)
+
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
+@@ -12,7 +12,7 @@
+ &a53_opp_table {
+       opp-1000000000 {
+-              opp-microvolt = <1000000>;
++              opp-microvolt = <950000>;
+       };
+ };
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -704,8 +704,8 @@
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               regulator-ramp-delay = <1250>;
+-                              rohm,dvs-run-voltage = <900000>;
+-                              rohm,dvs-idle-voltage = <850000>;
++                              rohm,dvs-run-voltage = <880000>;
++                              rohm,dvs-idle-voltage = <820000>;
+                               rohm,dvs-suspend-voltage = <800000>;
+                               regulator-always-on;
+                       };
+@@ -716,8 +716,8 @@
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               regulator-ramp-delay = <1250>;
+-                              rohm,dvs-run-voltage = <1000000>;
+-                              rohm,dvs-idle-voltage = <900000>;
++                              rohm,dvs-run-voltage = <950000>;
++                              rohm,dvs-idle-voltage = <850000>;
+                               regulator-always-on;
+                       };
+@@ -726,14 +726,14 @@
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+-                              rohm,dvs-run-voltage = <900000>;
++                              rohm,dvs-run-voltage = <850000>;
+                       };
+                       buck4_reg: BUCK4 {
+                               regulator-name = "buck4";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+-                              rohm,dvs-run-voltage = <1000000>;
++                              rohm,dvs-run-voltage = <930000>;
+                       };
+                       buck5_reg: BUCK5 {
+@@ -1214,3 +1214,13 @@
+       fsl,ext-reset-output;
+       status = "okay";
+ };
++
++&a53_opp_table {
++      opp-1000000000 {
++              opp-microvolt = <850000>;
++      };
++
++      opp-1500000000 {
++              opp-microvolt = <950000>;
++      };
++};
diff --git a/queue-5.15/fs-ocfs2-fix-comments-mentioning-i_mutex.patch b/queue-5.15/fs-ocfs2-fix-comments-mentioning-i_mutex.patch
new file mode 100644 (file)
index 0000000..f44af4e
--- /dev/null
@@ -0,0 +1,209 @@
+From stable+bounces-239239-greg=kroah.com@vger.kernel.org Mon Apr 20 18:53:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 10:41:57 -0400
+Subject: fs/ocfs2: fix comments mentioning i_mutex
+To: stable@vger.kernel.org
+Cc: hongnanli <hongnan.li@linux.alibaba.com>, Joseph Qi <joseph.qi@linux.alibaba.com>, Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>, Junxiao Bi <junxiao.bi@oracle.com>, Changwei Ge <gechangwei@live.cn>, Gang He <ghe@suse.com>, Jun Piao <piaojun@huawei.com>, Andrew Morton <akpm@linux-foundation.org>, Linus Torvalds <torvalds@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260420144158.1143438-1-sashal@kernel.org>
+
+From: hongnanli <hongnan.li@linux.alibaba.com>
+
+[ Upstream commit 137cebf9432eae024d0334953ed92a2a78619b52 ]
+
+inode->i_mutex has been replaced with inode->i_rwsem long ago.  Fix
+comments still mentioning i_mutex.
+
+Link: https://lkml.kernel.org/r/20220214031314.100094-1-hongnan.li@linux.alibaba.com
+Signed-off-by: hongnanli <hongnan.li@linux.alibaba.com>
+Acked-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Gang He <ghe@suse.com>
+Cc: Jun Piao <piaojun@huawei.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Stable-dep-of: b02da26a992d ("ocfs2: fix possible deadlock between unlink and dio_end_io_write")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/alloc.c               |    2 +-
+ fs/ocfs2/aops.c                |    2 +-
+ fs/ocfs2/cluster/nodemanager.c |    2 +-
+ fs/ocfs2/dir.c                 |    4 ++--
+ fs/ocfs2/file.c                |    4 ++--
+ fs/ocfs2/inode.c               |    2 +-
+ fs/ocfs2/localalloc.c          |    6 +++---
+ fs/ocfs2/namei.c               |    2 +-
+ fs/ocfs2/ocfs2.h               |    4 ++--
+ fs/ocfs2/quota_global.c        |    2 +-
+ fs/ocfs2/xattr.c               |    2 +-
+ 11 files changed, 16 insertions(+), 16 deletions(-)
+
+--- a/fs/ocfs2/alloc.c
++++ b/fs/ocfs2/alloc.c
+@@ -5986,7 +5986,7 @@ bail:
+       return status;
+ }
+-/* Expects you to already be holding tl_inode->i_mutex */
++/* Expects you to already be holding tl_inode->i_rwsem */
+ int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
+ {
+       int status;
+--- a/fs/ocfs2/aops.c
++++ b/fs/ocfs2/aops.c
+@@ -2324,7 +2324,7 @@ static int ocfs2_dio_end_io_write(struct
+       down_write(&oi->ip_alloc_sem);
+-      /* Delete orphan before acquire i_mutex. */
++      /* Delete orphan before acquire i_rwsem. */
+       if (dwc->dw_orphaned) {
+               BUG_ON(dwc->dw_writer_pid != task_pid_nr(current));
+--- a/fs/ocfs2/cluster/nodemanager.c
++++ b/fs/ocfs2/cluster/nodemanager.c
+@@ -689,7 +689,7 @@ static struct config_group *o2nm_cluster
+       struct o2nm_node_group *ns = NULL;
+       struct config_group *o2hb_group = NULL, *ret = NULL;
+-      /* this runs under the parent dir's i_mutex; there can be only
++      /* this runs under the parent dir's i_rwsem; there can be only
+        * one caller in here at a time */
+       if (o2nm_single_cluster)
+               return ERR_PTR(-ENOSPC);
+--- a/fs/ocfs2/dir.c
++++ b/fs/ocfs2/dir.c
+@@ -1979,7 +1979,7 @@ bail_nolock:
+ }
+ /*
+- * NOTE: this should always be called with parent dir i_mutex taken.
++ * NOTE: this should always be called with parent dir i_rwsem taken.
+  */
+ int ocfs2_find_files_on_disk(const char *name,
+                            int namelen,
+@@ -2026,7 +2026,7 @@ int ocfs2_lookup_ino_from_name(struct in
+  * Return -EEXIST if the directory contains the name
+  * Return -EFSCORRUPTED if found corruption
+  *
+- * Callers should have i_mutex + a cluster lock on dir
++ * Callers should have i_rwsem + a cluster lock on dir
+  */
+ int ocfs2_check_dir_for_entry(struct inode *dir,
+                             const char *name,
+--- a/fs/ocfs2/file.c
++++ b/fs/ocfs2/file.c
+@@ -270,7 +270,7 @@ int ocfs2_update_inode_atime(struct inod
+       /*
+        * Don't use ocfs2_mark_inode_dirty() here as we don't always
+-       * have i_mutex to guard against concurrent changes to other
++       * have i_rwsem to guard against concurrent changes to other
+        * inode fields.
+        */
+       inode->i_atime = current_time(inode);
+@@ -1068,7 +1068,7 @@ static int ocfs2_extend_file(struct inod
+       /*
+        * The alloc sem blocks people in read/write from reading our
+        * allocation until we're done changing it. We depend on
+-       * i_mutex to block other extend/truncate calls while we're
++       * i_rwsem to block other extend/truncate calls while we're
+        * here.  We even have to hold it for sparse files because there
+        * might be some tail zeroing.
+        */
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -713,7 +713,7 @@ bail:
+ /*
+  * Serialize with orphan dir recovery. If the process doing
+  * recovery on this orphan dir does an iget() with the dir
+- * i_mutex held, we'll deadlock here. Instead we detect this
++ * i_rwsem held, we'll deadlock here. Instead we detect this
+  * and exit early - recovery will wipe this inode for us.
+  */
+ static int ocfs2_check_orphan_recovery_state(struct ocfs2_super *osb,
+--- a/fs/ocfs2/localalloc.c
++++ b/fs/ocfs2/localalloc.c
+@@ -606,7 +606,7 @@ out:
+ /*
+  * make sure we've got at least bits_wanted contiguous bits in the
+- * local alloc. You lose them when you drop i_mutex.
++ * local alloc. You lose them when you drop i_rwsem.
+  *
+  * We will add ourselves to the transaction passed in, but may start
+  * our own in order to shift windows.
+@@ -636,7 +636,7 @@ int ocfs2_reserve_local_alloc_bits(struc
+       /*
+        * We must double check state and allocator bits because
+-       * another process may have changed them while holding i_mutex.
++       * another process may have changed them while holding i_rwsem.
+        */
+       spin_lock(&osb->osb_lock);
+       if (!ocfs2_la_state_enabled(osb) ||
+@@ -1029,7 +1029,7 @@ enum ocfs2_la_event {
+ /*
+  * Given an event, calculate the size of our next local alloc window.
+  *
+- * This should always be called under i_mutex of the local alloc inode
++ * This should always be called under i_rwsem of the local alloc inode
+  * so that local alloc disabling doesn't race with processes trying to
+  * use the allocator.
+  *
+--- a/fs/ocfs2/namei.c
++++ b/fs/ocfs2/namei.c
+@@ -485,7 +485,7 @@ leave:
+               ocfs2_free_alloc_context(meta_ac);
+       /*
+-       * We should call iput after the i_mutex of the bitmap been
++       * We should call iput after the i_rwsem of the bitmap been
+        * unlocked in ocfs2_free_alloc_context, or the
+        * ocfs2_delete_inode will mutex_lock again.
+        */
+--- a/fs/ocfs2/ocfs2.h
++++ b/fs/ocfs2/ocfs2.h
+@@ -369,7 +369,7 @@ struct ocfs2_super
+       struct delayed_work             la_enable_wq;
+       /*
+-       * Must hold local alloc i_mutex and osb->osb_lock to change
++       * Must hold local alloc i_rwsem and osb->osb_lock to change
+        * local_alloc_bits. Reads can be done under either lock.
+        */
+       unsigned int local_alloc_bits;
+@@ -444,7 +444,7 @@ struct ocfs2_super
+       atomic_t                        osb_tl_disable;
+       /*
+        * How many clusters in our truncate log.
+-       * It must be protected by osb_tl_inode->i_mutex.
++       * It must be protected by osb_tl_inode->i_rwsem.
+        */
+       unsigned int truncated_clusters;
+--- a/fs/ocfs2/quota_global.c
++++ b/fs/ocfs2/quota_global.c
+@@ -36,7 +36,7 @@
+  * should be obeyed by all the functions:
+  * - any write of quota structure (either to local or global file) is protected
+  *   by dqio_sem or dquot->dq_lock.
+- * - any modification of global quota file holds inode cluster lock, i_mutex,
++ * - any modification of global quota file holds inode cluster lock, i_rwsem,
+  *   and ip_alloc_sem of the global quota file (achieved by
+  *   ocfs2_lock_global_qf). It also has to hold qinfo_lock.
+  * - an allocation of new blocks for local quota file is protected by
+--- a/fs/ocfs2/xattr.c
++++ b/fs/ocfs2/xattr.c
+@@ -7208,7 +7208,7 @@ out:
+  * Used for reflink a non-preserve-security file.
+  *
+  * It uses common api like ocfs2_xattr_set, so the caller
+- * must not hold any lock expect i_mutex.
++ * must not hold any lock expect i_rwsem.
+  */
+ int ocfs2_init_security_and_acl(struct inode *dir,
+                               struct inode *inode,
diff --git a/queue-5.15/mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch b/queue-5.15/mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch
new file mode 100644 (file)
index 0000000..fdd5a3d
--- /dev/null
@@ -0,0 +1,91 @@
+From stable+bounces-239966-greg=kroah.com@vger.kernel.org Mon Apr 20 20:27:29 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 13:29:31 -0400
+Subject: mm: blk-cgroup: fix use-after-free in cgwb_release_workfn()
+To: stable@vger.kernel.org
+Cc: Breno Leitao <leitao@debian.org>, Dennis Zhou <dennis@kernel.org>, Shakeel Butt <shakeel.butt@linux.dev>, David Hildenbrand <david@kernel.org>, Jens Axboe <axboe@kernel.dk>, Johannes Weiner <hannes@cmpxchg.org>, Josef Bacik <josef@toxicpanda.com>, JP Kobryn <inwardvessel@gmail.com>, Liam Howlett <liam.howlett@oracle.com>, "Lorenzo Stoakes (Oracle)" <ljs@kernel.org>, Martin KaFai Lau <martin.lau@linux.dev>, Michal Hocko <mhocko@suse.com>, Mike Rapoport <rppt@kernel.org>, Suren Baghdasaryan <surenb@google.com>, Tejun Heo <tj@kernel.org>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260420172931.1421876-1-sashal@kernel.org>
+
+From: Breno Leitao <leitao@debian.org>
+
+[ Upstream commit 8f5857be99f1ed1fa80991c72449541f634626ee ]
+
+cgwb_release_workfn() calls css_put(wb->blkcg_css) and then later accesses
+wb->blkcg_css again via blkcg_unpin_online().  If css_put() drops the last
+reference, the blkcg can be freed asynchronously (css_free_rwork_fn ->
+blkcg_css_free -> kfree) before blkcg_unpin_online() dereferences the
+pointer to access blkcg->online_pin, resulting in a use-after-free:
+
+  BUG: KASAN: slab-use-after-free in blkcg_unpin_online (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 block/blk-cgroup.c:1367)
+  Write of size 4 at addr ff11000117aa6160 by task kworker/71:1/531
+   Workqueue: cgwb_release cgwb_release_workfn
+   Call Trace:
+    <TASK>
+     blkcg_unpin_online (./include/linux/instrumented.h:112 ./include/linux/atomic/atomic-instrumented.h:400 ./include/linux/refcount.h:389 ./include/linux/refcount.h:432 ./include/linux/refcount.h:450 block/blk-cgroup.c:1367)
+     cgwb_release_workfn (mm/backing-dev.c:629)
+     process_scheduled_works (kernel/workqueue.c:3278 kernel/workqueue.c:3385)
+
+   Freed by task 1016:
+    kfree (./include/linux/kasan.h:235 mm/slub.c:2689 mm/slub.c:6246 mm/slub.c:6561)
+    css_free_rwork_fn (kernel/cgroup/cgroup.c:5542)
+    process_scheduled_works (kernel/workqueue.c:3302 kernel/workqueue.c:3385)
+
+** Stack based on commit 66672af7a095 ("Add linux-next specific files
+for 20260410")
+
+I am seeing this crash sporadically in Meta fleet across multiple kernel
+versions.  A full reproducer is available at:
+https://github.com/leitao/debug/blob/main/reproducers/repro_blkcg_uaf.sh
+
+(The race window is narrow.  To make it easily reproducible, inject a
+msleep(100) between css_put() and blkcg_unpin_online() in
+cgwb_release_workfn().  With that delay and a KASAN-enabled kernel, the
+reproducer triggers the splat reliably in less than a second.)
+
+Fix this by moving blkcg_unpin_online() before css_put(), so the
+cgwb's CSS reference keeps the blkcg alive while blkcg_unpin_online()
+accesses it.
+
+Link: https://lore.kernel.org/20260413-blkcg-v1-1-35b72622d16c@debian.org
+Fixes: 59b57717fff8 ("blkcg: delay blkg destruction until after writeback has finished")
+Signed-off-by: Breno Leitao <leitao@debian.org>
+Reviewed-by: Dennis Zhou <dennis@kernel.org>
+Reviewed-by: Shakeel Butt <shakeel.butt@linux.dev>
+Cc: David Hildenbrand <david@kernel.org>
+Cc: Jens Axboe <axboe@kernel.dk>
+Cc: Johannes Weiner <hannes@cmpxchg.org>
+Cc: Josef Bacik <josef@toxicpanda.com>
+Cc: JP Kobryn <inwardvessel@gmail.com>
+Cc: Liam Howlett <liam.howlett@oracle.com>
+Cc: Lorenzo Stoakes (Oracle) <ljs@kernel.org>
+Cc: Martin KaFai Lau <martin.lau@linux.dev>
+Cc: Michal Hocko <mhocko@suse.com>
+Cc: Mike Rapoport <rppt@kernel.org>
+Cc: Suren Baghdasaryan <surenb@google.com>
+Cc: Tejun Heo <tj@kernel.org>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ mm/backing-dev.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/mm/backing-dev.c
++++ b/mm/backing-dev.c
+@@ -404,12 +404,13 @@ static void cgwb_release_workfn(struct w
+       wb_shutdown(wb);
+       css_put(wb->memcg_css);
+-      css_put(wb->blkcg_css);
+-      mutex_unlock(&wb->bdi->cgwb_release_mutex);
+       /* triggers blkg destruction if no online users left */
+       blkcg_unpin_online(blkcg);
++      css_put(wb->blkcg_css);
++      mutex_unlock(&wb->bdi->cgwb_release_mutex);
++
+       fprop_local_destroy_percpu(&wb->memcg_completions);
+       spin_lock_irq(&cgwb_lock);
diff --git a/queue-5.15/mptcp-fix-lock-class-name-family-in-pm_nl_create_listen_socket.patch b/queue-5.15/mptcp-fix-lock-class-name-family-in-pm_nl_create_listen_socket.patch
new file mode 100644 (file)
index 0000000..7adc952
--- /dev/null
@@ -0,0 +1,41 @@
+From stable+bounces-233086-greg=kroah.com@vger.kernel.org Thu Apr  2 19:42:24 2026
+From: "Matthieu Baerts (NGI0)" <matttbe@kernel.org>
+Date: Thu,  2 Apr 2026 19:42:01 +0200
+Subject: MPTCP: fix lock class name family in pm_nl_create_listen_socket
+To: stable@vger.kernel.org, gregkh@linuxfoundation.org
+Cc: MPTCP Upstream <mptcp@lists.linux.dev>, Li Xiasong <lixiasong1@huawei.com>, "Matthieu Baerts (NGI0)" <matttbe@kernel.org>, Jakub Kicinski <kuba@kernel.org>
+Message-ID: <20260402174200.3474039-2-matttbe@kernel.org>
+
+From: Li Xiasong <lixiasong1@huawei.com>
+
+commit 7ab4a7c5d969642782b8a5b608da0dd02aa9f229 upstream.
+
+In mptcp_pm_nl_create_listen_socket(), use entry->addr.family
+instead of sk->sk_family for lock class setup. The 'sk' parameter
+is a netlink socket, not the MPTCP subflow socket being created.
+
+Fixes: cee4034a3db1 ("mptcp: fix lockdep false positive in mptcp_pm_nl_create_listen_socket()")
+Signed-off-by: Li Xiasong <lixiasong1@huawei.com>
+Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Link: https://patch.msgid.link/20260319112159.3118874-1-lixiasong1@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ Conflict in pm_kernel.c, because commit 8617e85e04bd ("mptcp: pm:
+  split in-kernel PM specific code") is not in this version, and moves
+  code from pm_netlink.c to pm_kernel.c. ]
+Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/mptcp/pm_netlink.c |    2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+--- a/net/mptcp/pm_netlink.c
++++ b/net/mptcp/pm_netlink.c
+@@ -1041,7 +1041,7 @@ static struct lock_class_key mptcp_keys[
+ static int mptcp_pm_nl_create_listen_socket(struct sock *sk,
+                                           struct mptcp_pm_addr_entry *entry)
+ {
+-      bool is_ipv6 = sk->sk_family == AF_INET6;
++      bool is_ipv6 = entry->addr.family == AF_INET6;
+       int addrlen = sizeof(struct sockaddr_in);
+       struct sockaddr_storage addr;
+       struct socket *ssock;
diff --git a/queue-5.15/netdevsim-fix-memory-leak-of-nsim_dev-fa_cookie.patch b/queue-5.15/netdevsim-fix-memory-leak-of-nsim_dev-fa_cookie.patch
new file mode 100644 (file)
index 0000000..021fe76
--- /dev/null
@@ -0,0 +1,62 @@
+From stable+bounces-230415-greg=kroah.com@vger.kernel.org Thu Mar 26 04:18:23 2026
+From: Johnny Hao <johnny_haocn@sina.com>
+Date: Thu, 26 Mar 2026 11:18:02 +0800
+Subject: netdevsim: Fix memory leak of nsim_dev->fa_cookie
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, Wang Yufen <wangyufen@huawei.com>, Jiri Pirko <jiri@mellanox.com>, Jakub Kicinski <kuba@kernel.org>, Johnny Hao <johnny_haocn@sina.com>
+Message-ID: <20260326031802.2410719-1-johnny_haocn@sina.com>
+
+From: Wang Yufen <wangyufen@huawei.com>
+
+[ Upstream commit 064bc7312bd09a48798418663090be0c776183db ]
+
+kmemleak reports this issue:
+
+unreferenced object 0xffff8881bac872d0 (size 8):
+  comm "sh", pid 58603, jiffies 4481524462 (age 68.065s)
+  hex dump (first 8 bytes):
+    04 00 00 00 de ad be ef                          ........
+  backtrace:
+    [<00000000c80b8577>] __kmalloc+0x49/0x150
+    [<000000005292b8c6>] nsim_dev_trap_fa_cookie_write+0xc1/0x210 [netdevsim]
+    [<0000000093d78e77>] full_proxy_write+0xf3/0x180
+    [<000000005a662c16>] vfs_write+0x1c5/0xaf0
+    [<000000007aabf84a>] ksys_write+0xed/0x1c0
+    [<000000005f1d2e47>] do_syscall_64+0x3b/0x90
+    [<000000006001c6ec>] entry_SYSCALL_64_after_hwframe+0x63/0xcd
+
+The issue occurs in the following scenarios:
+
+nsim_dev_trap_fa_cookie_write()
+  kmalloc() fa_cookie
+  nsim_dev->fa_cookie = fa_cookie
+..
+nsim_drv_remove()
+
+The fa_cookie allocked in nsim_dev_trap_fa_cookie_write() is not freed. To
+fix, add kfree(nsim_dev->fa_cookie) to nsim_drv_remove().
+
+Fixes: d3cbb907ae57 ("netdevsim: add ACL trap reporting cookie as a metadata")
+Signed-off-by: Wang Yufen <wangyufen@huawei.com>
+Cc: Jiri Pirko <jiri@mellanox.com>
+Link: https://lore.kernel.org/r/1668504625-14698-1-git-send-email-wangyufen@huawei.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ The context change is due to the commit 5e388f3dc38c
+("netdevsim: move vfconfig to nsim_dev") in v5.16
+which is irrelevant to the logic of this patch. ]
+Signed-off-by: Johnny Hao <johnny_haocn@sina.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/netdevsim/dev.c |    1 +
+ 1 file changed, 1 insertion(+)
+
+--- a/drivers/net/netdevsim/dev.c
++++ b/drivers/net/netdevsim/dev.c
+@@ -1582,6 +1582,7 @@ void nsim_dev_remove(struct nsim_bus_dev
+                                 ARRAY_SIZE(nsim_devlink_params));
+       devlink_unregister(devlink);
+       devlink_resources_unregister(devlink, NULL);
++      kfree(nsim_dev->fa_cookie);
+       devlink_free(devlink);
+ }
diff --git a/queue-5.15/netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch b/queue-5.15/netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch
new file mode 100644 (file)
index 0000000..af3ff3e
--- /dev/null
@@ -0,0 +1,67 @@
+From 07ace0bbe03b3d8e85869af1dec5e4087b1d57b8 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Tue, 13 Feb 2024 16:23:38 +0100
+Subject: netfilter: nft_set_pipapo: do not rely on ZERO_SIZE_PTR
+
+From: Florian Westphal <fw@strlen.de>
+
+commit 07ace0bbe03b3d8e85869af1dec5e4087b1d57b8 upstream.
+
+pipapo relies on kmalloc(0) returning ZERO_SIZE_PTR (i.e., not NULL
+but pointer is invalid).
+
+Rework this to not call slab allocator when we'd request a 0-byte
+allocation.
+
+Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+[Keerthana: In older stable branches (v6.6 and earlier), the allocation logic in
+pipapo_clone() still relies on `src->rules` rather than `src->rules_alloc`
+(introduced in v6.9 via 9f439bd6ef4f). Consequently, the previously
+backported INT_MAX clamping check uses `src->rules`. This patch correctly
+moves that `src->rules > (INT_MAX / ...)` check inside the new
+`if (src->rules > 0)` block]
+Signed-off-by: Keerthana K <keerthana.kalyanasundaram@broadcom.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/netfilter/nft_set_pipapo.c |   20 ++++++++++++++------
+ 1 file changed, 14 insertions(+), 6 deletions(-)
+
+--- a/net/netfilter/nft_set_pipapo.c
++++ b/net/netfilter/nft_set_pipapo.c
+@@ -525,6 +525,8 @@ static struct nft_pipapo_elem *pipapo_ge
+       int i;
+       m = priv->clone;
++      if (m->bsize_max == 0)
++              return ret;
+       res_map = kmalloc_array(m->bsize_max, sizeof(*res_map), GFP_ATOMIC);
+       if (!res_map) {
+@@ -1365,14 +1367,20 @@ static struct nft_pipapo_match *pipapo_c
+                      src->bsize * sizeof(*dst->lt) *
+                      src->groups * NFT_PIPAPO_BUCKETS(src->bb));
+-              if (src->rules > (INT_MAX / sizeof(*src->mt)))
+-                      goto out_mt;
++              if (src->rules > 0) {
++                      if (src->rules > (INT_MAX / sizeof(*src->mt)))
++                              goto out_mt;
++
++                      dst->mt = kvmalloc_array(src->rules, sizeof(*src->mt),
++                                               GFP_KERNEL);
++                      if (!dst->mt)
++                              goto out_mt;
+-              dst->mt = kvmalloc(src->rules * sizeof(*src->mt), GFP_KERNEL);
+-              if (!dst->mt)
+-                      goto out_mt;
++                      memcpy(dst->mt, src->mt, src->rules * sizeof(*src->mt));
++              } else {
++                      dst->mt = NULL;
++              }
+-              memcpy(dst->mt, src->mt, src->rules * sizeof(*src->mt));
+               src++;
+               dst++;
+       }
diff --git a/queue-5.15/ocfs2-add-inline-inode-consistency-check-to-ocfs2_validate_inode_block.patch b/queue-5.15/ocfs2-add-inline-inode-consistency-check-to-ocfs2_validate_inode_block.patch
new file mode 100644 (file)
index 0000000..015d8a2
--- /dev/null
@@ -0,0 +1,53 @@
+From stable+bounces-236156-greg=kroah.com@vger.kernel.org Mon Apr 13 17:56:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 11:50:23 -0400
+Subject: ocfs2: add inline inode consistency check to ocfs2_validate_inode_block()
+To: stable@vger.kernel.org
+Cc: Dmitry Antipov <dmantipov@yandex.ru>, syzbot+c16daba279a1161acfb0@syzkaller.appspotmail.com, Joseph Qi <joseph.qi@linux.alibaba.com>, Joseph Qi <jiangqi903@gmail.com>, Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>, Junxiao Bi <junxiao.bi@oracle.com>, Changwei Ge <gechangwei@live.cn>, Jun Piao <piaojun@huawei.com>, Heming Zhao <heming.zhao@suse.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413155025.3145781-1-sashal@kernel.org>
+
+From: Dmitry Antipov <dmantipov@yandex.ru>
+
+[ Upstream commit a2b1c419ff72ec62ff5831684e30cd1d4f0b09ee ]
+
+In 'ocfs2_validate_inode_block()', add an extra check whether an inode
+with inline data (i.e.  self-contained) has no clusters, thus preventing
+an invalid inode from being passed to 'ocfs2_evict_inode()' and below.
+
+Link: https://lkml.kernel.org/r/20251023141650.417129-1-dmantipov@yandex.ru
+Signed-off-by: Dmitry Antipov <dmantipov@yandex.ru>
+Reported-by: syzbot+c16daba279a1161acfb0@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=c16daba279a1161acfb0
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Joseph Qi <jiangqi903@gmail.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 7bc5da4842be ("ocfs2: fix out-of-bounds write in ocfs2_write_end_inline")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/inode.c |    8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -1416,6 +1416,14 @@ int ocfs2_validate_inode_block(struct su
+               goto bail;
+       }
++      if ((le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) &&
++          le32_to_cpu(di->i_clusters)) {
++              rc = ocfs2_error(sb, "Invalid dinode %llu: %u clusters\n",
++                               (unsigned long long)bh->b_blocknr,
++                               le32_to_cpu(di->i_clusters));
++              goto bail;
++      }
++
+       rc = 0;
+ bail:
diff --git a/queue-5.15/ocfs2-fix-out-of-bounds-write-in-ocfs2_write_end_inline.patch b/queue-5.15/ocfs2-fix-out-of-bounds-write-in-ocfs2_write_end_inline.patch
new file mode 100644 (file)
index 0000000..1366ca6
--- /dev/null
@@ -0,0 +1,77 @@
+From stable+bounces-236158-greg=kroah.com@vger.kernel.org Mon Apr 13 17:50:34 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 11:50:25 -0400
+Subject: ocfs2: fix out-of-bounds write in ocfs2_write_end_inline
+To: stable@vger.kernel.org
+Cc: Joseph Qi <joseph.qi@linux.alibaba.com>, syzbot+62c1793956716ea8b28a@syzkaller.appspotmail.com, Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>, Junxiao Bi <junxiao.bi@oracle.com>, Changwei Ge <gechangwei@live.cn>, Jun Piao <piaojun@huawei.com>, Heming Zhao <heming.zhao@suse.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413155025.3145781-3-sashal@kernel.org>
+
+From: Joseph Qi <joseph.qi@linux.alibaba.com>
+
+[ Upstream commit 7bc5da4842bed3252d26e742213741a4d0ac1b14 ]
+
+KASAN reports a use-after-free write of 4086 bytes in
+ocfs2_write_end_inline, called from ocfs2_write_end_nolock during a
+copy_file_range splice fallback on a corrupted ocfs2 filesystem mounted on
+a loop device.  The actual bug is an out-of-bounds write past the inode
+block buffer, not a true use-after-free.  The write overflows into an
+adjacent freed page, which KASAN reports as UAF.
+
+The root cause is that ocfs2_try_to_write_inline_data trusts the on-disk
+id_count field to determine whether a write fits in inline data.  On a
+corrupted filesystem, id_count can exceed the physical maximum inline data
+capacity, causing writes to overflow the inode block buffer.
+
+Call trace (crash path):
+
+   vfs_copy_file_range (fs/read_write.c:1634)
+     do_splice_direct
+       splice_direct_to_actor
+         iter_file_splice_write
+           ocfs2_file_write_iter
+             generic_perform_write
+               ocfs2_write_end
+                 ocfs2_write_end_nolock (fs/ocfs2/aops.c:1949)
+                   ocfs2_write_end_inline (fs/ocfs2/aops.c:1915)
+                     memcpy_from_folio     <-- KASAN: write OOB
+
+So add id_count upper bound check in ocfs2_validate_inode_block() to
+alongside the existing i_size check to fix it.
+
+Link: https://lkml.kernel.org/r/20260403063830.3662739-1-joseph.qi@linux.alibaba.com
+Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Reported-by: syzbot+62c1793956716ea8b28a@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=62c1793956716ea8b28a
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/inode.c |   10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -1427,6 +1427,16 @@ int ocfs2_validate_inode_block(struct su
+                       goto bail;
+               }
++              if (le16_to_cpu(data->id_count) >
++                  ocfs2_max_inline_data_with_xattr(sb, di)) {
++                      rc = ocfs2_error(sb,
++                                       "Invalid dinode #%llu: inline data id_count %u exceeds max %d\n",
++                                       (unsigned long long)bh->b_blocknr,
++                                       le16_to_cpu(data->id_count),
++                                       ocfs2_max_inline_data_with_xattr(sb, di));
++                      goto bail;
++              }
++
+               if (le64_to_cpu(di->i_size) > le16_to_cpu(data->id_count)) {
+                       rc = ocfs2_error(sb,
+                                        "Invalid dinode #%llu: inline data i_size %llu exceeds id_count %u\n",
diff --git a/queue-5.15/ocfs2-fix-possible-deadlock-between-unlink-and-dio_end_io_write.patch b/queue-5.15/ocfs2-fix-possible-deadlock-between-unlink-and-dio_end_io_write.patch
new file mode 100644 (file)
index 0000000..1daf36e
--- /dev/null
@@ -0,0 +1,86 @@
+From stable+bounces-239240-greg=kroah.com@vger.kernel.org Mon Apr 20 17:35:05 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 20 Apr 2026 10:41:58 -0400
+Subject: ocfs2: fix possible deadlock between unlink and dio_end_io_write
+To: stable@vger.kernel.org
+Cc: Joseph Qi <joseph.qi@linux.alibaba.com>, syzbot+67b90111784a3eac8c04@syzkaller.appspotmail.com, Heming Zhao <heming.zhao@suse.com>, Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>, Junxiao Bi <junxiao.bi@oracle.com>, Joseph Qi <jiangqi903@gmail.com>, Changwei Ge <gechangwei@live.cn>, Jun Piao <piaojun@huawei.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260420144158.1143438-2-sashal@kernel.org>
+
+From: Joseph Qi <joseph.qi@linux.alibaba.com>
+
+[ Upstream commit b02da26a992db0c0e2559acbda0fc48d4a2fd337 ]
+
+ocfs2_unlink takes orphan dir inode_lock first and then ip_alloc_sem,
+while in ocfs2_dio_end_io_write, it acquires these locks in reverse order.
+This creates an ABBA lock ordering violation on lock classes
+ocfs2_sysfile_lock_key[ORPHAN_DIR_SYSTEM_INODE] and
+ocfs2_file_ip_alloc_sem_key.
+
+Lock Chain #0 (orphan dir inode_lock -> ip_alloc_sem):
+ocfs2_unlink
+  ocfs2_prepare_orphan_dir
+    ocfs2_lookup_lock_orphan_dir
+      inode_lock(orphan_dir_inode) <- lock A
+    __ocfs2_prepare_orphan_dir
+      ocfs2_prepare_dir_for_insert
+        ocfs2_extend_dir
+         ocfs2_expand_inline_dir
+           down_write(&oi->ip_alloc_sem) <- Lock B
+
+Lock Chain #1 (ip_alloc_sem -> orphan dir inode_lock):
+ocfs2_dio_end_io_write
+  down_write(&oi->ip_alloc_sem) <- Lock B
+  ocfs2_del_inode_from_orphan()
+    inode_lock(orphan_dir_inode) <- Lock A
+
+Deadlock Scenario:
+  CPU0 (unlink)                     CPU1 (dio_end_io_write)
+  ------                            ------
+  inode_lock(orphan_dir_inode)
+                                    down_write(ip_alloc_sem)
+  down_write(ip_alloc_sem)
+                                    inode_lock(orphan_dir_inode)
+
+Since ip_alloc_sem is to protect allocation changes, which is unrelated
+with operations in ocfs2_del_inode_from_orphan.  So move
+ocfs2_del_inode_from_orphan out of ip_alloc_sem to fix the deadlock.
+
+Link: https://lkml.kernel.org/r/20260306032211.1016452-1-joseph.qi@linux.alibaba.com
+Reported-by: syzbot+67b90111784a3eac8c04@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=67b90111784a3eac8c04
+Fixes: a86a72a4a4e0 ("ocfs2: take ip_alloc_sem in ocfs2_dio_get_block & ocfs2_dio_end_io_write")
+Signed-off-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Reviewed-by: Heming Zhao <heming.zhao@suse.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Joseph Qi <jiangqi903@gmail.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: <stable@vger.kernel.org>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/aops.c |    3 +--
+ 1 file changed, 1 insertion(+), 2 deletions(-)
+
+--- a/fs/ocfs2/aops.c
++++ b/fs/ocfs2/aops.c
+@@ -2322,8 +2322,6 @@ static int ocfs2_dio_end_io_write(struct
+               goto out;
+       }
+-      down_write(&oi->ip_alloc_sem);
+-
+       /* Delete orphan before acquire i_rwsem. */
+       if (dwc->dw_orphaned) {
+               BUG_ON(dwc->dw_writer_pid != task_pid_nr(current));
+@@ -2336,6 +2334,7 @@ static int ocfs2_dio_end_io_write(struct
+                       mlog_errno(ret);
+       }
++      down_write(&oi->ip_alloc_sem);
+       di = (struct ocfs2_dinode *)di_bh->b_data;
+       ocfs2_init_dinode_extent_tree(&et, INODE_CACHE(inode), di_bh);
diff --git a/queue-5.15/ocfs2-validate-inline-data-i_size-during-inode-read.patch b/queue-5.15/ocfs2-validate-inline-data-i_size-during-inode-read.patch
new file mode 100644 (file)
index 0000000..57133eb
--- /dev/null
@@ -0,0 +1,88 @@
+From stable+bounces-236157-greg=kroah.com@vger.kernel.org Mon Apr 13 17:50:32 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 11:50:24 -0400
+Subject: ocfs2: validate inline data i_size during inode read
+To: stable@vger.kernel.org
+Cc: Deepanshu Kartikey <kartikey406@gmail.com>, syzbot+c897823f699449cc3eb4@syzkaller.appspotmail.com, Joseph Qi <joseph.qi@linux.alibaba.com>, Mark Fasheh <mark@fasheh.com>, Joel Becker <jlbec@evilplan.org>, Junxiao Bi <junxiao.bi@oracle.com>, Changwei Ge <gechangwei@live.cn>, Jun Piao <piaojun@huawei.com>, Heming Zhao <heming.zhao@suse.com>, Andrew Morton <akpm@linux-foundation.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413155025.3145781-2-sashal@kernel.org>
+
+From: Deepanshu Kartikey <kartikey406@gmail.com>
+
+[ Upstream commit 1524af3685b35feac76662cc551cbc37bd14775f ]
+
+When reading an inode from disk, ocfs2_validate_inode_block() performs
+various sanity checks but does not validate the size of inline data.  If
+the filesystem is corrupted, an inode's i_size can exceed the actual
+inline data capacity (id_count).
+
+This causes ocfs2_dir_foreach_blk_id() to iterate beyond the inline data
+buffer, triggering a use-after-free when accessing directory entries from
+freed memory.
+
+In the syzbot report:
+  - i_size was 1099511627576 bytes (~1TB)
+  - Actual inline data capacity (id_count) is typically <256 bytes
+  - A garbage rec_len (54648) caused ctx->pos to jump out of bounds
+  - This triggered a UAF in ocfs2_check_dir_entry()
+
+Fix by adding a validation check in ocfs2_validate_inode_block() to ensure
+inodes with inline data have i_size <= id_count.  This catches the
+corruption early during inode read and prevents all downstream code from
+operating on invalid data.
+
+Link: https://lkml.kernel.org/r/20251212052132.16750-1-kartikey406@gmail.com
+Signed-off-by: Deepanshu Kartikey <kartikey406@gmail.com>
+Reported-by: syzbot+c897823f699449cc3eb4@syzkaller.appspotmail.com
+Closes: https://syzkaller.appspot.com/bug?extid=c897823f699449cc3eb4
+Tested-by: syzbot+c897823f699449cc3eb4@syzkaller.appspotmail.com
+Link: https://lore.kernel.org/all/20251211115231.3560028-1-kartikey406@gmail.com/T/ [v1]
+Link: https://lore.kernel.org/all/20251212040400.6377-1-kartikey406@gmail.com/T/ [v2]
+Reviewed-by: Joseph Qi <joseph.qi@linux.alibaba.com>
+Cc: Mark Fasheh <mark@fasheh.com>
+Cc: Joel Becker <jlbec@evilplan.org>
+Cc: Junxiao Bi <junxiao.bi@oracle.com>
+Cc: Changwei Ge <gechangwei@live.cn>
+Cc: Jun Piao <piaojun@huawei.com>
+Cc: Heming Zhao <heming.zhao@suse.com>
+Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
+Stable-dep-of: 7bc5da4842be ("ocfs2: fix out-of-bounds write in ocfs2_write_end_inline")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ fs/ocfs2/inode.c |   25 +++++++++++++++++++------
+ 1 file changed, 19 insertions(+), 6 deletions(-)
+
+--- a/fs/ocfs2/inode.c
++++ b/fs/ocfs2/inode.c
+@@ -1416,12 +1416,25 @@ int ocfs2_validate_inode_block(struct su
+               goto bail;
+       }
+-      if ((le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) &&
+-          le32_to_cpu(di->i_clusters)) {
+-              rc = ocfs2_error(sb, "Invalid dinode %llu: %u clusters\n",
+-                               (unsigned long long)bh->b_blocknr,
+-                               le32_to_cpu(di->i_clusters));
+-              goto bail;
++      if (le16_to_cpu(di->i_dyn_features) & OCFS2_INLINE_DATA_FL) {
++              struct ocfs2_inline_data *data = &di->id2.i_data;
++
++              if (le32_to_cpu(di->i_clusters)) {
++                      rc = ocfs2_error(sb,
++                                       "Invalid dinode %llu: %u clusters\n",
++                                       (unsigned long long)bh->b_blocknr,
++                                       le32_to_cpu(di->i_clusters));
++                      goto bail;
++              }
++
++              if (le64_to_cpu(di->i_size) > le16_to_cpu(data->id_count)) {
++                      rc = ocfs2_error(sb,
++                                       "Invalid dinode #%llu: inline data i_size %llu exceeds id_count %u\n",
++                                       (unsigned long long)bh->b_blocknr,
++                                       (unsigned long long)le64_to_cpu(di->i_size),
++                                       le16_to_cpu(data->id_count));
++                      goto bail;
++              }
+       }
+       rc = 0;
diff --git a/queue-5.15/powerpc64-bpf-do-not-increment-tailcall-count-when-prog-is-null.patch b/queue-5.15/powerpc64-bpf-do-not-increment-tailcall-count-when-prog-is-null.patch
new file mode 100644 (file)
index 0000000..a207dfc
--- /dev/null
@@ -0,0 +1,74 @@
+From 521bd39d9d28ce54cbfec7f9b89c94ad4fdb8350 Mon Sep 17 00:00:00 2001
+From: Hari Bathini <hbathini@linux.ibm.com>
+Date: Tue, 3 Mar 2026 23:40:25 +0530
+Subject: powerpc64/bpf: do not increment tailcall count when prog is NULL
+
+From: Hari Bathini <hbathini@linux.ibm.com>
+
+commit 521bd39d9d28ce54cbfec7f9b89c94ad4fdb8350 upstream.
+
+Do not increment tailcall count, if tailcall did not succeed due to
+missing BPF program.
+
+Fixes: ce0761419fae ("powerpc/bpf: Implement support for tail calls")
+Cc: stable@vger.kernel.org
+Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
+Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
+Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
+Link: https://patch.msgid.link/20260303181031.390073-2-hbathini@linux.ibm.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ Conflicts due to missing clean up commits
+    b10cb163c4b3 ("powerpc64/bpf elfv2: Setup kernel TOC in r2 on entry")
+    49c3af43e65f ("powerpc/bpf:   Simplify bpf_to_ppc() and adopt it for powerpc64")
+    036d559c0bde ("powerpc/bpf: Use _Rn macros for GPRs")
+  and missing feature commit 2ed2d8f6fb38 ("powerpc64/bpf: Support
+  tailcalls with subprogs") resolved accordingly. ]
+Signed-off-by: Hari Bathini <hbathini@linux.ibm.com>
+---
+ arch/powerpc/net/bpf_jit_comp64.c |   20 +++++++++++---------
+ 1 file changed, 11 insertions(+), 9 deletions(-)
+
+--- a/arch/powerpc/net/bpf_jit_comp64.c
++++ b/arch/powerpc/net/bpf_jit_comp64.c
+@@ -239,30 +239,32 @@ static int bpf_jit_emit_tail_call(u32 *i
+        * tail_call_cnt++;
+        */
+       EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], 1));
+-      PPC_BPF_STL(b2p[TMP_REG_1], 1, bpf_jit_stack_tailcallcnt(ctx));
+       /* prog = array->ptrs[index]; */
+-      EMIT(PPC_RAW_MULI(b2p[TMP_REG_1], b2p_index, 8));
+-      EMIT(PPC_RAW_ADD(b2p[TMP_REG_1], b2p[TMP_REG_1], b2p_bpf_array));
+-      PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_1], offsetof(struct bpf_array, ptrs));
++      EMIT(PPC_RAW_MULI(b2p[TMP_REG_2], b2p_index, 8));
++      EMIT(PPC_RAW_ADD(b2p[TMP_REG_2], b2p[TMP_REG_2], b2p_bpf_array));
++      PPC_BPF_LL(b2p[TMP_REG_2], b2p[TMP_REG_2], offsetof(struct bpf_array, ptrs));
+       /*
+        * if (prog == NULL)
+        *   goto out;
+        */
+-      EMIT(PPC_RAW_CMPLDI(b2p[TMP_REG_1], 0));
++      EMIT(PPC_RAW_CMPLDI(b2p[TMP_REG_2], 0));
+       PPC_BCC(COND_EQ, out);
+       /* goto *(prog->bpf_func + prologue_size); */
+-      PPC_BPF_LL(b2p[TMP_REG_1], b2p[TMP_REG_1], offsetof(struct bpf_prog, bpf_func));
++      PPC_BPF_LL(b2p[TMP_REG_2], b2p[TMP_REG_2], offsetof(struct bpf_prog, bpf_func));
+ #ifdef PPC64_ELF_ABI_v1
+       /* skip past the function descriptor */
+-      EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1],
++      EMIT(PPC_RAW_ADDI(b2p[TMP_REG_2], b2p[TMP_REG_2],
+                       FUNCTION_DESCR_SIZE + BPF_TAILCALL_PROLOGUE_SIZE));
+ #else
+-      EMIT(PPC_RAW_ADDI(b2p[TMP_REG_1], b2p[TMP_REG_1], BPF_TAILCALL_PROLOGUE_SIZE));
++      EMIT(PPC_RAW_ADDI(b2p[TMP_REG_2], b2p[TMP_REG_2], BPF_TAILCALL_PROLOGUE_SIZE));
+ #endif
+-      EMIT(PPC_RAW_MTCTR(b2p[TMP_REG_1]));
++      EMIT(PPC_RAW_MTCTR(b2p[TMP_REG_2]));
++
++      /* Writeback updated tailcall count */
++      PPC_BPF_STL(b2p[TMP_REG_1], 1, bpf_jit_stack_tailcallcnt(ctx));
+       /* tear down stack, restore NVRs, ... */
+       bpf_jit_emit_common_epilogue(image, ctx);
diff --git a/queue-5.15/revert-arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch b/queue-5.15/revert-arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch
new file mode 100644 (file)
index 0000000..b6e8c05
--- /dev/null
@@ -0,0 +1,97 @@
+From stable+bounces-236110-greg=kroah.com@vger.kernel.org Mon Apr 13 16:22:55 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 10:20:56 -0400
+Subject: Revert "arm64: dts: imx8mq-librem5: Set the DVS voltages lower"
+To: stable@vger.kernel.org
+Cc: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>, Frank Li <Frank.Li@nxp.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413142057.2909222-3-sashal@kernel.org>
+
+From: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+
+[ Upstream commit 4cd46ea0eb4504f7f4fea92cb4601c5c9a3e545e ]
+
+This reverts commit c24a9b698fb02cd0723fa8375abab07f94b97b10.
+
+It's been found that there's a significant per-unit variance in accepted
+supply voltages and the current set still makes some units unstable.
+
+Revert back to nominal values.
+
+Cc: stable@vger.kernel.org
+Fixes: c24a9b698fb0 ("arm64: dts: imx8mq-librem5: Set the DVS voltages lower")
+Signed-off-by: Sebastian Krzyszkowiak <sebastian.krzyszkowiak@puri.sm>
+Signed-off-by: Frank Li <Frank.Li@nxp.com>
+Stable-dep-of: 511f76bf1dce ("arm64: dts: imx8mq-librem5: Bump BUCK1 suspend voltage up to 0.85V")
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts |    2 -
+ arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi   |   22 +++++---------------
+ 2 files changed, 7 insertions(+), 17 deletions(-)
+
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5-r3.dts
+@@ -12,7 +12,7 @@
+ &a53_opp_table {
+       opp-1000000000 {
+-              opp-microvolt = <950000>;
++              opp-microvolt = <1000000>;
+       };
+ };
+--- a/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
++++ b/arch/arm64/boot/dts/freescale/imx8mq-librem5.dtsi
+@@ -704,8 +704,8 @@
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               regulator-ramp-delay = <1250>;
+-                              rohm,dvs-run-voltage = <880000>;
+-                              rohm,dvs-idle-voltage = <820000>;
++                              rohm,dvs-run-voltage = <900000>;
++                              rohm,dvs-idle-voltage = <850000>;
+                               rohm,dvs-suspend-voltage = <810000>;
+                               regulator-always-on;
+                       };
+@@ -716,8 +716,8 @@
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+                               regulator-ramp-delay = <1250>;
+-                              rohm,dvs-run-voltage = <950000>;
+-                              rohm,dvs-idle-voltage = <850000>;
++                              rohm,dvs-run-voltage = <1000000>;
++                              rohm,dvs-idle-voltage = <900000>;
+                               regulator-always-on;
+                       };
+@@ -726,14 +726,14 @@
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+                               regulator-boot-on;
+-                              rohm,dvs-run-voltage = <850000>;
++                              rohm,dvs-run-voltage = <900000>;
+                       };
+                       buck4_reg: BUCK4 {
+                               regulator-name = "buck4";
+                               regulator-min-microvolt = <700000>;
+                               regulator-max-microvolt = <1300000>;
+-                              rohm,dvs-run-voltage = <930000>;
++                              rohm,dvs-run-voltage = <1000000>;
+                       };
+                       buck5_reg: BUCK5 {
+@@ -1214,13 +1214,3 @@
+       fsl,ext-reset-output;
+       status = "okay";
+ };
+-
+-&a53_opp_table {
+-      opp-1000000000 {
+-              opp-microvolt = <850000>;
+-      };
+-
+-      opp-1500000000 {
+-              opp-microvolt = <950000>;
+-      };
+-};
diff --git a/queue-5.15/rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch b/queue-5.15/rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch
new file mode 100644 (file)
index 0000000..9e5c158
--- /dev/null
@@ -0,0 +1,93 @@
+From stable+bounces-237697-greg=kroah.com@vger.kernel.org Tue Apr 14 03:35:37 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 21:35:02 -0400
+Subject: rxrpc: Fix call removal to use RCU safe deletion
+To: stable@vger.kernel.org
+Cc: David Howells <dhowells@redhat.com>, Marc Dionne <marc.dionne@auristor.com>, Jeffrey Altman <jaltman@auristor.com>, Linus Torvalds <torvalds@linux-foundation.org>, Simon Horman <horms@kernel.org>, linux-afs@lists.infradead.org, stable@kernel.org, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260414013502.3857050-1-sashal@kernel.org>
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit 146d4ab94cf129ee06cd467cb5c71368a6b5bad6 ]
+
+Fix rxrpc call removal from the rxnet->calls list to use list_del_rcu()
+rather than list_del_init() to prevent stuffing up reading
+/proc/net/rxrpc/calls from potentially getting into an infinite loop.
+
+This, however, means that list_empty() no longer works on an entry that's
+been deleted from the list, making it harder to detect prior deletion.  Fix
+this by:
+
+Firstly, make rxrpc_destroy_all_calls() only dump the first ten calls that
+are unexpectedly still on the list.  Limiting the number of steps means
+there's no need to call cond_resched() or to remove calls from the list
+here, thereby eliminating the need for rxrpc_put_call() to check for that.
+
+rxrpc_put_call() can then be fixed to unconditionally delete the call from
+the list as it is the only place that the deletion occurs.
+
+Fixes: 2baec2c3f854 ("rxrpc: Support network namespacing")
+Closes: https://sashiko.dev/#/patchset/20260319150150.4189381-1-dhowells%40redhat.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Jeffrey Altman <jaltman@auristor.com>
+cc: Linus Torvalds <torvalds@linux-foundation.org>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-5-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ adapted to older API ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/call_object.c |   22 ++++++++--------------
+ 1 file changed, 8 insertions(+), 14 deletions(-)
+
+--- a/net/rxrpc/call_object.c
++++ b/net/rxrpc/call_object.c
+@@ -634,11 +634,9 @@ void rxrpc_put_call(struct rxrpc_call *c
+               _debug("call %d dead", call->debug_id);
+               ASSERTCMP(call->state, ==, RXRPC_CALL_COMPLETE);
+-              if (!list_empty(&call->link)) {
+-                      spin_lock_bh(&rxnet->call_lock);
+-                      list_del_init(&call->link);
+-                      spin_unlock_bh(&rxnet->call_lock);
+-              }
++              spin_lock_bh(&rxnet->call_lock);
++              list_del_rcu(&call->link);
++              spin_unlock_bh(&rxnet->call_lock);
+               rxrpc_cleanup_call(call);
+       }
+@@ -709,24 +707,20 @@ void rxrpc_destroy_all_calls(struct rxrp
+       _enter("");
+       if (!list_empty(&rxnet->calls)) {
+-              spin_lock_bh(&rxnet->call_lock);
++              int shown = 0;
+-              while (!list_empty(&rxnet->calls)) {
+-                      call = list_entry(rxnet->calls.next,
+-                                        struct rxrpc_call, link);
+-                      _debug("Zapping call %p", call);
++              spin_lock_bh(&rxnet->call_lock);
++              list_for_each_entry(call, &rxnet->calls, link) {
+                       rxrpc_see_call(call);
+-                      list_del_init(&call->link);
+                       pr_err("Call %p still in use (%d,%s,%lx,%lx)!\n",
+                              call, refcount_read(&call->ref),
+                              rxrpc_call_states[call->state],
+                              call->flags, call->events);
+-                      spin_unlock_bh(&rxnet->call_lock);
+-                      cond_resched();
+-                      spin_lock_bh(&rxnet->call_lock);
++                      if (++shown >= 10)
++                              break;
+               }
+               spin_unlock_bh(&rxnet->call_lock);
diff --git a/queue-5.15/rxrpc-fix-key-quota-calculation-for-multitoken-keys.patch b/queue-5.15/rxrpc-fix-key-quota-calculation-for-multitoken-keys.patch
new file mode 100644 (file)
index 0000000..6f29df7
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-237683-greg=kroah.com@vger.kernel.org Tue Apr 14 02:17:46 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 20:17:39 -0400
+Subject: rxrpc: Fix key quota calculation for multitoken keys
+To: stable@vger.kernel.org
+Cc: David Howells <dhowells@redhat.com>, Marc Dionne <marc.dionne@auristor.com>, Jeffrey Altman <jaltman@auristor.com>, Simon Horman <horms@kernel.org>, linux-afs@lists.infradead.org, stable@kernel.org, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260414001739.3796841-1-sashal@kernel.org>
+
+From: David Howells <dhowells@redhat.com>
+
+[ Upstream commit bdbfead6d38979475df0c2f4bad2b19394fe9bdc ]
+
+In the rxrpc key preparsing, every token extracted sets the proposed quota
+value, but for multitoken keys, this will overwrite the previous proposed
+quota, losing it.
+
+Fix this by adding to the proposed quota instead.
+
+Fixes: 8a7a3eb4ddbe ("KEYS: RxRPC: Use key preparsing")
+Closes: https://sashiko.dev/#/patchset/20260319150150.4189381-1-dhowells%40redhat.com
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Jeffrey Altman <jaltman@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-2-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ dropped hunk for rxrpc_preparse_xdr_yfs_rxgk() ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/key.c |    5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+--- a/net/rxrpc/key.c
++++ b/net/rxrpc/key.c
+@@ -72,7 +72,7 @@ static int rxrpc_preparse_xdr_rxkad(stru
+               return -EKEYREJECTED;
+       plen = sizeof(*token) + sizeof(*token->kad) + tktlen;
+-      prep->quotalen = datalen + plen;
++      prep->quotalen += datalen + plen;
+       plen -= sizeof(*token);
+       token = kzalloc(sizeof(*token), GFP_KERNEL);
+@@ -303,6 +303,7 @@ static int rxrpc_preparse(struct key_pre
+       memcpy(&kver, prep->data, sizeof(kver));
+       prep->data += sizeof(kver);
+       prep->datalen -= sizeof(kver);
++      prep->quotalen = 0;
+       _debug("KEY I/F VERSION: %u", kver);
+@@ -340,7 +341,7 @@ static int rxrpc_preparse(struct key_pre
+               goto error;
+       plen = sizeof(*token->kad) + v1->ticket_length;
+-      prep->quotalen = plen + sizeof(*token);
++      prep->quotalen += plen + sizeof(*token);
+       ret = -ENOMEM;
+       token = kzalloc(sizeof(*token), GFP_KERNEL);
diff --git a/queue-5.15/rxrpc-reject-undecryptable-rxkad-response-tickets.patch b/queue-5.15/rxrpc-reject-undecryptable-rxkad-response-tickets.patch
new file mode 100644 (file)
index 0000000..3ed98bf
--- /dev/null
@@ -0,0 +1,63 @@
+From stable+bounces-237840-greg=kroah.com@vger.kernel.org Tue Apr 14 14:04:30 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Tue, 14 Apr 2026 07:56:10 -0400
+Subject: rxrpc: reject undecryptable rxkad response tickets
+To: stable@vger.kernel.org
+Cc: Yuqi Xu <xuyuqiabc@gmail.com>, Yifan Wu <yifanwucs@gmail.com>, Juefei Pu <tomapufckgml@gmail.com>, Yuan Tan <yuantan098@gmail.com>, Xin Liu <bird@lzu.edu.cn>, Ren Wei <enjou1224z@gmail.com>, Ren Wei <n05ec@lzu.edu.cn>, David Howells <dhowells@redhat.com>, Marc Dionne <marc.dionne@auristor.com>, Simon Horman <horms@kernel.org>, linux-afs@lists.infradead.org, stable@kernel.org, Jakub Kicinski <kuba@kernel.org>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260414115610.548230-1-sashal@kernel.org>
+
+From: Yuqi Xu <xuyuqiabc@gmail.com>
+
+[ Upstream commit fe4447cd95623b1cfacc15f280aab73a6d7340b2 ]
+
+rxkad_decrypt_ticket() decrypts the RXKAD response ticket and then
+parses the buffer as plaintext without checking whether
+crypto_skcipher_decrypt() succeeded.
+
+A malformed RESPONSE can therefore use a non-block-aligned ticket
+length, make the decrypt operation fail, and still drive the ticket
+parser with attacker-controlled bytes.
+
+Check the decrypt result and abort the connection with RXKADBADTICKET
+when ticket decryption fails.
+
+Fixes: 17926a79320a ("[AF_RXRPC]: Provide secure RxRPC sockets for use by userspace and kernel both")
+Reported-by: Yifan Wu <yifanwucs@gmail.com>
+Reported-by: Juefei Pu <tomapufckgml@gmail.com>
+Co-developed-by: Yuan Tan <yuantan098@gmail.com>
+Signed-off-by: Yuan Tan <yuantan098@gmail.com>
+Suggested-by: Xin Liu <bird@lzu.edu.cn>
+Tested-by: Ren Wei <enjou1224z@gmail.com>
+Signed-off-by: Yuqi Xu <xuyuqiabc@gmail.com>
+Signed-off-by: Ren Wei <n05ec@lzu.edu.cn>
+Signed-off-by: David Howells <dhowells@redhat.com>
+cc: Marc Dionne <marc.dionne@auristor.com>
+cc: Simon Horman <horms@kernel.org>
+cc: linux-afs@lists.infradead.org
+cc: stable@kernel.org
+Link: https://patch.msgid.link/20260408121252.2249051-12-dhowells@redhat.com
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+[ adapted `rxrpc_abort_conn()` call to existing `goto other_error` error-handling pattern ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/rxrpc/rxkad.c |    7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+--- a/net/rxrpc/rxkad.c
++++ b/net/rxrpc/rxkad.c
+@@ -1013,8 +1013,13 @@ static int rxkad_decrypt_ticket(struct r
+       sg_init_one(&sg[0], ticket, ticket_len);
+       skcipher_request_set_callback(req, 0, NULL, NULL);
+       skcipher_request_set_crypt(req, sg, sg, ticket_len, iv.x);
+-      crypto_skcipher_decrypt(req);
++      ret = crypto_skcipher_decrypt(req);
+       skcipher_request_free(req);
++      if (ret < 0) {
++              abort_code = RXKADBADTICKET;
++              ret = -EPROTO;
++              goto other_error;
++      }
+       p = ticket;
+       end = p + ticket_len;
index 0fee0122cfdd2469e9cb985eae72c2b733acf2e5..5959c2a4c240df8d6a592aaedc8d1d4f4b626309 100644 (file)
@@ -97,3 +97,23 @@ gfs2-improve-gfs2_consist_inode-usage.patch
 gfs2-validate-i_depth-for-exhash-directories.patch
 wifi-mac80211-always-free-skb-on-ieee80211_tx_prepar.patch
 pci-acpi-restrict-program_hpx_type2-to-aer-bits.patch
+netfilter-nft_set_pipapo-do-not-rely-on-zero_size_ptr.patch
+powerpc64-bpf-do-not-increment-tailcall-count-when-prog-is-null.patch
+arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch
+arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-to-0.81v.patch
+revert-arm64-dts-imx8mq-librem5-set-the-dvs-voltages-lower.patch
+arm64-dts-imx8mq-librem5-bump-buck1-suspend-voltage-up-to-0.85v.patch
+ocfs2-add-inline-inode-consistency-check-to-ocfs2_validate_inode_block.patch
+ocfs2-validate-inline-data-i_size-during-inode-read.patch
+ocfs2-fix-out-of-bounds-write-in-ocfs2_write_end_inline.patch
+xfrm-clear-trailing-padding-in-build_polexpire.patch
+rxrpc-fix-key-quota-calculation-for-multitoken-keys.patch
+rxrpc-fix-call-removal-to-use-rcu-safe-deletion.patch
+rxrpc-reject-undecryptable-rxkad-response-tickets.patch
+fs-ocfs2-fix-comments-mentioning-i_mutex.patch
+ocfs2-fix-possible-deadlock-between-unlink-and-dio_end_io_write.patch
+mm-blk-cgroup-fix-use-after-free-in-cgwb_release_workfn.patch
+mptcp-fix-lock-class-name-family-in-pm_nl_create_listen_socket.patch
+xen-netfront-handle-null-returned-by-xdp_convert_buff_to_frame.patch
+tty-n_gsm-fix-deadlock-and-link-starvation-in-outgoing-data-path.patch
+netdevsim-fix-memory-leak-of-nsim_dev-fa_cookie.patch
diff --git a/queue-5.15/tty-n_gsm-fix-deadlock-and-link-starvation-in-outgoing-data-path.patch b/queue-5.15/tty-n_gsm-fix-deadlock-and-link-starvation-in-outgoing-data-path.patch
new file mode 100644 (file)
index 0000000..f4f2105
--- /dev/null
@@ -0,0 +1,714 @@
+From stable+bounces-230427-greg=kroah.com@vger.kernel.org Thu Mar 26 07:52:10 2026
+From: Johnny Hao <johnny_haocn@sina.com>
+Date: Thu, 26 Mar 2026 14:51:39 +0800
+Subject: tty: n_gsm: fix deadlock and link starvation in outgoing data path
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, Daniel Starke <daniel.starke@siemens.com>, Johnny Hao <johnny_haocn@sina.com>
+Message-ID: <20260326065139.1735715-1-johnny_haocn@sina.com>
+
+From: Daniel Starke <daniel.starke@siemens.com>
+
+[ Upstream commit 0af021678d5d30c31f5a6b631f404ead3575212a ]
+
+The current implementation queues up new control and user packets as needed
+and processes this queue down to the ldisc in the same code path.
+That means that the upper and the lower layer are hard coupled in the code.
+Due to this deadlocks can happen as seen below while transmitting data,
+especially during ldisc congestion. Furthermore, the data channels starve
+the control channel on high transmission load on the ldisc.
+
+Introduce an additional control channel data queue to prevent timeouts and
+link hangups during ldisc congestion. This is being processed before the
+user channel data queue in gsm_data_kick(), i.e. with the highest priority.
+Put the queue to ldisc data path into a workqueue and trigger it whenever
+new data has been put into the transmission queue. Change
+gsm_dlci_data_sweep() accordingly to fill up the transmission queue until
+TX_THRESH_HI. This solves the locking issue, keeps latency low and provides
+good performance on high data load.
+Note that now all packets from a DLCI are removed from the internal queue
+if the associated DLCI was closed. This ensures that no data is sent by the
+introduced write task to an already closed DLCI.
+
+BUG: spinlock recursion on CPU#0, test_v24_loop/124
+ lock: serial8250_ports+0x3a8/0x7500, .magic: dead4ead, .owner: test_v24_loop/124, .owner_cpu: 0
+CPU: 0 PID: 124 Comm: test_v24_loop Tainted: G           O      5.18.0-rc2 #3
+Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.15.0-1 04/01/2014
+Call Trace:
+ <IRQ>
+ dump_stack_lvl+0x34/0x44
+ do_raw_spin_lock+0x76/0xa0
+ _raw_spin_lock_irqsave+0x72/0x80
+ uart_write_room+0x3b/0xc0
+ gsm_data_kick+0x14b/0x240 [n_gsm]
+ gsmld_write_wakeup+0x35/0x70 [n_gsm]
+ tty_wakeup+0x53/0x60
+ tty_port_default_wakeup+0x1b/0x30
+ serial8250_tx_chars+0x12f/0x220
+ serial8250_handle_irq.part.0+0xfe/0x150
+ serial8250_default_handle_irq+0x48/0x80
+ serial8250_interrupt+0x56/0xa0
+ __handle_irq_event_percpu+0x78/0x1f0
+ handle_irq_event+0x34/0x70
+ handle_fasteoi_irq+0x90/0x1e0
+ __common_interrupt+0x69/0x100
+ common_interrupt+0x48/0xc0
+ asm_common_interrupt+0x1e/0x40
+RIP: 0010:__do_softirq+0x83/0x34e
+Code: 2a 0a ff 0f b7 ed c7 44 24 10 0a 00 00 00 48 c7 c7 51 2a 64 82 e8 2d
+e2 d5 ff 65 66 c7 05 83 af 1e 7e 00 00 fb b8 ff ff ff ff <49> c7 c2 40 61
+80 82 0f bc c5 41 89 c4 41 83 c4 01 0f 84 e6 00 00
+RSP: 0018:ffffc90000003f98 EFLAGS: 00000286
+RAX: 00000000ffffffff RBX: 0000000000000000 RCX: 0000000000000000
+RDX: 0000000000000000 RSI: ffffffff82642a51 RDI: ffffffff825bb5e7
+RBP: 0000000000000200 R08: 00000008de3271a8 R09: 0000000000000000
+R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000030 R14: 0000000000000000 R15: 0000000000000000
+ ? __do_softirq+0x73/0x34e
+ irq_exit_rcu+0xb5/0x100
+ common_interrupt+0xa4/0xc0
+ </IRQ>
+ <TASK>
+ asm_common_interrupt+0x1e/0x40
+RIP: 0010:_raw_spin_unlock_irqrestore+0x2e/0x50
+Code: 00 55 48 89 fd 48 83 c7 18 53 48 89 f3 48 8b 74 24 10 e8 85 28 36 ff
+48 89 ef e8 cd 58 36 ff 80 e7 02 74 01 fb bf 01 00 00 00 <e8> 3d 97 33 ff
+65 8b 05 96 23 2b 7e 85 c0 74 03 5b 5d c3 0f 1f 44
+RSP: 0018:ffffc9000020fd08 EFLAGS: 00000202
+RAX: 0000000000000000 RBX: 0000000000000246 RCX: 0000000000000000
+RDX: 0000000000000004 RSI: ffffffff8257fd74 RDI: 0000000000000001
+RBP: ffff8880057de3a0 R08: 00000008de233000 R09: 0000000000000000
+R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000
+R13: 0000000000000100 R14: 0000000000000202 R15: ffff8880057df0b8
+ ? _raw_spin_unlock_irqrestore+0x23/0x50
+ gsmtty_write+0x65/0x80 [n_gsm]
+ n_tty_write+0x33f/0x530
+ ? swake_up_all+0xe0/0xe0
+ file_tty_write.constprop.0+0x1b1/0x320
+ ? n_tty_flush_buffer+0xb0/0xb0
+ new_sync_write+0x10c/0x190
+ vfs_write+0x282/0x310
+ ksys_write+0x68/0xe0
+ do_syscall_64+0x3b/0x90
+ entry_SYSCALL_64_after_hwframe+0x44/0xae
+RIP: 0033:0x7f3e5e35c15c
+Code: 8b 7c 24 08 89 c5 e8 c5 ff ff ff 89 ef 89 44 24 08 e8 58 bc 02 00 8b
+44 24 08 48 83 c4 10 5d c3 48 63 ff b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff
+ff 76 10 48 8b 15 fd fc 05 00 f7 d8 64 89 02 48 83
+RSP: 002b:00007ffcee77cd18 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
+RAX: ffffffffffffffda RBX: 00007ffcee77cd70 RCX: 00007f3e5e35c15c
+RDX: 0000000000000100 RSI: 00007ffcee77cd90 RDI: 0000000000000003
+RBP: 0000000000000100 R08: 0000000000000000 R09: 7efefefefefefeff
+R10: 00007f3e5e3bddeb R11: 0000000000000246 R12: 00007ffcee77ce8f
+R13: 0000000000000001 R14: 000056214404e010 R15: 00007ffcee77cd90
+ </TASK>
+
+Fixes: e1eaea46bb40 ("tty: n_gsm line discipline")
+Signed-off-by: Daniel Starke <daniel.starke@siemens.com>
+Link: https://lore.kernel.org/r/20220701122332.2039-1-daniel.starke@siemens.com
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+[ The context change is due to the commit a8c5b8255f8a
+("tty: n_gsm: fix broken virtual tty handling") in v5.18
+which is irrelevant to the logic of this patch. ]
+Signed-off-by: Johnny Hao <johnny_haocn@sina.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/tty/n_gsm.c |  403 ++++++++++++++++++++++++++++++++++++----------------
+ 1 file changed, 279 insertions(+), 124 deletions(-)
+
+--- a/drivers/tty/n_gsm.c
++++ b/drivers/tty/n_gsm.c
+@@ -5,6 +5,14 @@
+  *
+  *    * THIS IS A DEVELOPMENT SNAPSHOT IT IS NOT A FINAL RELEASE *
+  *
++ * Outgoing path:
++ * tty -> DLCI fifo -> scheduler -> GSM MUX data queue    ---o-> ldisc
++ * control message               -> GSM MUX control queue --´
++ *
++ * Incoming path:
++ * ldisc -> gsm_queue() -o--> tty
++ *                        `-> gsm_control_response()
++ *
+  * TO DO:
+  *    Mostly done:    ioctls for setting modes/timing
+  *    Partly done:    hooks so you can pull off frames to non tty devs
+@@ -212,6 +220,9 @@ struct gsm_mux {
+       /* Events on the GSM channel */
+       wait_queue_head_t event;
++      /* ldisc send work */
++      struct work_struct tx_work;
++
+       /* Bits for GSM mode decoding */
+       /* Framing Layer */
+@@ -243,7 +254,8 @@ struct gsm_mux {
+       unsigned int tx_bytes;          /* TX data outstanding */
+ #define TX_THRESH_HI          8192
+ #define TX_THRESH_LO          2048
+-      struct list_head tx_list;       /* Pending data packets */
++      struct list_head tx_ctrl_list;  /* Pending control packets */
++      struct list_head tx_data_list;  /* Pending data packets */
+       /* Control messages */
+       struct timer_list kick_timer;   /* Kick TX queuing on timeout */
+@@ -377,6 +389,11 @@ static const u8 gsm_fcs8[256] = {
+ static int gsmld_output(struct gsm_mux *gsm, u8 *data, int len);
+ static int gsm_modem_update(struct gsm_dlci *dlci, u8 brk);
++static struct gsm_msg *gsm_data_alloc(struct gsm_mux *gsm, u8 addr, int len,
++                                                              u8 ctrl);
++static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg);
++static void gsmld_write_trigger(struct gsm_mux *gsm);
++static void gsmld_write_task(struct work_struct *work);
+ /**
+  *    gsm_fcs_add     -       update FCS
+@@ -661,53 +678,73 @@ static int gsm_stuff_frame(const u8 *inp
+  *    @cr: command/response bit seen as initiator
+  *    @control:  control byte including PF bit
+  *
+- *    Format up and transmit a control frame. These do not go via the
+- *    queueing logic as they should be transmitted ahead of data when
+- *    they are needed.
+- *
+- *    FIXME: Lock versus data TX path
++ *    Format up and transmit a control frame. These should be transmitted
++ *    ahead of data when they are needed.
+  */
+-
+-static void gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
++static int gsm_send(struct gsm_mux *gsm, int addr, int cr, int control)
+ {
+-      int len;
+-      u8 cbuf[10];
+-      u8 ibuf[3];
++      struct gsm_msg *msg;
++      u8 *dp;
+       int ocr;
++      unsigned long flags;
++
++      msg = gsm_data_alloc(gsm, addr, 0, control);
++      if (!msg)
++              return -ENOMEM;
+       /* toggle C/R coding if not initiator */
+       ocr = cr ^ (gsm->initiator ? 0 : 1);
+-      switch (gsm->encoding) {
+-      case 0:
+-              cbuf[0] = GSM0_SOF;
+-              cbuf[1] = (addr << 2) | (ocr << 1) | EA;
+-              cbuf[2] = control;
+-              cbuf[3] = EA;   /* Length of data = 0 */
+-              cbuf[4] = 0xFF - gsm_fcs_add_block(INIT_FCS, cbuf + 1, 3);
+-              cbuf[5] = GSM0_SOF;
+-              len = 6;
+-              break;
+-      case 1:
+-      case 2:
+-              /* Control frame + packing (but not frame stuffing) in mode 1 */
+-              ibuf[0] = (addr << 2) | (ocr << 1) | EA;
+-              ibuf[1] = control;
+-              ibuf[2] = 0xFF - gsm_fcs_add_block(INIT_FCS, ibuf, 2);
+-              /* Stuffing may double the size worst case */
+-              len = gsm_stuff_frame(ibuf, cbuf + 1, 3);
+-              /* Now add the SOF markers */
+-              cbuf[0] = GSM1_SOF;
+-              cbuf[len + 1] = GSM1_SOF;
+-              /* FIXME: we can omit the lead one in many cases */
+-              len += 2;
+-              break;
+-      default:
+-              WARN_ON(1);
+-              return;
++      msg->data -= 3;
++      dp = msg->data;
++      *dp++ = (addr << 2) | (ocr << 1) | EA;
++      *dp++ = control;
++
++      if (gsm->encoding == 0)
++              *dp++ = EA; /* Length of data = 0 */
++
++      *dp = 0xFF - gsm_fcs_add_block(INIT_FCS, msg->data, dp - msg->data);
++      msg->len = (dp - msg->data) + 1;
++
++      gsm_print_packet("Q->", addr, cr, control, NULL, 0);
++
++      spin_lock_irqsave(&gsm->tx_lock, flags);
++      list_add_tail(&msg->list, &gsm->tx_ctrl_list);
++      gsm->tx_bytes += msg->len;
++      spin_unlock_irqrestore(&gsm->tx_lock, flags);
++      gsmld_write_trigger(gsm);
++
++      return 0;
++}
++
++/**
++ *    gsm_dlci_clear_queues   -       remove outstanding data for a DLCI
++ *    @gsm: mux
++ *    @dlci: clear for this DLCI
++ *
++ *    Clears the data queues for a given DLCI.
++ */
++static void gsm_dlci_clear_queues(struct gsm_mux *gsm, struct gsm_dlci *dlci)
++{
++      struct gsm_msg *msg, *nmsg;
++      int addr = dlci->addr;
++      unsigned long flags;
++
++      /* Clear DLCI write fifo first */
++      spin_lock_irqsave(&dlci->lock, flags);
++      kfifo_reset(&dlci->fifo);
++      spin_unlock_irqrestore(&dlci->lock, flags);
++
++      /* Clear data packets in MUX write queue */
++      spin_lock_irqsave(&gsm->tx_lock, flags);
++      list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) {
++              if (msg->addr != addr)
++                      continue;
++              gsm->tx_bytes -= msg->len;
++              list_del(&msg->list);
++              kfree(msg);
+       }
+-      gsmld_output(gsm, cbuf, len);
+-      gsm_print_packet("-->", addr, cr, control, NULL, 0);
++      spin_unlock_irqrestore(&gsm->tx_lock, flags);
+ }
+ /**
+@@ -770,6 +807,45 @@ static struct gsm_msg *gsm_data_alloc(st
+ }
+ /**
++ *    gsm_send_packet -       sends a single packet
++ *    @gsm: GSM Mux
++ *    @msg: packet to send
++ *
++ *    The given packet is encoded and sent out. No memory is freed.
++ *    The caller must hold the gsm tx lock.
++ */
++static int gsm_send_packet(struct gsm_mux *gsm, struct gsm_msg *msg)
++{
++      int len, ret;
++
++
++      if (gsm->encoding == 0) {
++              gsm->txframe[0] = GSM0_SOF;
++              memcpy(gsm->txframe + 1, msg->data, msg->len);
++              gsm->txframe[msg->len + 1] = GSM0_SOF;
++              len = msg->len + 2;
++      } else {
++              gsm->txframe[0] = GSM1_SOF;
++              len = gsm_stuff_frame(msg->data, gsm->txframe + 1, msg->len);
++              gsm->txframe[len + 1] = GSM1_SOF;
++              len += 2;
++      }
++
++      if (debug & 4)
++              gsm_hex_dump_bytes(__func__, gsm->txframe, len);
++      gsm_print_packet("-->", msg->addr, gsm->initiator, msg->ctrl, msg->data,
++                       msg->len);
++
++      ret = gsmld_output(gsm, gsm->txframe, len);
++      if (ret <= 0)
++              return ret;
++      /* FIXME: Can eliminate one SOF in many more cases */
++      gsm->tx_bytes -= msg->len;
++
++      return 0;
++}
++
++/**
+  *    gsm_is_flow_ctrl_msg    -       checks if flow control message
+  *    @msg: message to check
+  *
+@@ -801,59 +877,81 @@ static bool gsm_is_flow_ctrl_msg(struct
+ }
+ /**
+- *    gsm_data_kick           -       poke the queue
++ *    gsm_data_kick   -       poke the queue
+  *    @gsm: GSM Mux
+- *    @dlci: DLCI sending the data
+  *
+  *    The tty device has called us to indicate that room has appeared in
+- *    the transmit queue. Ram more data into the pipe if we have any
++ *    the transmit queue. Ram more data into the pipe if we have any.
+  *    If we have been flow-stopped by a CMD_FCOFF, then we can only
+- *    send messages on DLCI0 until CMD_FCON
+- *
+- *    FIXME: lock against link layer control transmissions
++ *    send messages on DLCI0 until CMD_FCON. The caller must hold
++ *    the gsm tx lock.
+  */
+-
+-static void gsm_data_kick(struct gsm_mux *gsm, struct gsm_dlci *dlci)
++static int gsm_data_kick(struct gsm_mux *gsm)
+ {
+       struct gsm_msg *msg, *nmsg;
+-      int len;
++      struct gsm_dlci *dlci;
++      int ret;
+-      list_for_each_entry_safe(msg, nmsg, &gsm->tx_list, list) {
++      clear_bit(TTY_DO_WRITE_WAKEUP, &gsm->tty->flags);
++
++      /* Serialize control messages and control channel messages first */
++      list_for_each_entry_safe(msg, nmsg, &gsm->tx_ctrl_list, list) {
+               if (gsm->constipated && !gsm_is_flow_ctrl_msg(msg))
++                      return -EAGAIN;
++              ret = gsm_send_packet(gsm, msg);
++              switch (ret) {
++              case -ENOSPC:
++                      return -ENOSPC;
++              case -ENODEV:
++                      /* ldisc not open */
++                      gsm->tx_bytes -= msg->len;
++                      list_del(&msg->list);
++                      kfree(msg);
+                       continue;
+-              if (gsm->encoding != 0) {
+-                      gsm->txframe[0] = GSM1_SOF;
+-                      len = gsm_stuff_frame(msg->data,
+-                                              gsm->txframe + 1, msg->len);
+-                      gsm->txframe[len + 1] = GSM1_SOF;
+-                      len += 2;
+-              } else {
+-                      gsm->txframe[0] = GSM0_SOF;
+-                      memcpy(gsm->txframe + 1 , msg->data, msg->len);
+-                      gsm->txframe[msg->len + 1] = GSM0_SOF;
+-                      len = msg->len + 2;
+-              }
+-
+-              if (debug & 4)
+-                      gsm_hex_dump_bytes(__func__, gsm->txframe, len);
+-              if (gsmld_output(gsm, gsm->txframe, len) <= 0)
++              default:
++                      if (ret >= 0) {
++                              list_del(&msg->list);
++                              kfree(msg);
++                      }
+                       break;
+-              /* FIXME: Can eliminate one SOF in many more cases */
+-              gsm->tx_bytes -= msg->len;
+-
+-              list_del(&msg->list);
+-              kfree(msg);
++              }
++      }
+-              if (dlci) {
+-                      tty_port_tty_wakeup(&dlci->port);
+-              } else {
+-                      int i = 0;
++      if (gsm->constipated)
++              return -EAGAIN;
+-                      for (i = 0; i < NUM_DLCI; i++)
+-                              if (gsm->dlci[i])
+-                                      tty_port_tty_wakeup(&gsm->dlci[i]->port);
++      /* Serialize other channels */
++      if (list_empty(&gsm->tx_data_list))
++              return 0;
++      list_for_each_entry_safe(msg, nmsg, &gsm->tx_data_list, list) {
++              dlci = gsm->dlci[msg->addr];
++              /* Send only messages for DLCIs with valid state */
++              if (dlci->state != DLCI_OPEN) {
++                      gsm->tx_bytes -= msg->len;
++                      list_del(&msg->list);
++                      kfree(msg);
++                      continue;
++              }
++              ret = gsm_send_packet(gsm, msg);
++              switch (ret) {
++              case -ENOSPC:
++                      return -ENOSPC;
++              case -ENODEV:
++                      /* ldisc not open */
++                      gsm->tx_bytes -= msg->len;
++                      list_del(&msg->list);
++                      kfree(msg);
++                      continue;
++              default:
++                      if (ret >= 0) {
++                              list_del(&msg->list);
++                              kfree(msg);
++                      }
++                      break;
+               }
+       }
++
++      return 1;
+ }
+ /**
+@@ -902,9 +1000,21 @@ static void __gsm_data_queue(struct gsm_
+       msg->data = dp;
+       /* Add to the actual output queue */
+-      list_add_tail(&msg->list, &gsm->tx_list);
++      switch (msg->ctrl & ~PF) {
++      case UI:
++      case UIH:
++              if (msg->addr > 0) {
++                      list_add_tail(&msg->list, &gsm->tx_data_list);
++                      break;
++              }
++              fallthrough;
++      default:
++              list_add_tail(&msg->list, &gsm->tx_ctrl_list);
++              break;
++      }
+       gsm->tx_bytes += msg->len;
+-      gsm_data_kick(gsm, dlci);
++
++      gsmld_write_trigger(gsm);
+       mod_timer(&gsm->kick_timer, jiffies + 10 * gsm->t1 * HZ / 100);
+ }
+@@ -1131,32 +1241,39 @@ static int gsm_dlci_modem_output(struct
+ static int gsm_dlci_data_sweep(struct gsm_mux *gsm)
+ {
+-      int len, ret = 0;
+       /* Priority ordering: We should do priority with RR of the groups */
+-      int i = 1;
+-
+-      while (i < NUM_DLCI) {
+-              struct gsm_dlci *dlci;
++      int i, len, ret = 0;
++      bool sent;
++      struct gsm_dlci *dlci;
+-              if (gsm->tx_bytes > TX_THRESH_HI)
+-                      break;
+-              dlci = gsm->dlci[i];
+-              if (dlci == NULL || dlci->constipated) {
+-                      i++;
+-                      continue;
++      while (gsm->tx_bytes < TX_THRESH_HI) {
++              for (sent = false, i = 1; i < NUM_DLCI; i++) {
++                      dlci = gsm->dlci[i];
++                      /* skip unused or blocked channel */
++                      if (!dlci || dlci->constipated)
++                              continue;
++                      /* skip channels with invalid state */
++                      if (dlci->state != DLCI_OPEN)
++                              continue;
++                      /* count the sent data per adaption */
++                      if (dlci->adaption < 3 && !dlci->net)
++                              len = gsm_dlci_data_output(gsm, dlci);
++                      else
++                              len = gsm_dlci_data_output_framed(gsm, dlci);
++                      /* on error exit */
++                      if (len < 0)
++                              return ret;
++                      if (len > 0) {
++                              ret++;
++                              sent = true;
++                              /* The lower DLCs can starve the higher DLCs! */
++                              break;
++                      }
++                      /* try next */
+               }
+-              if (dlci->adaption < 3 && !dlci->net)
+-                      len = gsm_dlci_data_output(gsm, dlci);
+-              else
+-                      len = gsm_dlci_data_output_framed(gsm, dlci);
+-              if (len < 0)
++              if (!sent)
+                       break;
+-              /* DLCI empty - try the next */
+-              if (len == 0)
+-                      i++;
+-              else
+-                      ret++;
+-      }
++      };
+       return ret;
+ }
+@@ -1405,7 +1522,6 @@ static void gsm_control_message(struct g
+                                               const u8 *data, int clen)
+ {
+       u8 buf[1];
+-      unsigned long flags;
+       struct gsm_dlci *dlci;
+       int i;
+       int address;
+@@ -1440,9 +1556,7 @@ static void gsm_control_message(struct g
+               gsm->constipated = false;
+               gsm_control_reply(gsm, CMD_FCON, NULL, 0);
+               /* Kick the link in case it is idling */
+-              spin_lock_irqsave(&gsm->tx_lock, flags);
+-              gsm_data_kick(gsm, NULL);
+-              spin_unlock_irqrestore(&gsm->tx_lock, flags);
++              gsmld_write_trigger(gsm);
+               break;
+       case CMD_FCOFF:
+               /* Modem wants us to STFU */
+@@ -1645,8 +1759,6 @@ static int gsm_control_wait(struct gsm_m
+ static void gsm_dlci_close(struct gsm_dlci *dlci)
+ {
+-      unsigned long flags;
+-
+       del_timer(&dlci->t1);
+       if (debug & 8)
+               pr_debug("DLCI %d goes closed.\n", dlci->addr);
+@@ -1655,17 +1767,16 @@ static void gsm_dlci_close(struct gsm_dl
+       dlci->constipated = true;
+       if (dlci->addr != 0) {
+               tty_port_tty_hangup(&dlci->port, false);
+-              spin_lock_irqsave(&dlci->lock, flags);
+-              kfifo_reset(&dlci->fifo);
+-              spin_unlock_irqrestore(&dlci->lock, flags);
++              gsm_dlci_clear_queues(dlci->gsm, dlci);
+               /* Ensure that gsmtty_open() can return. */
+               tty_port_set_initialized(&dlci->port, 0);
+               wake_up_interruptible(&dlci->port.open_wait);
+       } else
+               dlci->gsm->dead = true;
+-      wake_up(&dlci->gsm->event);
+       /* A DLCI 0 close is a MUX termination so we need to kick that
+          back to userspace somehow */
++      gsm_dlci_data_kick(dlci);
++      wake_up(&dlci->gsm->event);
+ }
+ /**
+@@ -1688,6 +1799,7 @@ static void gsm_dlci_open(struct gsm_dlc
+       /* Send current modem state */
+       if (dlci->addr)
+               gsm_modem_update(dlci, 0);
++      gsm_dlci_data_kick(dlci);
+       wake_up(&dlci->gsm->event);
+ }
+@@ -2325,7 +2437,7 @@ static void gsm1_receive(struct gsm_mux
+       } else if ((c & ISO_IEC_646_MASK) == XOFF) {
+               gsm->constipated = false;
+               /* Kick the link in case it is idling */
+-              gsm_data_kick(gsm, NULL);
++              gsmld_write_trigger(gsm);
+               return;
+       }
+       if (c == GSM1_SOF) {
+@@ -2460,6 +2572,9 @@ static void gsm_cleanup_mux(struct gsm_m
+       del_timer_sync(&gsm->kick_timer);
+       del_timer_sync(&gsm->t2_timer);
++      /* Finish writing to ldisc */
++      flush_work(&gsm->tx_work);
++
+       /* Free up any link layer users and finally the control channel */
+       if (gsm->has_devices) {
+               gsm_unregister_devices(gsm_tty_driver, gsm->num);
+@@ -2471,9 +2586,12 @@ static void gsm_cleanup_mux(struct gsm_m
+       mutex_unlock(&gsm->mutex);
+       /* Now wipe the queues */
+       tty_ldisc_flush(gsm->tty);
+-      list_for_each_entry_safe(txq, ntxq, &gsm->tx_list, list)
++      list_for_each_entry_safe(txq, ntxq, &gsm->tx_ctrl_list, list)
++              kfree(txq);
++      INIT_LIST_HEAD(&gsm->tx_ctrl_list);
++      list_for_each_entry_safe(txq, ntxq, &gsm->tx_data_list, list)
+               kfree(txq);
+-      INIT_LIST_HEAD(&gsm->tx_list);
++      INIT_LIST_HEAD(&gsm->tx_data_list);
+ }
+ /**
+@@ -2496,6 +2614,7 @@ static int gsm_activate_mux(struct gsm_m
+       timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+       timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
++      INIT_WORK(&gsm->tx_work, gsmld_write_task);
+       init_waitqueue_head(&gsm->event);
+       spin_lock_init(&gsm->control_lock);
+       spin_lock_init(&gsm->tx_lock);
+@@ -2602,7 +2721,8 @@ static struct gsm_mux *gsm_alloc_mux(voi
+       spin_lock_init(&gsm->lock);
+       mutex_init(&gsm->mutex);
+       kref_init(&gsm->ref);
+-      INIT_LIST_HEAD(&gsm->tx_list);
++      INIT_LIST_HEAD(&gsm->tx_ctrl_list);
++      INIT_LIST_HEAD(&gsm->tx_data_list);
+       gsm->t1 = T1;
+       gsm->t2 = T2;
+@@ -2759,6 +2879,47 @@ static int gsmld_output(struct gsm_mux *
+       return gsm->tty->ops->write(gsm->tty, data, len);
+ }
++
++/**
++ *    gsmld_write_trigger     -       schedule ldisc write task
++ *    @gsm: our mux
++ */
++static void gsmld_write_trigger(struct gsm_mux *gsm)
++{
++      if (!gsm || !gsm->dlci[0] || gsm->dlci[0]->dead)
++              return;
++      schedule_work(&gsm->tx_work);
++}
++
++
++/**
++ *    gsmld_write_task        -       ldisc write task
++ *    @work: our tx write work
++ *
++ *    Writes out data to the ldisc if possible. We are doing this here to
++ *    avoid dead-locking. This returns if no space or data is left for output.
++ */
++static void gsmld_write_task(struct work_struct *work)
++{
++      struct gsm_mux *gsm = container_of(work, struct gsm_mux, tx_work);
++      unsigned long flags;
++      int i, ret;
++
++      /* All outstanding control channel and control messages and one data
++       * frame is sent.
++       */
++      ret = -ENODEV;
++      spin_lock_irqsave(&gsm->tx_lock, flags);
++      if (gsm->tty)
++              ret = gsm_data_kick(gsm);
++      spin_unlock_irqrestore(&gsm->tx_lock, flags);
++
++      if (ret >= 0)
++              for (i = 0; i < NUM_DLCI; i++)
++                      if (gsm->dlci[i])
++                              tty_port_tty_wakeup(&gsm->dlci[i]->port);
++}
++
+ /**
+  *    gsmld_attach_gsm        -       mode set up
+  *    @tty: our tty structure
+@@ -2902,6 +3063,7 @@ static int gsmld_open(struct tty_struct
+       timer_setup(&gsm->kick_timer, gsm_kick_timer, 0);
+       timer_setup(&gsm->t2_timer, gsm_control_retransmit, 0);
++      INIT_WORK(&gsm->tx_work, gsmld_write_task);
+       return 0;
+ }
+@@ -2918,16 +3080,9 @@ static int gsmld_open(struct tty_struct
+ static void gsmld_write_wakeup(struct tty_struct *tty)
+ {
+       struct gsm_mux *gsm = tty->disc_data;
+-      unsigned long flags;
+       /* Queue poll */
+-      clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
+-      spin_lock_irqsave(&gsm->tx_lock, flags);
+-      gsm_data_kick(gsm, NULL);
+-      if (gsm->tx_bytes < TX_THRESH_LO) {
+-              gsm_dlci_data_sweep(gsm);
+-      }
+-      spin_unlock_irqrestore(&gsm->tx_lock, flags);
++      gsmld_write_trigger(gsm);
+ }
+ /**
diff --git a/queue-5.15/xen-netfront-handle-null-returned-by-xdp_convert_buff_to_frame.patch b/queue-5.15/xen-netfront-handle-null-returned-by-xdp_convert_buff_to_frame.patch
new file mode 100644 (file)
index 0000000..2470860
--- /dev/null
@@ -0,0 +1,69 @@
+From johnny_haocn@sina.com Fri Mar 27 06:59:57 2026
+From: Johnny Hao <johnny_haocn@sina.com>
+Date: Fri, 27 Mar 2026 13:59:50 +0800
+Subject: xen-netfront: handle NULL returned by xdp_convert_buff_to_frame()
+To: gregkh@linuxfoundation.org, stable@vger.kernel.org
+Cc: linux-kernel@vger.kernel.org, Alexey Nepomnyashih <sdl@nppct.ru>, Jakub Kicinski <kuba@kernel.org>, Johnny Hao <johnny_haocn@sina.com>
+Message-ID: <20260327055950.2618928-1-johnny_haocn@sina.com>
+
+From: Alexey Nepomnyashih <sdl@nppct.ru>
+
+[ Upstream commit cc3628dcd851ddd8d418bf0c897024b4621ddc92 ]
+
+The function xdp_convert_buff_to_frame() may return NULL if it fails
+to correctly convert the XDP buffer into an XDP frame due to memory
+constraints, internal errors, or invalid data. Failing to check for NULL
+may lead to a NULL pointer dereference if the result is used later in
+processing, potentially causing crashes, data corruption, or undefined
+behavior.
+
+On XDP redirect failure, the associated page must be released explicitly
+if it was previously retained via get_page(). Failing to do so may result
+in a memory leak, as the pages reference count is not decremented.
+
+Cc: stable@vger.kernel.org # v5.9+
+Fixes: 6c5aa6fc4def ("xen networking: add basic XDP support for xen-netfront")
+Signed-off-by: Alexey Nepomnyashih <sdl@nppct.ru>
+Link: https://patch.msgid.link/20250417122118.1009824-1-sdl@nppct.ru
+Signed-off-by: Jakub Kicinski <kuba@kernel.org>
+Signed-off-by: Johnny Hao <johnny_haocn@sina.com>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ drivers/net/xen-netfront.c |   17 ++++++++++++-----
+ 1 file changed, 12 insertions(+), 5 deletions(-)
+
+--- a/drivers/net/xen-netfront.c
++++ b/drivers/net/xen-netfront.c
+@@ -982,20 +982,27 @@ static u32 xennet_run_xdp(struct netfron
+       act = bpf_prog_run_xdp(prog, xdp);
+       switch (act) {
+       case XDP_TX:
+-              get_page(pdata);
+               xdpf = xdp_convert_buff_to_frame(xdp);
++              if (unlikely(!xdpf)) {
++                      trace_xdp_exception(queue->info->netdev, prog, act);
++                      break;
++              }
++              get_page(pdata);
+               err = xennet_xdp_xmit(queue->info->netdev, 1, &xdpf, 0);
+-              if (unlikely(!err))
++              if (unlikely(err <= 0)) {
++                      if (err < 0)
++                              trace_xdp_exception(queue->info->netdev, prog, act);
+                       xdp_return_frame_rx_napi(xdpf);
+-              else if (unlikely(err < 0))
+-                      trace_xdp_exception(queue->info->netdev, prog, act);
++              }
+               break;
+       case XDP_REDIRECT:
+               get_page(pdata);
+               err = xdp_do_redirect(queue->info->netdev, xdp, prog);
+               *need_xdp_flush = true;
+-              if (unlikely(err))
++              if (unlikely(err)) {
+                       trace_xdp_exception(queue->info->netdev, prog, act);
++                      xdp_return_buff(xdp);
++              }
+               break;
+       case XDP_PASS:
+       case XDP_DROP:
diff --git a/queue-5.15/xfrm-clear-trailing-padding-in-build_polexpire.patch b/queue-5.15/xfrm-clear-trailing-padding-in-build_polexpire.patch
new file mode 100644 (file)
index 0000000..ea7037c
--- /dev/null
@@ -0,0 +1,48 @@
+From stable+bounces-237666-greg=kroah.com@vger.kernel.org Mon Apr 13 23:59:54 2026
+From: Sasha Levin <sashal@kernel.org>
+Date: Mon, 13 Apr 2026 17:59:48 -0400
+Subject: xfrm: clear trailing padding in build_polexpire()
+To: stable@vger.kernel.org
+Cc: Yasuaki Torimaru <yasuakitorimaru@gmail.com>, Simon Horman <horms@kernel.org>, Breno Leitao <leitao@debian.org>, Steffen Klassert <steffen.klassert@secunet.com>, Sasha Levin <sashal@kernel.org>
+Message-ID: <20260413215948.3711943-1-sashal@kernel.org>
+
+From: Yasuaki Torimaru <yasuakitorimaru@gmail.com>
+
+[ Upstream commit 71a98248c63c535eaa4d4c22f099b68d902006d0 ]
+
+build_expire() clears the trailing padding bytes of struct
+xfrm_user_expire after setting the hard field via memset_after(),
+but the analogous function build_polexpire() does not do this for
+struct xfrm_user_polexpire.
+
+The padding bytes after the __u8 hard field are left
+uninitialized from the heap allocation, and are then sent to
+userspace via netlink multicast to XFRMNLGRP_EXPIRE listeners,
+leaking kernel heap memory contents.
+
+Add the missing memset_after() call, matching build_expire().
+
+Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
+Cc: stable@vger.kernel.org
+Signed-off-by: Yasuaki Torimaru <yasuakitorimaru@gmail.com>
+Reviewed-by: Simon Horman <horms@kernel.org>
+Reviewed-by: Breno Leitao <leitao@debian.org>
+Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
+[ replaced `memset_after()` macro with equivalent manual `memset()` call ]
+Signed-off-by: Sasha Levin <sashal@kernel.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+---
+ net/xfrm/xfrm_user.c |    2 ++
+ 1 file changed, 2 insertions(+)
+
+--- a/net/xfrm/xfrm_user.c
++++ b/net/xfrm/xfrm_user.c
+@@ -3389,6 +3389,8 @@ static int build_polexpire(struct sk_buf
+               return err;
+       }
+       upe->hard = !!hard;
++      /* clear the padding bytes */
++      memset(&upe->hard + 1, 0, sizeof(*upe) - offsetofend(typeof(*upe), hard));
+       nlmsg_end(skb, nlh);
+       return 0;