From: Greg Kroah-Hartman Date: Fri, 1 May 2026 12:34:51 +0000 (+0200) Subject: 6.18-stable patches X-Git-Tag: v6.12.86~43 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2cc37db9e7e15e95b1e90204cbdc808e2e5cd6bf;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-stable patches added patches: arm64-dts-marvell-udpu-add-ethernet-aliases.patch drm-arcpgu-fix-device-node-leak.patch extract-cert-wrap-key_pass-with-ifdef-use_pkcs11_engine.patch fs-prepare-for-adding-lsm-blob-to-backing_file.patch hwmon-isl28022-fix-integer-overflow-in-power-calculation-on-32-bit.patch ipv4-icmp-validate-reply-type-before-using-icmp_pointers.patch libceph-prevent-potential-null-ptr-deref-in-ceph_handle_auth_reply.patch loongarch-show-cpu-vulnerabilites-correctly.patch net-bridge-use-a-stable-fdb-dst-snapshot-in-rcu-readers.patch net-ks8851-avoid-excess-softirq-scheduling.patch net-ks8851-reinstate-disabling-of-bhs-around-irq-handler.patch net-mctp-fix-don-t-require-received-header-reserved-bits-to-be-zero.patch net-qrtr-ns-free-the-node-during-ctrl_cmd_bye.patch net-rds-fix-mr-cleanup-on-copy-error.patch net-smc-avoid-early-lgr-access-in-smc_clc_wait_msg.patch net-txgbe-fix-firmware-version-check.patch netconsole-avoid-out-of-bounds-access-on-empty-string-in-trim_newline.patch power-supply-axp288_charger-do-not-cancel-work-before-initializing-it.patch rdma-rxe-validate-pad-and-icrc-before-payload_size-in-rxe_rcv.patch slub-fix-data-loss-and-overflow-in-krealloc.patch spi-fix-resource-leaks-on-device-setup-failure.patch tpm-avoid-wunused-but-set-variable.patch tracing-fprobe-reject-registration-of-a-registered-fprobe-before-init.patch --- diff --git a/queue-6.18/arm64-dts-marvell-udpu-add-ethernet-aliases.patch b/queue-6.18/arm64-dts-marvell-udpu-add-ethernet-aliases.patch new file mode 100644 index 0000000000..e2bd95efd7 --- /dev/null +++ b/queue-6.18/arm64-dts-marvell-udpu-add-ethernet-aliases.patch @@ -0,0 +1,39 @@ +From 38f09c97340cd23f976242e6cb1e7aa4c8ed28d0 Mon Sep 17 00:00:00 2001 +From: Robert Marko +Date: Tue, 27 Jan 2026 13:32:15 +0100 +Subject: arm64: dts: marvell: uDPU: add ethernet aliases + +From: Robert Marko + +commit 38f09c97340cd23f976242e6cb1e7aa4c8ed28d0 upstream. + +On eDPU plus, which is an updated revision of eDPU which uses an external +MV88E6361 switch we are relying on U-Boot to detect the board, and then +enable and disable the required nodes for that revision. + +However, it seems that I missed adding the required aliases for ethernet +controllers, and this worked as in OpenWrt we had added those locally. + +Cc: stable@vger.kernel.org +Fixes: 660b8b2f3944 ("arm64: dts: marvell: eDPU: add support for version with external switch") +Signed-off-by: Robert Marko +Signed-off-by: Gregory CLEMENT +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi | 5 +++++ + 1 file changed, 5 insertions(+) + +--- a/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi ++++ b/arch/arm64/boot/dts/marvell/armada-3720-uDPU.dtsi +@@ -15,6 +15,11 @@ + #include "armada-372x.dtsi" + + / { ++ aliases { ++ ethernet0 = ð0; ++ ethernet1 = ð1; ++ }; ++ + chosen { + stdout-path = "serial0:115200n8"; + }; diff --git a/queue-6.18/drm-arcpgu-fix-device-node-leak.patch b/queue-6.18/drm-arcpgu-fix-device-node-leak.patch new file mode 100644 index 0000000000..b608e6cfe3 --- /dev/null +++ b/queue-6.18/drm-arcpgu-fix-device-node-leak.patch @@ -0,0 +1,39 @@ +From ad3ac32a3893a2bbcad545efc005a8e4e7ecf10c Mon Sep 17 00:00:00 2001 +From: Luca Ceresoli +Date: Thu, 2 Apr 2026 18:42:20 +0200 +Subject: drm/arcpgu: fix device node leak + +From: Luca Ceresoli + +commit ad3ac32a3893a2bbcad545efc005a8e4e7ecf10c upstream. + +This function gets a device_node reference via +of_graph_get_remote_port_parent() and stores it in encoder_node, but never +puts that reference. Add it. + +There used to be a of_node_put(encoder_node) but it has been removed by +mistake during a rework in commit 3ea66a794fdc ("drm/arc: Inline +arcpgu_drm_hdmi_init"). + +Fixes: 3ea66a794fdc ("drm/arc: Inline arcpgu_drm_hdmi_init") +Cc: stable@vger.kernel.org +Reviewed-by: Louis Chauvet +Link: https://patch.msgid.link/20260402-drm-arcgpu-fix-device-node-leak-v2-1-d773cf754ae5@bootlin.com +Signed-off-by: Luca Ceresoli +Signed-off-by: Greg Kroah-Hartman +--- + drivers/gpu/drm/tiny/arcpgu.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/gpu/drm/tiny/arcpgu.c ++++ b/drivers/gpu/drm/tiny/arcpgu.c +@@ -250,7 +250,8 @@ DEFINE_DRM_GEM_DMA_FOPS(arcpgu_drm_ops); + static int arcpgu_load(struct arcpgu_drm_private *arcpgu) + { + struct platform_device *pdev = to_platform_device(arcpgu->drm.dev); +- struct device_node *encoder_node = NULL, *endpoint_node = NULL; ++ struct device_node *encoder_node __free(device_node) = NULL; ++ struct device_node *endpoint_node = NULL; + struct drm_connector *connector = NULL; + struct drm_device *drm = &arcpgu->drm; + int ret; diff --git a/queue-6.18/extract-cert-wrap-key_pass-with-ifdef-use_pkcs11_engine.patch b/queue-6.18/extract-cert-wrap-key_pass-with-ifdef-use_pkcs11_engine.patch new file mode 100644 index 0000000000..33bd510c6c --- /dev/null +++ b/queue-6.18/extract-cert-wrap-key_pass-with-ifdef-use_pkcs11_engine.patch @@ -0,0 +1,61 @@ +From 4f96b7c68a9904e01049ef610d701b382dca9574 Mon Sep 17 00:00:00 2001 +From: Nathan Chancellor +Date: Wed, 25 Mar 2026 18:19:15 -0700 +Subject: extract-cert: Wrap key_pass with '#ifdef USE_PKCS11_ENGINE' + +From: Nathan Chancellor + +commit 4f96b7c68a9904e01049ef610d701b382dca9574 upstream. + +A recent strengthening of -Wunused-but-set-variable (enabled with -Wall) +in clang under a new subwarning, -Wunused-but-set-global, points out an +unused static global variable in certs/extract-cert.c: + + certs/extract-cert.c:46:20: error: variable 'key_pass' set but not used [-Werror,-Wunused-but-set-global] + 46 | static const char *key_pass; + | ^ + +After commit 558bdc45dfb2 ("sign-file,extract-cert: use pkcs11 provider +for OPENSSL MAJOR >= 3"), key_pass is only used with the OpenSSL engine +API, not the new provider API. Wrap key_pass's declaration and +assignment with '#ifdef USE_PKCS11_ENGINE' so that it is only included +with its use to clear up the warning. While this is a little uglier than +just marking key_pass with the unused attribute, this will make it +easier to clean up all code associated with the use of the engine API if +it were ever removed in the future. While in the area, use a tab for +the key_pass assignment line to match the rest of the file. + +Cc: stable@vger.kernel.org +Fixes: 558bdc45dfb2 ("sign-file,extract-cert: use pkcs11 provider for OPENSSL MAJOR >= 3") +Reviewed-by: Nick Desaulniers +Tested-by: Nick Desaulniers +Link: https://patch.msgid.link/20260325-certs-extract-cert-key_pass-unused-but-set-global-v1-1-ecf94326d532@kernel.org +Signed-off-by: Nathan Chancellor +Signed-off-by: Greg Kroah-Hartman +--- + certs/extract-cert.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/certs/extract-cert.c ++++ b/certs/extract-cert.c +@@ -43,7 +43,9 @@ void format(void) + exit(2); + } + ++#ifdef USE_PKCS11_ENGINE + static const char *key_pass; ++#endif + static BIO *wb; + static char *cert_dst; + static bool verbose; +@@ -135,7 +137,9 @@ int main(int argc, char **argv) + if (verbose_env && strchr(verbose_env, '1')) + verbose = true; + +- key_pass = getenv("KBUILD_SIGN_PIN"); ++#ifdef USE_PKCS11_ENGINE ++ key_pass = getenv("KBUILD_SIGN_PIN"); ++#endif + + if (argc != 3) + format(); diff --git a/queue-6.18/fs-prepare-for-adding-lsm-blob-to-backing_file.patch b/queue-6.18/fs-prepare-for-adding-lsm-blob-to-backing_file.patch new file mode 100644 index 0000000000..cdb13a77be --- /dev/null +++ b/queue-6.18/fs-prepare-for-adding-lsm-blob-to-backing_file.patch @@ -0,0 +1,78 @@ +From 880bd496ec72a6dcb00cb70c430ef752ba242ae7 Mon Sep 17 00:00:00 2001 +From: Amir Goldstein +Date: Mon, 30 Mar 2026 10:27:51 +0200 +Subject: fs: prepare for adding LSM blob to backing_file + +From: Amir Goldstein + +commit 880bd496ec72a6dcb00cb70c430ef752ba242ae7 upstream. + +In preparation to adding LSM blob to backing_file struct, factor out +helpers init_backing_file() and backing_file_free(). + +Cc: stable@vger.kernel.org +Cc: linux-fsdevel@vger.kernel.org +Cc: linux-unionfs@vger.kernel.org +Cc: linux-erofs@lists.ozlabs.org +Signed-off-by: Amir Goldstein +Reviewed-by: Serge Hallyn +[PM: use the term "LSM blob", fix comment style to match file] +Signed-off-by: Paul Moore +Signed-off-by: Greg Kroah-Hartman +--- + fs/file_table.c | 22 ++++++++++++++++++++-- + 1 file changed, 20 insertions(+), 2 deletions(-) + +--- a/fs/file_table.c ++++ b/fs/file_table.c +@@ -66,6 +66,12 @@ void backing_file_set_user_path(struct f + } + EXPORT_SYMBOL_GPL(backing_file_set_user_path); + ++static inline void backing_file_free(struct backing_file *ff) ++{ ++ path_put(&ff->user_path); ++ kmem_cache_free(bfilp_cachep, ff); ++} ++ + static inline void file_free(struct file *f) + { + security_file_free(f); +@@ -73,8 +79,7 @@ static inline void file_free(struct file + percpu_counter_dec(&nr_files); + put_cred(f->f_cred); + if (unlikely(f->f_mode & FMODE_BACKING)) { +- path_put(backing_file_user_path(f)); +- kmem_cache_free(bfilp_cachep, backing_file(f)); ++ backing_file_free(backing_file(f)); + } else { + kmem_cache_free(filp_cachep, f); + } +@@ -283,6 +288,12 @@ struct file *alloc_empty_file_noaccount( + return f; + } + ++static int init_backing_file(struct backing_file *ff) ++{ ++ memset(&ff->user_path, 0, sizeof(ff->user_path)); ++ return 0; ++} ++ + /* + * Variant of alloc_empty_file() that allocates a backing_file container + * and doesn't check and modify nr_files. +@@ -305,7 +316,14 @@ struct file *alloc_empty_backing_file(in + return ERR_PTR(error); + } + ++ /* The f_mode flags must be set before fput(). */ + ff->file.f_mode |= FMODE_BACKING | FMODE_NOACCOUNT; ++ error = init_backing_file(ff); ++ if (unlikely(error)) { ++ fput(&ff->file); ++ return ERR_PTR(error); ++ } ++ + return &ff->file; + } + diff --git a/queue-6.18/hwmon-isl28022-fix-integer-overflow-in-power-calculation-on-32-bit.patch b/queue-6.18/hwmon-isl28022-fix-integer-overflow-in-power-calculation-on-32-bit.patch new file mode 100644 index 0000000000..52d77ca636 --- /dev/null +++ b/queue-6.18/hwmon-isl28022-fix-integer-overflow-in-power-calculation-on-32-bit.patch @@ -0,0 +1,64 @@ +From a7c0aaa50e40ffd8fd703d006d5a04b540b9ca92 Mon Sep 17 00:00:00 2001 +From: Sanman Pradhan +Date: Fri, 10 Apr 2026 00:26:19 +0000 +Subject: hwmon: (isl28022) Fix integer overflow in power calculation on 32-bit + +From: Sanman Pradhan + +commit a7c0aaa50e40ffd8fd703d006d5a04b540b9ca92 upstream. + +isl28022_read_power() computes: + + *val = ((51200000L * ((long)data->gain)) / + (long)data->shunt) * (long)regval; + +On 32-bit platforms, 'long' is 32 bits. With gain=8 and shunt=10000 +(the default configuration): + + (51200000 * 8) / 10000 = 40960 + 40960 * 65535 = 2,684,313,600 + +This exceeds LONG_MAX (2,147,483,647), resulting in signed integer +overflow. + +Additionally, dividing before multiplying by regval loses precision +unnecessarily. + +Use u64 arithmetic with div_u64() and multiply before dividing to +retain precision. The intermediate product cannot overflow u64 +(worst case: 51200000 * 8 * 65535 = 26843136000000). Power is +inherently non-negative, so unsigned types are the natural fit. +Cap the result to LONG_MAX before returning it through the hwmon +callback. + +Fixes: 39671a14df4f2 ("hwmon: (isl28022) new driver for ISL28022 power monitor") +Cc: stable@vger.kernel.org +Signed-off-by: Sanman Pradhan +Link: https://lore.kernel.org/r/20260410002613.424557-1-sanman.pradhan@hpe.com +Signed-off-by: Guenter Roeck +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hwmon/isl28022.c | 5 +++-- + 1 file changed, 3 insertions(+), 2 deletions(-) + +--- a/drivers/hwmon/isl28022.c ++++ b/drivers/hwmon/isl28022.c +@@ -9,6 +9,7 @@ + #include + #include + #include ++#include + #include + #include + +@@ -185,8 +186,8 @@ static int isl28022_read_power(struct de + ISL28022_REG_POWER, ®val); + if (err < 0) + return err; +- *val = ((51200000L * ((long)data->gain)) / +- (long)data->shunt) * (long)regval; ++ *val = min(div_u64(51200000ULL * data->gain * regval, ++ data->shunt), LONG_MAX); + break; + default: + return -EOPNOTSUPP; diff --git a/queue-6.18/ipv4-icmp-validate-reply-type-before-using-icmp_pointers.patch b/queue-6.18/ipv4-icmp-validate-reply-type-before-using-icmp_pointers.patch new file mode 100644 index 0000000000..38b81ec3ad --- /dev/null +++ b/queue-6.18/ipv4-icmp-validate-reply-type-before-using-icmp_pointers.patch @@ -0,0 +1,54 @@ +From 67bf002a2d7387a6312138210d0bd06e3cf4879b Mon Sep 17 00:00:00 2001 +From: Ruide Cao +Date: Tue, 21 Apr 2026 12:16:31 +0800 +Subject: ipv4: icmp: validate reply type before using icmp_pointers + +From: Ruide Cao + +commit 67bf002a2d7387a6312138210d0bd06e3cf4879b upstream. + +Extended echo replies use ICMP_EXT_ECHOREPLY as the outbound reply type. +That value is outside the range covered by icmp_pointers[], which only +describes the traditional ICMP types up to NR_ICMP_TYPES. + +Avoid consulting icmp_pointers[] for reply types outside that range, and +use array_index_nospec() for the remaining in-range lookup. Normal ICMP +replies keep their existing behavior unchanged. + +Fixes: d329ea5bd884 ("icmp: add response to RFC 8335 PROBE messages") +Cc: stable@kernel.org +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Signed-off-by: Ruide Cao +Signed-off-by: Ren Wei +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/0dace90c01a5978e829ca741ef684dbd7304ce62.1776628519.git.caoruide123@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/icmp.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/net/ipv4/icmp.c ++++ b/net/ipv4/icmp.c +@@ -64,6 +64,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -362,7 +363,9 @@ static int icmp_glue_bits(void *from, ch + to, len); + + skb->csum = csum_block_add(skb->csum, csum, odd); +- if (icmp_pointers[icmp_param->data.icmph.type].error) ++ if (icmp_param->data.icmph.type <= NR_ICMP_TYPES && ++ icmp_pointers[array_index_nospec(icmp_param->data.icmph.type, ++ NR_ICMP_TYPES + 1)].error) + nf_ct_attach(skb, icmp_param->skb); + return 0; + } diff --git a/queue-6.18/libceph-prevent-potential-null-ptr-deref-in-ceph_handle_auth_reply.patch b/queue-6.18/libceph-prevent-potential-null-ptr-deref-in-ceph_handle_auth_reply.patch new file mode 100644 index 0000000000..4478ef4b51 --- /dev/null +++ b/queue-6.18/libceph-prevent-potential-null-ptr-deref-in-ceph_handle_auth_reply.patch @@ -0,0 +1,42 @@ +From 5199c125d25aeae8615c4fc31652cc0fe624338e Mon Sep 17 00:00:00 2001 +From: Raphael Zimmer +Date: Wed, 18 Mar 2026 18:09:03 +0100 +Subject: libceph: Prevent potential null-ptr-deref in ceph_handle_auth_reply() + +From: Raphael Zimmer + +commit 5199c125d25aeae8615c4fc31652cc0fe624338e upstream. + +If a message of type CEPH_MSG_AUTH_REPLY contains a zero value for both +protocol and result, this is currently not treated as an error. In case +of ac->negotiating == true and ac->protocol > 0, this leads to setting +ac->protocol = 0 and ac->ops = NULL. Thereafter, the check for +ac->protocol != protocol returns false, and init_protocol() is not +called. Subsequently, ac->ops->handle_reply() is called, which leads to +a null pointer dereference, because ac->ops is still NULL. + +This patch changes the check for ac->protocol != protocol to +!ac->protocol, as this also includes the case when the protocol was set +to zero in the message. This causes the message to be treated as +containing a bad auth protocol. + +Cc: stable@vger.kernel.org +Signed-off-by: Raphael Zimmer +Reviewed-by: Ilya Dryomov +Signed-off-by: Ilya Dryomov +Signed-off-by: Greg Kroah-Hartman +--- + net/ceph/auth.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/ceph/auth.c ++++ b/net/ceph/auth.c +@@ -245,7 +245,7 @@ int ceph_handle_auth_reply(struct ceph_a + ac->protocol = 0; + ac->ops = NULL; + } +- if (ac->protocol != protocol) { ++ if (!ac->protocol) { + ret = init_protocol(ac, protocol); + if (ret) { + pr_err("auth protocol '%s' init failed: %d\n", diff --git a/queue-6.18/loongarch-show-cpu-vulnerabilites-correctly.patch b/queue-6.18/loongarch-show-cpu-vulnerabilites-correctly.patch new file mode 100644 index 0000000000..50df0b16c6 --- /dev/null +++ b/queue-6.18/loongarch-show-cpu-vulnerabilites-correctly.patch @@ -0,0 +1,45 @@ +From 37e57e8ad96cdec4a57b55fd10bef50f7370a954 Mon Sep 17 00:00:00 2001 +From: Huacai Chen +Date: Wed, 22 Apr 2026 15:45:12 +0800 +Subject: LoongArch: Show CPU vulnerabilites correctly + +From: Huacai Chen + +commit 37e57e8ad96cdec4a57b55fd10bef50f7370a954 upstream. + +Most LoongArch processors are vulnerable to Spectre-V1 Proof-of-Concept +(PoC). And the generic mechanism, __user pointer sanitization, can be +used as a mitigation. This means to use array_index_nospec() to prevent +out of boundry access in syscall and other critical paths. + +Implement the arch-specific cpu_show_spectre_v1() to show CPU Spectre-V1 +vulnerabilites correctly. + +Cc: stable@vger.kernel.org +Link: https://cc-sw.com/chinese-loongarch-architecture-evaluation-part-3-of-3/ +Signed-off-by: Huacai Chen +Signed-off-by: Greg Kroah-Hartman +--- + arch/loongarch/kernel/cpu-probe.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +--- a/arch/loongarch/kernel/cpu-probe.c ++++ b/arch/loongarch/kernel/cpu-probe.c +@@ -7,6 +7,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -387,3 +388,9 @@ void cpu_probe(void) + + cpu_report(); + } ++ ++ssize_t cpu_show_spectre_v1(struct device *dev, ++ struct device_attribute *attr, char *buf) ++{ ++ return sysfs_emit(buf, "Mitigation: __user pointer sanitization\n"); ++} diff --git a/queue-6.18/net-bridge-use-a-stable-fdb-dst-snapshot-in-rcu-readers.patch b/queue-6.18/net-bridge-use-a-stable-fdb-dst-snapshot-in-rcu-readers.patch new file mode 100644 index 0000000000..d2922eb546 --- /dev/null +++ b/queue-6.18/net-bridge-use-a-stable-fdb-dst-snapshot-in-rcu-readers.patch @@ -0,0 +1,171 @@ +From df4601653201de21b487c3e7fffd464790cab808 Mon Sep 17 00:00:00 2001 +From: Zhengchuan Liang +Date: Mon, 13 Apr 2026 17:08:46 +0800 +Subject: net: bridge: use a stable FDB dst snapshot in RCU readers + +From: Zhengchuan Liang + +commit df4601653201de21b487c3e7fffd464790cab808 upstream. + +Local FDB entries can be rewritten in place by `fdb_delete_local()`, which +updates `f->dst` to another port or to `NULL` while keeping the entry +alive. Several bridge RCU readers inspect `f->dst`, including +`br_fdb_fillbuf()` through the `brforward_read()` sysfs path. + +These readers currently load `f->dst` multiple times and can therefore +observe inconsistent values across the check and later dereference. +In `br_fdb_fillbuf()`, this means a concurrent local-FDB update can change +`f->dst` after the NULL check and before the `port_no` dereference, +leading to a NULL-ptr-deref. + +Fix this by taking a single `READ_ONCE()` snapshot of `f->dst` in each +affected RCU reader and using that snapshot for the rest of the access +sequence. Also publish the in-place `f->dst` updates in `fdb_delete_local()` +with `WRITE_ONCE()` so the readers and writer use matching access patterns. + +Fixes: 960b589f86c7 ("bridge: Properly check if local fdb entry can be deleted in br_fdb_change_mac_address") +Cc: stable@kernel.org +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Co-developed-by: Yuan Tan +Signed-off-by: Yuan Tan +Suggested-by: Xin Liu +Tested-by: Ren Wei +Signed-off-by: Zhengchuan Liang +Signed-off-by: Ren Wei +Reviewed-by: Ido Schimmel +Acked-by: Nikolay Aleksandrov +Link: https://patch.msgid.link/6570fabb85ecadb8baaf019efe856f407711c7b9.1776043229.git.zcliangcn@gmail.com +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + net/bridge/br_arp_nd_proxy.c | 8 +++++--- + net/bridge/br_fdb.c | 28 ++++++++++++++++++---------- + 2 files changed, 23 insertions(+), 13 deletions(-) + +--- a/net/bridge/br_arp_nd_proxy.c ++++ b/net/bridge/br_arp_nd_proxy.c +@@ -202,11 +202,12 @@ void br_do_proxy_suppress_arp(struct sk_ + + f = br_fdb_find_rcu(br, n->ha, vid); + if (f) { ++ const struct net_bridge_port *dst = READ_ONCE(f->dst); + bool replied = false; + + if ((p && (p->flags & BR_PROXYARP)) || +- (f->dst && (f->dst->flags & BR_PROXYARP_WIFI)) || +- br_is_neigh_suppress_enabled(f->dst, vid)) { ++ (dst && (dst->flags & BR_PROXYARP_WIFI)) || ++ br_is_neigh_suppress_enabled(dst, vid)) { + if (!vid) + br_arp_send(br, p, skb->dev, sip, tip, + sha, n->ha, sha, 0, 0); +@@ -470,9 +471,10 @@ void br_do_suppress_nd(struct sk_buff *s + + f = br_fdb_find_rcu(br, n->ha, vid); + if (f) { ++ const struct net_bridge_port *dst = READ_ONCE(f->dst); + bool replied = false; + +- if (br_is_neigh_suppress_enabled(f->dst, vid)) { ++ if (br_is_neigh_suppress_enabled(dst, vid)) { + if (vid != 0) + br_nd_send(br, p, skb, n, + skb->vlan_proto, +--- a/net/bridge/br_fdb.c ++++ b/net/bridge/br_fdb.c +@@ -236,6 +236,7 @@ struct net_device *br_fdb_find_port(cons + const unsigned char *addr, + __u16 vid) + { ++ const struct net_bridge_port *dst; + struct net_bridge_fdb_entry *f; + struct net_device *dev = NULL; + struct net_bridge *br; +@@ -248,8 +249,11 @@ struct net_device *br_fdb_find_port(cons + br = netdev_priv(br_dev); + rcu_read_lock(); + f = br_fdb_find_rcu(br, addr, vid); +- if (f && f->dst) +- dev = f->dst->dev; ++ if (f) { ++ dst = READ_ONCE(f->dst); ++ if (dst) ++ dev = dst->dev; ++ } + rcu_read_unlock(); + + return dev; +@@ -346,7 +350,7 @@ static void fdb_delete_local(struct net_ + vg = nbp_vlan_group(op); + if (op != p && ether_addr_equal(op->dev->dev_addr, addr) && + (!vid || br_vlan_find(vg, vid))) { +- f->dst = op; ++ WRITE_ONCE(f->dst, op); + clear_bit(BR_FDB_ADDED_BY_USER, &f->flags); + return; + } +@@ -357,7 +361,7 @@ static void fdb_delete_local(struct net_ + /* Maybe bridge device has same hw addr? */ + if (p && ether_addr_equal(br->dev->dev_addr, addr) && + (!vid || (v && br_vlan_should_use(v)))) { +- f->dst = NULL; ++ WRITE_ONCE(f->dst, NULL); + clear_bit(BR_FDB_ADDED_BY_USER, &f->flags); + return; + } +@@ -928,6 +932,7 @@ int br_fdb_test_addr(struct net_device * + int br_fdb_fillbuf(struct net_bridge *br, void *buf, + unsigned long maxnum, unsigned long skip) + { ++ const struct net_bridge_port *dst; + struct net_bridge_fdb_entry *f; + struct __fdb_entry *fe = buf; + unsigned long delta; +@@ -944,7 +949,8 @@ int br_fdb_fillbuf(struct net_bridge *br + continue; + + /* ignore pseudo entry for local MAC address */ +- if (!f->dst) ++ dst = READ_ONCE(f->dst); ++ if (!dst) + continue; + + if (skip) { +@@ -956,8 +962,8 @@ int br_fdb_fillbuf(struct net_bridge *br + memcpy(fe->mac_addr, f->key.addr.addr, ETH_ALEN); + + /* due to ABI compat need to split into hi/lo */ +- fe->port_no = f->dst->port_no; +- fe->port_hi = f->dst->port_no >> 8; ++ fe->port_no = dst->port_no; ++ fe->port_hi = dst->port_no >> 8; + + fe->is_local = test_bit(BR_FDB_LOCAL, &f->flags); + if (!test_bit(BR_FDB_STATIC, &f->flags)) { +@@ -1083,9 +1089,11 @@ int br_fdb_dump(struct sk_buff *skb, + + rcu_read_lock(); + hlist_for_each_entry_rcu(f, &br->fdb_list, fdb_node) { ++ const struct net_bridge_port *dst = READ_ONCE(f->dst); ++ + if (*idx < ctx->fdb_idx) + goto skip; +- if (filter_dev && (!f->dst || f->dst->dev != filter_dev)) { ++ if (filter_dev && (!dst || dst->dev != filter_dev)) { + if (filter_dev != dev) + goto skip; + /* !f->dst is a special case for bridge +@@ -1093,10 +1101,10 @@ int br_fdb_dump(struct sk_buff *skb, + * Therefore need a little more filtering + * we only want to dump the !f->dst case + */ +- if (f->dst) ++ if (dst) + goto skip; + } +- if (!filter_dev && f->dst) ++ if (!filter_dev && dst) + goto skip; + + err = fdb_fill_info(skb, br, f, diff --git a/queue-6.18/net-ks8851-avoid-excess-softirq-scheduling.patch b/queue-6.18/net-ks8851-avoid-excess-softirq-scheduling.patch new file mode 100644 index 0000000000..b67f589f94 --- /dev/null +++ b/queue-6.18/net-ks8851-avoid-excess-softirq-scheduling.patch @@ -0,0 +1,41 @@ +From 22230e68b2cf1ab6b027be8cf1198164a949c4fa Mon Sep 17 00:00:00 2001 +From: Marek Vasut +Date: Thu, 16 Apr 2026 01:09:45 +0200 +Subject: net: ks8851: Avoid excess softirq scheduling + +From: Marek Vasut + +commit 22230e68b2cf1ab6b027be8cf1198164a949c4fa upstream. + +The code injects a packet into netif_rx() repeatedly, which will add +it to its internal NAPI and schedule a softirq, and process it. It is +more efficient to queue multiple packets and process them all at the +local_bh_enable() time. + +Reviewed-by: Sebastian Andrzej Siewior +Fixes: e0863634bf9f ("net: ks8851: Queue RX packets in IRQ handler instead of disabling BHs") +Cc: stable@vger.kernel.org +Signed-off-by: Marek Vasut +Link: https://patch.msgid.link/20260415231020.455298-2-marex@nabladev.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/micrel/ks8851_common.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/micrel/ks8851_common.c ++++ b/drivers/net/ethernet/micrel/ks8851_common.c +@@ -373,9 +373,12 @@ static irqreturn_t ks8851_irq(int irq, v + if (status & IRQ_LCI) + mii_check_link(&ks->mii); + +- if (status & IRQ_RXI) ++ if (status & IRQ_RXI) { ++ local_bh_disable(); + while ((skb = __skb_dequeue(&rxq))) + netif_rx(skb); ++ local_bh_enable(); ++ } + + return IRQ_HANDLED; + } diff --git a/queue-6.18/net-ks8851-reinstate-disabling-of-bhs-around-irq-handler.patch b/queue-6.18/net-ks8851-reinstate-disabling-of-bhs-around-irq-handler.patch new file mode 100644 index 0000000000..0d6f47e1f9 --- /dev/null +++ b/queue-6.18/net-ks8851-reinstate-disabling-of-bhs-around-irq-handler.patch @@ -0,0 +1,469 @@ +From 5c9fcac3c872224316714d0d8914d9af16c76a6d Mon Sep 17 00:00:00 2001 +From: Marek Vasut +Date: Thu, 16 Apr 2026 01:09:44 +0200 +Subject: net: ks8851: Reinstate disabling of BHs around IRQ handler + +From: Marek Vasut + +commit 5c9fcac3c872224316714d0d8914d9af16c76a6d upstream. + +If the driver executes ks8851_irq() AND a TX packet has been sent, then +the driver enables TX queue via netif_wake_queue() which schedules TX +softirq to queue packets for this device. + +If CONFIG_PREEMPT_RT=y is set AND a packet has also been received by +the MAC, then ks8851_rx_pkts() calls netdev_alloc_skb_ip_align() to +allocate SKBs for the received packets. If netdev_alloc_skb_ip_align() +is called with BH enabled, then local_bh_enable() at the end of +netdev_alloc_skb_ip_align() will trigger the pending softirq processing, +which may ultimately call the .xmit callback ks8851_start_xmit_par(). +The ks8851_start_xmit_par() will try to lock struct ks8851_net_par +.lock spinlock, which is already locked by ks8851_irq() from which +ks8851_start_xmit_par() was called. This leads to a deadlock, which +is reported by the kernel, including a trace listed below. + +If CONFIG_PREEMPT_RT is not set, then since commit 0913ec336a6c0 +("net: ks8851: Fix deadlock with the SPI chip variant") the deadlock +can also be triggered without received packet in the RX FIFO. The +pending softirqs will be processed on return from +spin_unlock_bh(&ks->statelock) in ks8851_irq(), which triggers the +deadlock as well. + +Fix the problem by disabling BH around critical sections, including the +IRQ handler, thus preventing the net_tx_action() softirq from triggering +during these critical sections. The net_tx_action() softirq is triggered +once BH are re-enabled and at the end of the IRQ handler, once all the +other IRQ handler actions have been completed. + + __schedule from schedule_rtlock+0x1c/0x34 + schedule_rtlock from rtlock_slowlock_locked+0x548/0x904 + rtlock_slowlock_locked from rt_spin_lock+0x60/0x9c + rt_spin_lock from ks8851_start_xmit_par+0x74/0x1a8 + ks8851_start_xmit_par from netdev_start_xmit+0x20/0x44 + netdev_start_xmit from dev_hard_start_xmit+0xd0/0x188 + dev_hard_start_xmit from sch_direct_xmit+0xb8/0x25c + sch_direct_xmit from __qdisc_run+0x1f8/0x4ec + __qdisc_run from qdisc_run+0x1c/0x28 + qdisc_run from net_tx_action+0x1f0/0x268 + net_tx_action from handle_softirqs+0x1a4/0x270 + handle_softirqs from __local_bh_enable_ip+0xcc/0xe0 + __local_bh_enable_ip from __alloc_skb+0xd8/0x128 + __alloc_skb from __netdev_alloc_skb+0x3c/0x19c + __netdev_alloc_skb from ks8851_irq+0x388/0x4d4 + ks8851_irq from irq_thread_fn+0x24/0x64 + irq_thread_fn from irq_thread+0x178/0x28c + irq_thread from kthread+0x12c/0x138 + kthread from ret_from_fork+0x14/0x28 + +Reviewed-by: Sebastian Andrzej Siewior +Fixes: e0863634bf9f ("net: ks8851: Queue RX packets in IRQ handler instead of disabling BHs") +Cc: stable@vger.kernel.org +Signed-off-by: Marek Vasut +Link: https://patch.msgid.link/20260415231020.455298-1-marex@nabladev.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/micrel/ks8851.h | 6 -- + drivers/net/ethernet/micrel/ks8851_common.c | 64 +++++++++++----------------- + drivers/net/ethernet/micrel/ks8851_par.c | 15 ++---- + drivers/net/ethernet/micrel/ks8851_spi.c | 11 +--- + 4 files changed, 38 insertions(+), 58 deletions(-) + +--- a/drivers/net/ethernet/micrel/ks8851.h ++++ b/drivers/net/ethernet/micrel/ks8851.h +@@ -408,10 +408,8 @@ struct ks8851_net { + struct gpio_desc *gpio; + struct mii_bus *mii_bus; + +- void (*lock)(struct ks8851_net *ks, +- unsigned long *flags); +- void (*unlock)(struct ks8851_net *ks, +- unsigned long *flags); ++ void (*lock)(struct ks8851_net *ks); ++ void (*unlock)(struct ks8851_net *ks); + unsigned int (*rdreg16)(struct ks8851_net *ks, + unsigned int reg); + void (*wrreg16)(struct ks8851_net *ks, +--- a/drivers/net/ethernet/micrel/ks8851_common.c ++++ b/drivers/net/ethernet/micrel/ks8851_common.c +@@ -28,25 +28,23 @@ + /** + * ks8851_lock - register access lock + * @ks: The chip state +- * @flags: Spinlock flags + * + * Claim chip register access lock + */ +-static void ks8851_lock(struct ks8851_net *ks, unsigned long *flags) ++static void ks8851_lock(struct ks8851_net *ks) + { +- ks->lock(ks, flags); ++ ks->lock(ks); + } + + /** + * ks8851_unlock - register access unlock + * @ks: The chip state +- * @flags: Spinlock flags + * + * Release chip register access lock + */ +-static void ks8851_unlock(struct ks8851_net *ks, unsigned long *flags) ++static void ks8851_unlock(struct ks8851_net *ks) + { +- ks->unlock(ks, flags); ++ ks->unlock(ks); + } + + /** +@@ -129,11 +127,10 @@ static void ks8851_set_powermode(struct + static int ks8851_write_mac_addr(struct net_device *dev) + { + struct ks8851_net *ks = netdev_priv(dev); +- unsigned long flags; + u16 val; + int i; + +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + + /* + * Wake up chip in case it was powered off when stopped; otherwise, +@@ -149,7 +146,7 @@ static int ks8851_write_mac_addr(struct + if (!netif_running(dev)) + ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); + +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + + return 0; + } +@@ -163,12 +160,11 @@ static int ks8851_write_mac_addr(struct + static void ks8851_read_mac_addr(struct net_device *dev) + { + struct ks8851_net *ks = netdev_priv(dev); +- unsigned long flags; + u8 addr[ETH_ALEN]; + u16 reg; + int i; + +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + + for (i = 0; i < ETH_ALEN; i += 2) { + reg = ks8851_rdreg16(ks, KS_MAR(i)); +@@ -177,7 +173,7 @@ static void ks8851_read_mac_addr(struct + } + eth_hw_addr_set(dev, addr); + +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + } + + /** +@@ -312,11 +308,10 @@ static irqreturn_t ks8851_irq(int irq, v + { + struct ks8851_net *ks = _ks; + struct sk_buff_head rxq; +- unsigned long flags; + unsigned int status; + struct sk_buff *skb; + +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + + status = ks8851_rdreg16(ks, KS_ISR); + ks8851_wrreg16(ks, KS_ISR, status); +@@ -373,7 +368,7 @@ static irqreturn_t ks8851_irq(int irq, v + ks8851_wrreg16(ks, KS_RXCR1, rxc->rxcr1); + } + +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + + if (status & IRQ_LCI) + mii_check_link(&ks->mii); +@@ -405,7 +400,6 @@ static void ks8851_flush_tx_work(struct + static int ks8851_net_open(struct net_device *dev) + { + struct ks8851_net *ks = netdev_priv(dev); +- unsigned long flags; + int ret; + + ret = request_threaded_irq(dev->irq, NULL, ks8851_irq, +@@ -418,7 +412,7 @@ static int ks8851_net_open(struct net_de + + /* lock the card, even if we may not actually be doing anything + * else at the moment */ +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + + netif_dbg(ks, ifup, ks->netdev, "opening\n"); + +@@ -471,7 +465,7 @@ static int ks8851_net_open(struct net_de + + netif_dbg(ks, ifup, ks->netdev, "network device up\n"); + +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + mii_check_link(&ks->mii); + return 0; + } +@@ -487,23 +481,22 @@ static int ks8851_net_open(struct net_de + static int ks8851_net_stop(struct net_device *dev) + { + struct ks8851_net *ks = netdev_priv(dev); +- unsigned long flags; + + netif_info(ks, ifdown, dev, "shutting down\n"); + + netif_stop_queue(dev); + +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + /* turn off the IRQs and ack any outstanding */ + ks8851_wrreg16(ks, KS_IER, 0x0000); + ks8851_wrreg16(ks, KS_ISR, 0xffff); +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + + /* stop any outstanding work */ + ks8851_flush_tx_work(ks); + flush_work(&ks->rxctrl_work); + +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + /* shutdown RX process */ + ks8851_wrreg16(ks, KS_RXCR1, 0x0000); + +@@ -512,7 +505,7 @@ static int ks8851_net_stop(struct net_de + + /* set powermode to soft power down to save power */ + ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN); +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + + /* ensure any queued tx buffers are dumped */ + while (!skb_queue_empty(&ks->txq)) { +@@ -566,14 +559,13 @@ static netdev_tx_t ks8851_start_xmit(str + static void ks8851_rxctrl_work(struct work_struct *work) + { + struct ks8851_net *ks = container_of(work, struct ks8851_net, rxctrl_work); +- unsigned long flags; + +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + + /* need to shutdown RXQ before modifying filter parameters */ + ks8851_wrreg16(ks, KS_RXCR1, 0x00); + +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + } + + static void ks8851_set_rx_mode(struct net_device *dev) +@@ -780,7 +772,6 @@ static int ks8851_set_eeprom(struct net_ + { + struct ks8851_net *ks = netdev_priv(dev); + int offset = ee->offset; +- unsigned long flags; + int len = ee->len; + u16 tmp; + +@@ -794,7 +785,7 @@ static int ks8851_set_eeprom(struct net_ + if (!(ks->rc_ccr & CCR_EEPROM)) + return -ENOENT; + +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + + ks8851_eeprom_claim(ks); + +@@ -817,7 +808,7 @@ static int ks8851_set_eeprom(struct net_ + eeprom_93cx6_wren(&ks->eeprom, false); + + ks8851_eeprom_release(ks); +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + + return 0; + } +@@ -827,7 +818,6 @@ static int ks8851_get_eeprom(struct net_ + { + struct ks8851_net *ks = netdev_priv(dev); + int offset = ee->offset; +- unsigned long flags; + int len = ee->len; + + /* must be 2 byte aligned */ +@@ -837,7 +827,7 @@ static int ks8851_get_eeprom(struct net_ + if (!(ks->rc_ccr & CCR_EEPROM)) + return -ENOENT; + +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + + ks8851_eeprom_claim(ks); + +@@ -845,7 +835,7 @@ static int ks8851_get_eeprom(struct net_ + + eeprom_93cx6_multiread(&ks->eeprom, offset/2, (__le16 *)data, len/2); + ks8851_eeprom_release(ks); +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + + return 0; + } +@@ -904,7 +894,6 @@ static int ks8851_phy_reg(int reg) + static int ks8851_phy_read_common(struct net_device *dev, int phy_addr, int reg) + { + struct ks8851_net *ks = netdev_priv(dev); +- unsigned long flags; + int result; + int ksreg; + +@@ -912,9 +901,9 @@ static int ks8851_phy_read_common(struct + if (ksreg < 0) + return ksreg; + +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + result = ks8851_rdreg16(ks, ksreg); +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + + return result; + } +@@ -949,14 +938,13 @@ static void ks8851_phy_write(struct net_ + int phy, int reg, int value) + { + struct ks8851_net *ks = netdev_priv(dev); +- unsigned long flags; + int ksreg; + + ksreg = ks8851_phy_reg(reg); + if (ksreg >= 0) { +- ks8851_lock(ks, &flags); ++ ks8851_lock(ks); + ks8851_wrreg16(ks, ksreg, value); +- ks8851_unlock(ks, &flags); ++ ks8851_unlock(ks); + } + } + +--- a/drivers/net/ethernet/micrel/ks8851_par.c ++++ b/drivers/net/ethernet/micrel/ks8851_par.c +@@ -55,29 +55,27 @@ struct ks8851_net_par { + /** + * ks8851_lock_par - register access lock + * @ks: The chip state +- * @flags: Spinlock flags + * + * Claim chip register access lock + */ +-static void ks8851_lock_par(struct ks8851_net *ks, unsigned long *flags) ++static void ks8851_lock_par(struct ks8851_net *ks) + { + struct ks8851_net_par *ksp = to_ks8851_par(ks); + +- spin_lock_irqsave(&ksp->lock, *flags); ++ spin_lock_bh(&ksp->lock); + } + + /** + * ks8851_unlock_par - register access unlock + * @ks: The chip state +- * @flags: Spinlock flags + * + * Release chip register access lock + */ +-static void ks8851_unlock_par(struct ks8851_net *ks, unsigned long *flags) ++static void ks8851_unlock_par(struct ks8851_net *ks) + { + struct ks8851_net_par *ksp = to_ks8851_par(ks); + +- spin_unlock_irqrestore(&ksp->lock, *flags); ++ spin_unlock_bh(&ksp->lock); + } + + /** +@@ -233,7 +231,6 @@ static netdev_tx_t ks8851_start_xmit_par + { + struct ks8851_net *ks = netdev_priv(dev); + netdev_tx_t ret = NETDEV_TX_OK; +- unsigned long flags; + unsigned int txqcr; + u16 txmir; + int err; +@@ -241,7 +238,7 @@ static netdev_tx_t ks8851_start_xmit_par + netif_dbg(ks, tx_queued, ks->netdev, + "%s: skb %p, %d@%p\n", __func__, skb, skb->len, skb->data); + +- ks8851_lock_par(ks, &flags); ++ ks8851_lock_par(ks); + + txmir = ks8851_rdreg16_par(ks, KS_TXMIR) & 0x1fff; + +@@ -262,7 +259,7 @@ static netdev_tx_t ks8851_start_xmit_par + ret = NETDEV_TX_BUSY; + } + +- ks8851_unlock_par(ks, &flags); ++ ks8851_unlock_par(ks); + + return ret; + } +--- a/drivers/net/ethernet/micrel/ks8851_spi.c ++++ b/drivers/net/ethernet/micrel/ks8851_spi.c +@@ -71,11 +71,10 @@ struct ks8851_net_spi { + /** + * ks8851_lock_spi - register access lock + * @ks: The chip state +- * @flags: Spinlock flags + * + * Claim chip register access lock + */ +-static void ks8851_lock_spi(struct ks8851_net *ks, unsigned long *flags) ++static void ks8851_lock_spi(struct ks8851_net *ks) + { + struct ks8851_net_spi *kss = to_ks8851_spi(ks); + +@@ -85,11 +84,10 @@ static void ks8851_lock_spi(struct ks885 + /** + * ks8851_unlock_spi - register access unlock + * @ks: The chip state +- * @flags: Spinlock flags + * + * Release chip register access lock + */ +-static void ks8851_unlock_spi(struct ks8851_net *ks, unsigned long *flags) ++static void ks8851_unlock_spi(struct ks8851_net *ks) + { + struct ks8851_net_spi *kss = to_ks8851_spi(ks); + +@@ -309,7 +307,6 @@ static void ks8851_tx_work(struct work_s + struct ks8851_net_spi *kss; + unsigned short tx_space; + struct ks8851_net *ks; +- unsigned long flags; + struct sk_buff *txb; + bool last; + +@@ -317,7 +314,7 @@ static void ks8851_tx_work(struct work_s + ks = &kss->ks8851; + last = skb_queue_empty(&ks->txq); + +- ks8851_lock_spi(ks, &flags); ++ ks8851_lock_spi(ks); + + while (!last) { + txb = skb_dequeue(&ks->txq); +@@ -343,7 +340,7 @@ static void ks8851_tx_work(struct work_s + ks->tx_space = tx_space; + spin_unlock_bh(&ks->statelock); + +- ks8851_unlock_spi(ks, &flags); ++ ks8851_unlock_spi(ks); + } + + /** diff --git a/queue-6.18/net-mctp-fix-don-t-require-received-header-reserved-bits-to-be-zero.patch b/queue-6.18/net-mctp-fix-don-t-require-received-header-reserved-bits-to-be-zero.patch new file mode 100644 index 0000000000..e681fb2ce7 --- /dev/null +++ b/queue-6.18/net-mctp-fix-don-t-require-received-header-reserved-bits-to-be-zero.patch @@ -0,0 +1,85 @@ +From a663bac71a2f0b3ac6c373168ca57b2a6e6381aa Mon Sep 17 00:00:00 2001 +From: Yuan Zhaoming +Date: Fri, 17 Apr 2026 22:13:40 +0800 +Subject: net: mctp: fix don't require received header reserved bits to be zero + +From: Yuan Zhaoming + +commit a663bac71a2f0b3ac6c373168ca57b2a6e6381aa upstream. + +From the MCTP Base specification (DSP0236 v1.2.1), the first byte of +the MCTP header contains a 4 bit reserved field, and 4 bit version. + +On our current receive path, we require those 4 reserved bits to be +zero, but the 9500-8i card is non-conformant, and may set these +reserved bits. + +DSP0236 states that the reserved bits must be written as zero, and +ignored when read. While the device might not conform to the former, +we should accept these message to conform to the latter. + +Relax our check on the MCTP version byte to allow non-zero bits in the +reserved field. + +Fixes: 889b7da23abf ("mctp: Add initial routing framework") +Signed-off-by: Yuan Zhaoming +Cc: stable@vger.kernel.org +Acked-by: Jeremy Kerr +Link: https://patch.msgid.link/20260417141340.5306-1-yuanzhaoming901030@126.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + include/net/mctp.h | 3 +++ + net/mctp/route.c | 8 ++++++-- + 2 files changed, 9 insertions(+), 2 deletions(-) + +--- a/include/net/mctp.h ++++ b/include/net/mctp.h +@@ -26,6 +26,9 @@ struct mctp_hdr { + #define MCTP_VER_MIN 1 + #define MCTP_VER_MAX 1 + ++/* Definitions for ver field */ ++#define MCTP_HDR_VER_MASK GENMASK(3, 0) ++ + /* Definitions for flags_seq_tag field */ + #define MCTP_HDR_FLAG_SOM BIT(7) + #define MCTP_HDR_FLAG_EOM BIT(6) +--- a/net/mctp/route.c ++++ b/net/mctp/route.c +@@ -441,6 +441,7 @@ static int mctp_dst_input(struct mctp_ds + unsigned long f; + u8 tag, flags; + int rc; ++ u8 ver; + + msk = NULL; + rc = -EINVAL; +@@ -467,7 +468,8 @@ static int mctp_dst_input(struct mctp_ds + netid = mctp_cb(skb)->net; + skb_pull(skb, sizeof(struct mctp_hdr)); + +- if (mh->ver != 1) ++ ver = mh->ver & MCTP_HDR_VER_MASK; ++ if (ver < MCTP_VER_MIN || ver > MCTP_VER_MAX) + goto out; + + flags = mh->flags_seq_tag & (MCTP_HDR_FLAG_SOM | MCTP_HDR_FLAG_EOM); +@@ -1325,6 +1327,7 @@ static int mctp_pkttype_receive(struct s + struct mctp_dst dst; + struct mctp_hdr *mh; + int rc; ++ u8 ver; + + rcu_read_lock(); + mdev = __mctp_dev_get(dev); +@@ -1342,7 +1345,8 @@ static int mctp_pkttype_receive(struct s + + /* We have enough for a header; decode and route */ + mh = mctp_hdr(skb); +- if (mh->ver < MCTP_VER_MIN || mh->ver > MCTP_VER_MAX) ++ ver = mh->ver & MCTP_HDR_VER_MASK; ++ if (ver < MCTP_VER_MIN || ver > MCTP_VER_MAX) + goto err_drop; + + /* source must be valid unicast or null; drop reserved ranges and diff --git a/queue-6.18/net-qrtr-ns-free-the-node-during-ctrl_cmd_bye.patch b/queue-6.18/net-qrtr-ns-free-the-node-during-ctrl_cmd_bye.patch new file mode 100644 index 0000000000..74f4cdbda8 --- /dev/null +++ b/queue-6.18/net-qrtr-ns-free-the-node-during-ctrl_cmd_bye.patch @@ -0,0 +1,73 @@ +From 68efba36446a7774ea5b971257ade049272a07ac Mon Sep 17 00:00:00 2001 +From: Manivannan Sadhasivam +Date: Thu, 9 Apr 2026 23:04:14 +0530 +Subject: net: qrtr: ns: Free the node during ctrl_cmd_bye() + +From: Manivannan Sadhasivam + +commit 68efba36446a7774ea5b971257ade049272a07ac upstream. + +A node sends the BYE packet when it is about to go down. So the nameserver +should advertise the removal of the node to all remote and local observers +and free the node finally. But currently, the nameserver doesn't free the +node memory even after processing the BYE packet. This causes the node +memory to leak. + +Hence, remove the node from Xarray list and free the node memory during +both success and failure case of ctrl_cmd_bye(). + +Cc: stable@vger.kernel.org +Fixes: 0c2204a4ad71 ("net: qrtr: Migrate nameservice to kernel from userspace") +Signed-off-by: Manivannan Sadhasivam +Link: https://patch.msgid.link/20260409-qrtr-fix-v3-3-00a8a5ff2b51@oss.qualcomm.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/qrtr/ns.c | 20 +++++++++++++++----- + 1 file changed, 15 insertions(+), 5 deletions(-) + +--- a/net/qrtr/ns.c ++++ b/net/qrtr/ns.c +@@ -342,7 +342,7 @@ static int ctrl_cmd_bye(struct sockaddr_ + struct qrtr_node *node; + unsigned long index; + struct kvec iv; +- int ret; ++ int ret = 0; + + iv.iov_base = &pkt; + iv.iov_len = sizeof(pkt); +@@ -357,8 +357,10 @@ static int ctrl_cmd_bye(struct sockaddr_ + + /* Advertise the removal of this client to all local servers */ + local_node = node_get(qrtr_ns.local_node); +- if (!local_node) +- return 0; ++ if (!local_node) { ++ ret = 0; ++ goto delete_node; ++ } + + memset(&pkt, 0, sizeof(pkt)); + pkt.cmd = cpu_to_le32(QRTR_TYPE_BYE); +@@ -375,10 +377,18 @@ static int ctrl_cmd_bye(struct sockaddr_ + ret = kernel_sendmsg(qrtr_ns.sock, &msg, &iv, 1, sizeof(pkt)); + if (ret < 0 && ret != -ENODEV) { + pr_err("failed to send bye cmd\n"); +- return ret; ++ goto delete_node; + } + } +- return 0; ++ ++ /* Ignore -ENODEV */ ++ ret = 0; ++ ++delete_node: ++ xa_erase(&nodes, from->sq_node); ++ kfree(node); ++ ++ return ret; + } + + static int ctrl_cmd_del_client(struct sockaddr_qrtr *from, diff --git a/queue-6.18/net-rds-fix-mr-cleanup-on-copy-error.patch b/queue-6.18/net-rds-fix-mr-cleanup-on-copy-error.patch new file mode 100644 index 0000000000..e582b58ea9 --- /dev/null +++ b/queue-6.18/net-rds-fix-mr-cleanup-on-copy-error.patch @@ -0,0 +1,47 @@ +From 8141a2dc70080eda1aedc0389ed2db2b292af5bd Mon Sep 17 00:00:00 2001 +From: Ao Zhou +Date: Wed, 22 Apr 2026 22:52:07 +0800 +Subject: net: rds: fix MR cleanup on copy error + +From: Ao Zhou + +commit 8141a2dc70080eda1aedc0389ed2db2b292af5bd upstream. + +__rds_rdma_map() hands sg/pages ownership to the transport after +get_mr() succeeds. If copying the generated cookie back to user space +fails after that point, the error path must not free those resources +again before dropping the MR reference. + +Remove the duplicate unpin/free from the put_user() failure branch so +that MR teardown is handled only through the existing final cleanup +path. + +Fixes: 0d4597c8c5ab ("net/rds: Track user mapped pages through special API") +Cc: stable@kernel.org +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Signed-off-by: Ao Zhou +Signed-off-by: Ren Wei +Reviewed-by: Allison Henderson +Link: https://patch.msgid.link/79c8ef73ec8e5844d71038983940cc2943099baf.1776764247.git.draw51280@163.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/rds/rdma.c | 4 ---- + 1 file changed, 4 deletions(-) + +--- a/net/rds/rdma.c ++++ b/net/rds/rdma.c +@@ -326,10 +326,6 @@ static int __rds_rdma_map(struct rds_soc + + if (args->cookie_addr && + put_user(cookie, (u64 __user *)(unsigned long)args->cookie_addr)) { +- if (!need_odp) { +- unpin_user_pages(pages, nr_pages); +- kfree(sg); +- } + ret = -EFAULT; + goto out; + } diff --git a/queue-6.18/net-smc-avoid-early-lgr-access-in-smc_clc_wait_msg.patch b/queue-6.18/net-smc-avoid-early-lgr-access-in-smc_clc_wait_msg.patch new file mode 100644 index 0000000000..c9b10360be --- /dev/null +++ b/queue-6.18/net-smc-avoid-early-lgr-access-in-smc_clc_wait_msg.patch @@ -0,0 +1,49 @@ +From 5a8db80f721deee8e916c2cfdee78decda02ce4f Mon Sep 17 00:00:00 2001 +From: Ruijie Li +Date: Wed, 22 Apr 2026 23:40:18 +0800 +Subject: net/smc: avoid early lgr access in smc_clc_wait_msg + +From: Ruijie Li + +commit 5a8db80f721deee8e916c2cfdee78decda02ce4f upstream. + +A CLC decline can be received while the handshake is still in an early +stage, before the connection has been associated with a link group. + +The decline handling in smc_clc_wait_msg() updates link-group level sync +state for first-contact declines, but that state only exists after link +group setup has completed. Guard the link-group update accordingly and +keep the per-socket peer diagnosis handling unchanged. + +This preserves the existing sync_err handling for established link-group +contexts and avoids touching link-group state before it is available. + +Fixes: 0cfdd8f92cac ("smc: connection and link group creation") +Cc: stable@kernel.org +Reported-by: Yuan Tan +Reported-by: Yifan Wu +Reported-by: Juefei Pu +Reported-by: Xin Liu +Signed-off-by: Ruijie Li +Signed-off-by: Ren Wei +Reviewed-by: Dust Li +Link: https://patch.msgid.link/08c68a5c817acf198cce63d22517e232e8d60718.1776850759.git.ruijieli51@gmail.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + net/smc/smc_clc.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/net/smc/smc_clc.c ++++ b/net/smc/smc_clc.c +@@ -788,8 +788,8 @@ int smc_clc_wait_msg(struct smc_sock *sm + dclc = (struct smc_clc_msg_decline *)clcm; + reason_code = SMC_CLC_DECL_PEERDECL; + smc->peer_diagnosis = ntohl(dclc->peer_diagnosis); +- if (((struct smc_clc_msg_decline *)buf)->hdr.typev2 & +- SMC_FIRST_CONTACT_MASK) { ++ if ((dclc->hdr.typev2 & SMC_FIRST_CONTACT_MASK) && ++ smc->conn.lgr) { + smc->conn.lgr->sync_err = 1; + smc_lgr_terminate_sched(smc->conn.lgr); + } diff --git a/queue-6.18/net-txgbe-fix-firmware-version-check.patch b/queue-6.18/net-txgbe-fix-firmware-version-check.patch new file mode 100644 index 0000000000..bde8fdb346 --- /dev/null +++ b/queue-6.18/net-txgbe-fix-firmware-version-check.patch @@ -0,0 +1,48 @@ +From c263f644add3d6ad81f9d62a99284fde408f0caa Mon Sep 17 00:00:00 2001 +From: Jiawen Wu +Date: Wed, 22 Apr 2026 15:18:37 +0800 +Subject: net: txgbe: fix firmware version check + +From: Jiawen Wu + +commit c263f644add3d6ad81f9d62a99284fde408f0caa upstream. + +For the device SP, the firmware version is a 32-bit value where the +lower 20 bits represent the base version number. And the customized +firmware version populates the upper 12 bits with a specific +identification number. + +For other devices AML 25G and 40G, the upper 12 bits of the firmware +version is always non-zero, and they have other naming conventions. + +Only SP devices need to check this to tell if XPCS will work properly. +So the judgement of MAC type is added here. + +And the original logic compared the entire 32-bit value against 0x20010, +which caused the outdated base firmwares bypass the version check +without a warning. Apply a mask 0xfffff to isolate the lower 20 bits for +an accurate base version comparison. + +Fixes: ab928c24e6cd ("net: txgbe: add FW version warning") +Cc: stable@vger.kernel.org +Signed-off-by: Jiawen Wu +Reviewed-by: Jacob Keller +Link: https://patch.msgid.link/C787AA5C07598B13+20260422071837.372731-1-jiawenwu@trustnetic.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/wangxun/txgbe/txgbe_main.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c ++++ b/drivers/net/ethernet/wangxun/txgbe/txgbe_main.c +@@ -867,7 +867,8 @@ static int txgbe_probe(struct pci_dev *p + "0x%08x", etrack_id); + } + +- if (etrack_id < 0x20010) ++ if (wx->mac.type == wx_mac_sp && ++ ((etrack_id & 0xfffff) < 0x20010)) + dev_warn(&pdev->dev, "Please upgrade the firmware to 0x20010 or above.\n"); + + err = txgbe_test_hostif(wx); diff --git a/queue-6.18/netconsole-avoid-out-of-bounds-access-on-empty-string-in-trim_newline.patch b/queue-6.18/netconsole-avoid-out-of-bounds-access-on-empty-string-in-trim_newline.patch new file mode 100644 index 0000000000..1124dc4671 --- /dev/null +++ b/queue-6.18/netconsole-avoid-out-of-bounds-access-on-empty-string-in-trim_newline.patch @@ -0,0 +1,52 @@ +From 7079c8c13f2d33992bc846240517d88f4ab07781 Mon Sep 17 00:00:00 2001 +From: Breno Leitao +Date: Mon, 20 Apr 2026 03:18:36 -0700 +Subject: netconsole: avoid out-of-bounds access on empty string in trim_newline() + +From: Breno Leitao + +commit 7079c8c13f2d33992bc846240517d88f4ab07781 upstream. + +trim_newline() unconditionally dereferences s[len - 1] after computing +len = strnlen(s, maxlen). When the string is empty, len is 0 and the +expression underflows to s[(size_t)-1], reading (and potentially +writing) one byte before the buffer. + +The two callers feed trim_newline() with the result of strscpy() from +configfs store callbacks (dev_name_store, userdatum_value_store). +configfs guarantees count >= 1 reaches the callback, but the byte +itself can be NUL: a userspace write(fd, "\0", 1) leaves the +destination empty after strscpy() and triggers the underflow. The OOB +write only fires if the adjacent byte happens to be '\n', so this is +not a security issue, but the access is undefined behaviour either way. + +This pattern is commonly flagged by LLM-based code reviewers. While it +is not a security fix, the underlying access is undefined behaviour and +the change is small and self-contained, so it is a reasonable candidate +for the stable trees. + +Guard the dereference on a non-zero length. + +Fixes: ae001dc67907 ("net: netconsole: move newline trimming to function") +Cc: stable@vger.kernel.org +Signed-off-by: Breno Leitao +Reviewed-by: Gustavo Luiz Duarte +Reviewed-by: Simon Horman +Link: https://patch.msgid.link/20260420-netcons_trim_newline-v1-1-dc35889aeedf@debian.org +Signed-off-by: Paolo Abeni +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/netconsole.c | 2 ++ + 1 file changed, 2 insertions(+) + +--- a/drivers/net/netconsole.c ++++ b/drivers/net/netconsole.c +@@ -383,6 +383,8 @@ static void trim_newline(char *s, size_t + size_t len; + + len = strnlen(s, maxlen); ++ if (!len) ++ return; + if (s[len - 1] == '\n') + s[len - 1] = '\0'; + } diff --git a/queue-6.18/power-supply-axp288_charger-do-not-cancel-work-before-initializing-it.patch b/queue-6.18/power-supply-axp288_charger-do-not-cancel-work-before-initializing-it.patch new file mode 100644 index 0000000000..2bb94da16f --- /dev/null +++ b/queue-6.18/power-supply-axp288_charger-do-not-cancel-work-before-initializing-it.patch @@ -0,0 +1,83 @@ +From 658342fd75b582cbb06544d513171c3d645faead Mon Sep 17 00:00:00 2001 +From: Krzysztof Kozlowski +Date: Fri, 20 Feb 2026 18:49:39 +0100 +Subject: power: supply: axp288_charger: Do not cancel work before initializing it + +From: Krzysztof Kozlowski + +commit 658342fd75b582cbb06544d513171c3d645faead upstream. + +Driver registered devm handler to cancel_work_sync() before even the +work was initialized, thus leading to possible warning from +kernel/workqueue.c on (!work->func) check, if the error path was hit +before the initialization happened. + +Use devm_work_autocancel() on each work item independently, which +handles the initialization and handler to cancel work. + +Fixes: 165c2357744e ("power: supply: axp288_charger: Properly stop work on probe-error / remove") +Cc: stable@vger.kernel.org +Signed-off-by: Krzysztof Kozlowski +Reviewed-by: Hans de Goede +Reviewed-by: Chen-Yu Tsai +Link: https://patch.msgid.link/20260220174938.672883-5-krzysztof.kozlowski@oss.qualcomm.com +Signed-off-by: Sebastian Reichel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/power/supply/axp288_charger.c | 19 ++++++++----------- + 1 file changed, 8 insertions(+), 11 deletions(-) + +--- a/drivers/power/supply/axp288_charger.c ++++ b/drivers/power/supply/axp288_charger.c +@@ -10,6 +10,7 @@ + #include + #include + #include ++#include + #include + #include + #include +@@ -821,14 +822,6 @@ static int charger_init_hw_regs(struct a + return 0; + } + +-static void axp288_charger_cancel_work(void *data) +-{ +- struct axp288_chrg_info *info = data; +- +- cancel_work_sync(&info->otg.work); +- cancel_work_sync(&info->cable.work); +-} +- + static int axp288_charger_probe(struct platform_device *pdev) + { + int ret, i, pirq; +@@ -911,12 +904,12 @@ static int axp288_charger_probe(struct p + } + + /* Cancel our work on cleanup, register this before the notifiers */ +- ret = devm_add_action(dev, axp288_charger_cancel_work, info); ++ ret = devm_work_autocancel(dev, &info->cable.work, ++ axp288_charger_extcon_evt_worker); + if (ret) + return ret; + + /* Register for extcon notification */ +- INIT_WORK(&info->cable.work, axp288_charger_extcon_evt_worker); + info->cable.nb.notifier_call = axp288_charger_handle_cable_evt; + ret = devm_extcon_register_notifier_all(dev, info->cable.edev, + &info->cable.nb); +@@ -926,8 +919,12 @@ static int axp288_charger_probe(struct p + } + schedule_work(&info->cable.work); + ++ ret = devm_work_autocancel(dev, &info->otg.work, ++ axp288_charger_otg_evt_worker); ++ if (ret) ++ return ret; ++ + /* Register for OTG notification */ +- INIT_WORK(&info->otg.work, axp288_charger_otg_evt_worker); + info->otg.id_nb.notifier_call = axp288_charger_handle_otg_evt; + if (info->otg.cable) { + ret = devm_extcon_register_notifier(dev, info->otg.cable, diff --git a/queue-6.18/rdma-rxe-validate-pad-and-icrc-before-payload_size-in-rxe_rcv.patch b/queue-6.18/rdma-rxe-validate-pad-and-icrc-before-payload_size-in-rxe_rcv.patch new file mode 100644 index 0000000000..0326c627ed --- /dev/null +++ b/queue-6.18/rdma-rxe-validate-pad-and-icrc-before-payload_size-in-rxe_rcv.patch @@ -0,0 +1,51 @@ +From 7244491dab347f648e661da96dc0febadd9daec3 Mon Sep 17 00:00:00 2001 +From: hkbinbin +Date: Wed, 1 Apr 2026 12:19:07 +0000 +Subject: RDMA/rxe: Validate pad and ICRC before payload_size() in rxe_rcv + +From: hkbinbin + +commit 7244491dab347f648e661da96dc0febadd9daec3 upstream. + +rxe_rcv() currently checks only that the incoming packet is at least +header_size(pkt) bytes long before payload_size() is used. + +However, payload_size() subtracts both the attacker-controlled BTH pad +field and RXE_ICRC_SIZE from pkt->paylen: + + payload_size = pkt->paylen - offset[RXE_PAYLOAD] - bth_pad(pkt) + - RXE_ICRC_SIZE + +This means a short packet can still make payload_size() underflow even +if it includes enough bytes for the fixed headers. Simply requiring +header_size(pkt) + RXE_ICRC_SIZE is not sufficient either, because a +packet with a forged non-zero BTH pad can still leave payload_size() +negative and pass an underflowed value to later receive-path users. + +Fix this by validating pkt->paylen against the full minimum length +required by payload_size(): header_size(pkt) + bth_pad(pkt) + +RXE_ICRC_SIZE. + +Cc: stable@vger.kernel.org +Fixes: 8700e3e7c485 ("Soft RoCE driver") +Link: https://patch.msgid.link/r/20260401121907.1468366-1-hkbinbinbin@gmail.com +Signed-off-by: hkbinbin +Reviewed-by: Zhu Yanjun +Signed-off-by: Jason Gunthorpe +Signed-off-by: Greg Kroah-Hartman +--- + drivers/infiniband/sw/rxe/rxe_recv.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/drivers/infiniband/sw/rxe/rxe_recv.c ++++ b/drivers/infiniband/sw/rxe/rxe_recv.c +@@ -330,7 +330,8 @@ void rxe_rcv(struct sk_buff *skb) + pkt->qp = NULL; + pkt->mask |= rxe_opcode[pkt->opcode].mask; + +- if (unlikely(skb->len < header_size(pkt))) ++ if (unlikely(pkt->paylen < header_size(pkt) + bth_pad(pkt) + ++ RXE_ICRC_SIZE)) + goto drop; + + err = hdr_check(pkt); diff --git a/queue-6.18/series b/queue-6.18/series index 61aa061599..27f3a3a931 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -115,3 +115,26 @@ rxrpc-fix-rxrpc_input_call_event-to-only-unshare-data-packets.patch edac-versalnet-fix-memory-leak-in-remove-and-probe-error-paths.patch tools-accounting-handle-truncated-taskstats-netlink-messages.patch net-txgbe-fix-rtnl-assertion-warning-when-remove-module.patch +arm64-dts-marvell-udpu-add-ethernet-aliases.patch +net-qrtr-ns-free-the-node-during-ctrl_cmd_bye.patch +net-rds-fix-mr-cleanup-on-copy-error.patch +net-txgbe-fix-firmware-version-check.patch +net-smc-avoid-early-lgr-access-in-smc_clc_wait_msg.patch +net-ks8851-reinstate-disabling-of-bhs-around-irq-handler.patch +net-bridge-use-a-stable-fdb-dst-snapshot-in-rcu-readers.patch +netconsole-avoid-out-of-bounds-access-on-empty-string-in-trim_newline.patch +net-mctp-fix-don-t-require-received-header-reserved-bits-to-be-zero.patch +net-ks8851-avoid-excess-softirq-scheduling.patch +drm-arcpgu-fix-device-node-leak.patch +slub-fix-data-loss-and-overflow-in-krealloc.patch +tracing-fprobe-reject-registration-of-a-registered-fprobe-before-init.patch +rdma-rxe-validate-pad-and-icrc-before-payload_size-in-rxe_rcv.patch +ipv4-icmp-validate-reply-type-before-using-icmp_pointers.patch +libceph-prevent-potential-null-ptr-deref-in-ceph_handle_auth_reply.patch +spi-fix-resource-leaks-on-device-setup-failure.patch +extract-cert-wrap-key_pass-with-ifdef-use_pkcs11_engine.patch +tpm-avoid-wunused-but-set-variable.patch +loongarch-show-cpu-vulnerabilites-correctly.patch +power-supply-axp288_charger-do-not-cancel-work-before-initializing-it.patch +hwmon-isl28022-fix-integer-overflow-in-power-calculation-on-32-bit.patch +fs-prepare-for-adding-lsm-blob-to-backing_file.patch diff --git a/queue-6.18/slub-fix-data-loss-and-overflow-in-krealloc.patch b/queue-6.18/slub-fix-data-loss-and-overflow-in-krealloc.patch new file mode 100644 index 0000000000..087c6e1e2b --- /dev/null +++ b/queue-6.18/slub-fix-data-loss-and-overflow-in-krealloc.patch @@ -0,0 +1,129 @@ +From 082a6d03a2d685a83a332666b500ad3966349588 Mon Sep 17 00:00:00 2001 +From: Marco Elver +Date: Thu, 16 Apr 2026 15:25:07 +0200 +Subject: slub: fix data loss and overflow in krealloc() + +From: Marco Elver + +commit 082a6d03a2d685a83a332666b500ad3966349588 upstream. + +Commit 2cd8231796b5 ("mm/slub: allow to set node and align in +k[v]realloc") introduced the ability to force a reallocation if the +original object does not satisfy new alignment or NUMA node, even when +the object is being shrunk. + +This introduced two bugs in the reallocation fallback path: + +1. Data loss during NUMA migration: The jump to 'alloc_new' happens + before 'ks' and 'orig_size' are initialized. As a result, the + memcpy() in the 'alloc_new' block would copy 0 bytes into the new + allocation. + +2. Buffer overflow during shrinking: When shrinking an object while + forcing a new alignment, 'new_size' is smaller than the old size. + However, the memcpy() used the old size ('orig_size ?: ks'), leading + to an out-of-bounds write. + +The same overflow bug exists in the kvrealloc() fallback path, where the +old bucket size ksize(p) is copied into the new buffer without being +bounded by the new size. + +A simple reproducer: + + // e.g. add to lkdtm as KREALLOC_SHRINK_OVERFLOW + while (1) { + void *p = kmalloc(128, GFP_KERNEL); + p = krealloc_node_align(p, 64, 256, GFP_KERNEL, NUMA_NO_NODE); + kfree(p); + } + +demonstrates the issue: + + ================================================================== + BUG: KFENCE: out-of-bounds write in memcpy_orig+0x68/0x130 + + Out-of-bounds write at 0xffff8883ad757038 (120B right of kfence-#47): + memcpy_orig+0x68/0x130 + krealloc_node_align_noprof+0x1c8/0x340 + lkdtm_KREALLOC_SHRINK_OVERFLOW+0x8c/0xc0 [lkdtm] + lkdtm_do_action+0x3a/0x60 [lkdtm] + ... + + kfence-#47: 0xffff8883ad756fc0-0xffff8883ad756fff, size=64, cache=kmalloc-64 + + allocated by task 316 on cpu 7 at 97.680481s (0.021813s ago): + krealloc_node_align_noprof+0x19c/0x340 + lkdtm_KREALLOC_SHRINK_OVERFLOW+0x8c/0xc0 [lkdtm] + lkdtm_do_action+0x3a/0x60 [lkdtm] + ... + ================================================================== + +Fix it by moving the old size calculation to the top of __do_krealloc() +and bounding all copy lengths by the new allocation size. + +Fixes: 2cd8231796b5 ("mm/slub: allow to set node and align in k[v]realloc") +Cc: stable@vger.kernel.org +Reported-by: https://sashiko.dev/#/patchset/20260415143735.2974230-1-elver%40google.com +Signed-off-by: Marco Elver +Link: https://patch.msgid.link/20260416132837.3787694-1-elver@google.com +Reviewed-by: Harry Yoo (Oracle) +Signed-off-by: Vlastimil Babka (SUSE) +Signed-off-by: Greg Kroah-Hartman +--- + mm/slub.c | 24 ++++++++++++------------ + 1 file changed, 12 insertions(+), 12 deletions(-) + +--- a/mm/slub.c ++++ b/mm/slub.c +@@ -6999,16 +6999,6 @@ __do_krealloc(const void *p, size_t new_ + if (!kasan_check_byte(p)) + return NULL; + +- /* +- * If reallocation is not necessary (e. g. the new size is less +- * than the current allocated size), the current allocation will be +- * preserved unless __GFP_THISNODE is set. In the latter case a new +- * allocation on the requested node will be attempted. +- */ +- if (unlikely(flags & __GFP_THISNODE) && nid != NUMA_NO_NODE && +- nid != page_to_nid(virt_to_page(p))) +- goto alloc_new; +- + if (is_kfence_address(p)) { + ks = orig_size = kfence_ksize(p); + } else { +@@ -7027,6 +7017,16 @@ __do_krealloc(const void *p, size_t new_ + } + } + ++ /* ++ * If reallocation is not necessary (e. g. the new size is less ++ * than the current allocated size), the current allocation will be ++ * preserved unless __GFP_THISNODE is set. In the latter case a new ++ * allocation on the requested node will be attempted. ++ */ ++ if (unlikely(flags & __GFP_THISNODE) && nid != NUMA_NO_NODE && ++ nid != page_to_nid(virt_to_page(p))) ++ goto alloc_new; ++ + /* If the old object doesn't fit, allocate a bigger one */ + if (new_size > ks) + goto alloc_new; +@@ -7061,7 +7061,7 @@ alloc_new: + if (ret && p) { + /* Disable KASAN checks as the object's redzone is accessed. */ + kasan_disable_current(); +- memcpy(ret, kasan_reset_tag(p), orig_size ?: ks); ++ memcpy(ret, kasan_reset_tag(p), min(new_size, (size_t)(orig_size ?: ks))); + kasan_enable_current(); + } + +@@ -7288,7 +7288,7 @@ void *kvrealloc_node_align_noprof(const + if (p) { + /* We already know that `p` is not a vmalloc address. */ + kasan_disable_current(); +- memcpy(n, kasan_reset_tag(p), ksize(p)); ++ memcpy(n, kasan_reset_tag(p), min(size, ksize(p))); + kasan_enable_current(); + + kfree(p); diff --git a/queue-6.18/spi-fix-resource-leaks-on-device-setup-failure.patch b/queue-6.18/spi-fix-resource-leaks-on-device-setup-failure.patch new file mode 100644 index 0000000000..e1af94e95c --- /dev/null +++ b/queue-6.18/spi-fix-resource-leaks-on-device-setup-failure.patch @@ -0,0 +1,129 @@ +From db357034f7e0cf23f233f414a8508312dfe8fbbe Mon Sep 17 00:00:00 2001 +From: Johan Hovold +Date: Fri, 10 Apr 2026 17:49:06 +0200 +Subject: spi: fix resource leaks on device setup failure + +From: Johan Hovold + +commit db357034f7e0cf23f233f414a8508312dfe8fbbe upstream. + +Make sure to call controller cleanup() if spi_setup() fails while +registering a device to avoid leaking any resources allocated by +setup(). + +Fixes: c7299fea6769 ("spi: Fix spi device unregister flow") +Cc: stable@vger.kernel.org # 5.13 +Cc: Saravana Kannan +Signed-off-by: Johan Hovold +Link: https://patch.msgid.link/20260410154907.129248-2-johan@kernel.org +Signed-off-by: Mark Brown +Signed-off-by: Greg Kroah-Hartman +--- + drivers/spi/spi.c | 61 ++++++++++++++++++++++++++++++++---------------------- + 1 file changed, 37 insertions(+), 24 deletions(-) + +--- a/drivers/spi/spi.c ++++ b/drivers/spi/spi.c +@@ -43,6 +43,8 @@ EXPORT_TRACEPOINT_SYMBOL(spi_transfer_st + + #include "internals.h" + ++static int __spi_setup(struct spi_device *spi, bool initial_setup); ++ + static DEFINE_IDR(spi_controller_idr); + + static void spidev_release(struct device *dev) +@@ -729,7 +731,7 @@ static int __spi_add_device(struct spi_d + * normally rely on the device being setup. Devices + * using SPI_CS_HIGH can't coexist well otherwise... + */ +- status = spi_setup(spi); ++ status = __spi_setup(spi, true); + if (status < 0) { + dev_err(dev, "can't setup %s, status %d\n", + dev_name(&spi->dev), status); +@@ -3854,27 +3856,7 @@ static int spi_set_cs_timing(struct spi_ + return status; + } + +-/** +- * spi_setup - setup SPI mode and clock rate +- * @spi: the device whose settings are being modified +- * Context: can sleep, and no requests are queued to the device +- * +- * SPI protocol drivers may need to update the transfer mode if the +- * device doesn't work with its default. They may likewise need +- * to update clock rates or word sizes from initial values. This function +- * changes those settings, and must be called from a context that can sleep. +- * Except for SPI_CS_HIGH, which takes effect immediately, the changes take +- * effect the next time the device is selected and data is transferred to +- * or from it. When this function returns, the SPI device is deselected. +- * +- * Note that this call will fail if the protocol driver specifies an option +- * that the underlying controller or its driver does not support. For +- * example, not all hardware supports wire transfers using nine bit words, +- * LSB-first wire encoding, or active-high chipselects. +- * +- * Return: zero on success, else a negative error code. +- */ +-int spi_setup(struct spi_device *spi) ++static int __spi_setup(struct spi_device *spi, bool initial_setup) + { + unsigned bad_bits, ugly_bits; + int status; +@@ -3959,7 +3941,7 @@ int spi_setup(struct spi_device *spi) + status = spi_set_cs_timing(spi); + if (status) { + mutex_unlock(&spi->controller->io_mutex); +- return status; ++ goto err_cleanup; + } + + if (spi->controller->auto_runtime_pm && spi->controller->set_cs) { +@@ -3968,7 +3950,7 @@ int spi_setup(struct spi_device *spi) + mutex_unlock(&spi->controller->io_mutex); + dev_err(&spi->controller->dev, "Failed to power device: %d\n", + status); +- return status; ++ goto err_cleanup; + } + + /* +@@ -4004,6 +3986,37 @@ int spi_setup(struct spi_device *spi) + status); + + return status; ++ ++err_cleanup: ++ if (initial_setup) ++ spi_cleanup(spi); ++ ++ return status; ++} ++ ++/** ++ * spi_setup - setup SPI mode and clock rate ++ * @spi: the device whose settings are being modified ++ * Context: can sleep, and no requests are queued to the device ++ * ++ * SPI protocol drivers may need to update the transfer mode if the ++ * device doesn't work with its default. They may likewise need ++ * to update clock rates or word sizes from initial values. This function ++ * changes those settings, and must be called from a context that can sleep. ++ * Except for SPI_CS_HIGH, which takes effect immediately, the changes take ++ * effect the next time the device is selected and data is transferred to ++ * or from it. When this function returns, the SPI device is deselected. ++ * ++ * Note that this call will fail if the protocol driver specifies an option ++ * that the underlying controller or its driver does not support. For ++ * example, not all hardware supports wire transfers using nine bit words, ++ * LSB-first wire encoding, or active-high chipselects. ++ * ++ * Return: zero on success, else a negative error code. ++ */ ++int spi_setup(struct spi_device *spi) ++{ ++ return __spi_setup(spi, false); + } + EXPORT_SYMBOL_GPL(spi_setup); + diff --git a/queue-6.18/tpm-avoid-wunused-but-set-variable.patch b/queue-6.18/tpm-avoid-wunused-but-set-variable.patch new file mode 100644 index 0000000000..253987a829 --- /dev/null +++ b/queue-6.18/tpm-avoid-wunused-but-set-variable.patch @@ -0,0 +1,52 @@ +From 6f1d4d2ecfcd1b577dc87350ea965fe81f272e83 Mon Sep 17 00:00:00 2001 +From: Arnd Bergmann +Date: Fri, 22 Mar 2024 14:22:48 +0100 +Subject: tpm: avoid -Wunused-but-set-variable + +From: Arnd Bergmann + +commit 6f1d4d2ecfcd1b577dc87350ea965fe81f272e83 upstream. + +Outside of the EFI tpm code, the TPM_MEMREMAP()/TPM_MEMUNMAP functions are +defined as trivial macros, leading to the mapping_size variable ending +up unused: + +In file included from drivers/char/tpm/tpm-sysfs.c:16: +In file included from drivers/char/tpm/tpm.h:28: +include/linux/tpm_eventlog.h:167:6: error: variable 'mapping_size' set but not used [-Werror,-Wunused-but-set-variable] + 167 | int mapping_size; + +Turn the stubs into inline functions to avoid this warning. + +Cc: stable@vger.kernel.org # v5.3+ +Fixes: c46f3405692d ("tpm: Reserve the TPM final events table") +Signed-off-by: Arnd Bergmann +Reviewed-by: Thorsten Blum +Reviewed-by: Jarkko Sakkinen +Signed-off-by: Jarkko Sakkinen +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/tpm_eventlog.h | 9 +++++++-- + 1 file changed, 7 insertions(+), 2 deletions(-) + +--- a/include/linux/tpm_eventlog.h ++++ b/include/linux/tpm_eventlog.h +@@ -131,11 +131,16 @@ struct tcg_algorithm_info { + }; + + #ifndef TPM_MEMREMAP +-#define TPM_MEMREMAP(start, size) NULL ++static inline void *TPM_MEMREMAP(unsigned long start, size_t size) ++{ ++ return NULL; ++} + #endif + + #ifndef TPM_MEMUNMAP +-#define TPM_MEMUNMAP(start, size) do{} while(0) ++static inline void TPM_MEMUNMAP(void *mapping, size_t size) ++{ ++} + #endif + + /** diff --git a/queue-6.18/tracing-fprobe-reject-registration-of-a-registered-fprobe-before-init.patch b/queue-6.18/tracing-fprobe-reject-registration-of-a-registered-fprobe-before-init.patch new file mode 100644 index 0000000000..ed1b0faa4a --- /dev/null +++ b/queue-6.18/tracing-fprobe-reject-registration-of-a-registered-fprobe-before-init.patch @@ -0,0 +1,115 @@ +From 6ad51ada17ed80c9a5f205b4c01c424cac8b0d46 Mon Sep 17 00:00:00 2001 +From: "Masami Hiramatsu (Google)" +Date: Mon, 20 Apr 2026 23:00:48 +0900 +Subject: tracing/fprobe: Reject registration of a registered fprobe before init + +From: Masami Hiramatsu (Google) + +commit 6ad51ada17ed80c9a5f205b4c01c424cac8b0d46 upstream. + +Reject registration of a registered fprobe which is on the fprobe +hash table before initializing fprobe. +The add_fprobe_hash() checks this re-register fprobe, but since +fprobe_init() clears hlist_array field, it is too late to check it. +It has to check the re-registration before touncing fprobe. + +Link: https://lore.kernel.org/all/177669364845.132053.18375367916162315835.stgit@mhiramat.tok.corp.google.com/ + +Fixes: 4346ba160409 ("fprobe: Rewrite fprobe on function-graph tracer") +Cc: stable@vger.kernel.org +Signed-off-by: Masami Hiramatsu (Google) +Signed-off-by: Greg Kroah-Hartman +--- + kernel/trace/fprobe.c | 21 ++++++++++----------- + 1 file changed, 10 insertions(+), 11 deletions(-) + +--- a/kernel/trace/fprobe.c ++++ b/kernel/trace/fprobe.c +@@ -4,6 +4,7 @@ + */ + #define pr_fmt(fmt) "fprobe: " fmt + ++#include + #include + #include + #include +@@ -98,7 +99,7 @@ static bool delete_fprobe_node(struct fp + } + + /* Check existence of the fprobe */ +-static bool is_fprobe_still_exist(struct fprobe *fp) ++static bool fprobe_registered(struct fprobe *fp) + { + struct hlist_head *head; + struct fprobe_hlist *fph; +@@ -111,7 +112,7 @@ static bool is_fprobe_still_exist(struct + } + return false; + } +-NOKPROBE_SYMBOL(is_fprobe_still_exist); ++NOKPROBE_SYMBOL(fprobe_registered); + + static int add_fprobe_hash(struct fprobe *fp) + { +@@ -123,9 +124,6 @@ static int add_fprobe_hash(struct fprobe + if (WARN_ON_ONCE(!fph)) + return -EINVAL; + +- if (is_fprobe_still_exist(fp)) +- return -EEXIST; +- + head = &fprobe_table[hash_ptr(fp, FPROBE_HASH_BITS)]; + hlist_add_head_rcu(&fp->hlist_array->hlist, head); + return 0; +@@ -140,7 +138,7 @@ static int del_fprobe_hash(struct fprobe + if (WARN_ON_ONCE(!fph)) + return -EINVAL; + +- if (!is_fprobe_still_exist(fp)) ++ if (!fprobe_registered(fp)) + return -ENOENT; + + fph->fp = NULL; +@@ -360,7 +358,7 @@ static void fprobe_return(struct ftrace_ + if (!fp) + break; + curr += FPROBE_HEADER_SIZE_IN_LONG; +- if (is_fprobe_still_exist(fp) && !fprobe_disabled(fp)) { ++ if (fprobe_registered(fp) && !fprobe_disabled(fp)) { + if (WARN_ON_ONCE(curr + size > size_words)) + break; + fp->exit_handler(fp, trace->func, ret_ip, fregs, +@@ -718,12 +716,14 @@ int register_fprobe_ips(struct fprobe *f + struct fprobe_hlist *hlist_array; + int ret, i; + ++ guard(mutex)(&fprobe_mutex); ++ if (fprobe_registered(fp)) ++ return -EEXIST; ++ + ret = fprobe_init(fp, addrs, num); + if (ret) + return ret; + +- mutex_lock(&fprobe_mutex); +- + hlist_array = fp->hlist_array; + ret = fprobe_graph_add_ips(addrs, num); + if (!ret) { +@@ -731,7 +731,6 @@ int register_fprobe_ips(struct fprobe *f + for (i = 0; i < hlist_array->size; i++) + insert_fprobe_node(&hlist_array->array[i]); + } +- mutex_unlock(&fprobe_mutex); + + if (ret) + fprobe_fail_cleanup(fp); +@@ -793,7 +792,7 @@ int unregister_fprobe(struct fprobe *fp) + int ret = 0, i, count; + + mutex_lock(&fprobe_mutex); +- if (!fp || !is_fprobe_still_exist(fp)) { ++ if (!fp || !fprobe_registered(fp)) { + ret = -EINVAL; + goto out; + }