From: Greg Kroah-Hartman Date: Mon, 9 Mar 2026 13:46:22 +0000 (+0100) Subject: 6.18-stable patches X-Git-Tag: v6.19.7~12 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=bc9d2fe54aa56b8d211f300d4c4d0b6b64dd18fd;p=thirdparty%2Fkernel%2Fstable-queue.git 6.18-stable patches added patches: arm-clean-up-the-memset64-c-wrapper.patch asoc-fsl_xcvr-provide-regmap-names.patch asoc-fsl_xcvr-use-dev_err_probe-replacing-dev_err-return.patch ipmi-fix-use-after-free-and-list-corruption-on-sender-error.patch ksmbd-call-ksmbd_vfs_kern_path_end_removing-on-some-error-paths.patch platform-x86-hp-bioscfg-support-allocations-of-larger-data.patch revert-netfilter-nft_set_rbtree-validate-open-interval-overlap.patch --- diff --git a/queue-6.18/arm-clean-up-the-memset64-c-wrapper.patch b/queue-6.18/arm-clean-up-the-memset64-c-wrapper.patch new file mode 100644 index 0000000000..25c32a5297 --- /dev/null +++ b/queue-6.18/arm-clean-up-the-memset64-c-wrapper.patch @@ -0,0 +1,57 @@ +From b52343d1cb47bb27ca32a3f4952cc2fd3cd165bf Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= +Date: Fri, 13 Feb 2026 08:39:29 +0100 +Subject: ARM: clean up the memset64() C wrapper +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +commit b52343d1cb47bb27ca32a3f4952cc2fd3cd165bf upstream. + +The current logic to split the 64-bit argument into its 32-bit halves is +byte-order specific and a bit clunky. Use a union instead which is +easier to read and works in all cases. + +GCC still generates the same machine code. + +While at it, rename the arguments of the __memset64() prototype to +actually reflect their semantics. + +Signed-off-by: Thomas Weißschuh +Signed-off-by: Linus Torvalds +Reported-by: Ben Hutchings # for -stable +Link: https://lore.kernel.org/all/1a11526ae3d8664f705b541b8d6ea57b847b49a8.camel@decadent.org.uk/ +Suggested-by: https://lore.kernel.org/all/aZonkWMwpbFhzDJq@casper.infradead.org/ # for -stable +Link: https://lore.kernel.org/all/aZonkWMwpbFhzDJq@casper.infradead.org/ +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm/include/asm/string.h | 14 +++++++++----- + 1 file changed, 9 insertions(+), 5 deletions(-) + +--- a/arch/arm/include/asm/string.h ++++ b/arch/arm/include/asm/string.h +@@ -39,13 +39,17 @@ static inline void *memset32(uint32_t *p + } + + #define __HAVE_ARCH_MEMSET64 +-extern void *__memset64(uint64_t *, uint32_t low, __kernel_size_t, uint32_t hi); ++extern void *__memset64(uint64_t *, uint32_t first, __kernel_size_t, uint32_t second); + static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n) + { +- if (IS_ENABLED(CONFIG_CPU_LITTLE_ENDIAN)) +- return __memset64(p, v, n * 8, v >> 32); +- else +- return __memset64(p, v >> 32, n * 8, v); ++ union { ++ uint64_t val; ++ struct { ++ uint32_t first, second; ++ }; ++ } word = { .val = v }; ++ ++ return __memset64(p, word.first, n * 8, word.second); + } + + /* diff --git a/queue-6.18/asoc-fsl_xcvr-provide-regmap-names.patch b/queue-6.18/asoc-fsl_xcvr-provide-regmap-names.patch new file mode 100644 index 0000000000..5df67afccb --- /dev/null +++ b/queue-6.18/asoc-fsl_xcvr-provide-regmap-names.patch @@ -0,0 +1,49 @@ +From 08fd332eeb88515af4f1892d91f6ef4ea7558b71 Mon Sep 17 00:00:00 2001 +From: Alexander Stein +Date: Tue, 16 Dec 2025 09:49:30 +0100 +Subject: ASoC: fsl_xcvr: provide regmap names + +From: Alexander Stein + +commit 08fd332eeb88515af4f1892d91f6ef4ea7558b71 upstream. + +This driver uses multiple regmaps, which will causes name conflicts +in debugfs like: + debugfs: '30cc0000.xcvr' already exists in 'regmap' +Fix this by adding a name for the non-core regmap configurations. + +Signed-off-by: Alexander Stein +Link: https://patch.msgid.link/20251216084931.553328-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Signed-off-by: Fabio Estevam +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/fsl/fsl_xcvr.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -1323,6 +1323,7 @@ static const struct reg_default fsl_xcvr + }; + + static const struct regmap_config fsl_xcvr_regmap_phy_cfg = { ++ .name = "phy", + .reg_bits = 8, + .reg_stride = 4, + .val_bits = 32, +@@ -1335,6 +1336,7 @@ static const struct regmap_config fsl_xc + }; + + static const struct regmap_config fsl_xcvr_regmap_pllv0_cfg = { ++ .name = "pllv0", + .reg_bits = 8, + .reg_stride = 4, + .val_bits = 32, +@@ -1345,6 +1347,7 @@ static const struct regmap_config fsl_xc + }; + + static const struct regmap_config fsl_xcvr_regmap_pllv1_cfg = { ++ .name = "pllv1", + .reg_bits = 8, + .reg_stride = 4, + .val_bits = 32, diff --git a/queue-6.18/asoc-fsl_xcvr-use-dev_err_probe-replacing-dev_err-return.patch b/queue-6.18/asoc-fsl_xcvr-use-dev_err_probe-replacing-dev_err-return.patch new file mode 100644 index 0000000000..c49fbf4b74 --- /dev/null +++ b/queue-6.18/asoc-fsl_xcvr-use-dev_err_probe-replacing-dev_err-return.patch @@ -0,0 +1,164 @@ +From 8ae28d04593a5fdddb16d3edcdabb8d1e4330d0b Mon Sep 17 00:00:00 2001 +From: Alexander Stein +Date: Tue, 25 Nov 2025 11:13:33 +0100 +Subject: ASoC: fsl_xcvr: use dev_err_probe() replacing dev_err() + return + +From: Alexander Stein + +commit 8ae28d04593a5fdddb16d3edcdabb8d1e4330d0b upstream. + +Use dev_err_probe() to simplify the code. This also silences -517 errors. + +Signed-off-by: Alexander Stein +Link: https://patch.msgid.link/20251125101334.1596381-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Signed-off-by: Fabio Estevam +Signed-off-by: Greg Kroah-Hartman +--- + sound/soc/fsl/fsl_xcvr.c | 86 ++++++++++++++++++----------------------------- + 1 file changed, 34 insertions(+), 52 deletions(-) + +--- a/sound/soc/fsl/fsl_xcvr.c ++++ b/sound/soc/fsl/fsl_xcvr.c +@@ -1548,28 +1548,24 @@ static int fsl_xcvr_probe(struct platfor + xcvr->soc_data = of_device_get_match_data(&pdev->dev); + + xcvr->ipg_clk = devm_clk_get(dev, "ipg"); +- if (IS_ERR(xcvr->ipg_clk)) { +- dev_err(dev, "failed to get ipg clock\n"); +- return PTR_ERR(xcvr->ipg_clk); +- } ++ if (IS_ERR(xcvr->ipg_clk)) ++ return dev_err_probe(dev, PTR_ERR(xcvr->ipg_clk), ++ "failed to get ipg clock\n"); + + xcvr->phy_clk = devm_clk_get(dev, "phy"); +- if (IS_ERR(xcvr->phy_clk)) { +- dev_err(dev, "failed to get phy clock\n"); +- return PTR_ERR(xcvr->phy_clk); +- } ++ if (IS_ERR(xcvr->phy_clk)) ++ return dev_err_probe(dev, PTR_ERR(xcvr->phy_clk), ++ "failed to get phy clock\n"); + + xcvr->spba_clk = devm_clk_get(dev, "spba"); +- if (IS_ERR(xcvr->spba_clk)) { +- dev_err(dev, "failed to get spba clock\n"); +- return PTR_ERR(xcvr->spba_clk); +- } ++ if (IS_ERR(xcvr->spba_clk)) ++ return dev_err_probe(dev, PTR_ERR(xcvr->spba_clk), ++ "failed to get spba clock\n"); + + xcvr->pll_ipg_clk = devm_clk_get(dev, "pll_ipg"); +- if (IS_ERR(xcvr->pll_ipg_clk)) { +- dev_err(dev, "failed to get pll_ipg clock\n"); +- return PTR_ERR(xcvr->pll_ipg_clk); +- } ++ if (IS_ERR(xcvr->pll_ipg_clk)) ++ return dev_err_probe(dev, PTR_ERR(xcvr->pll_ipg_clk), ++ "failed to get pll_ipg clock\n"); + + fsl_asoc_get_pll_clocks(dev, &xcvr->pll8k_clk, + &xcvr->pll11k_clk); +@@ -1593,51 +1589,42 @@ static int fsl_xcvr_probe(struct platfor + + xcvr->regmap = devm_regmap_init_mmio_clk(dev, NULL, regs, + &fsl_xcvr_regmap_cfg); +- if (IS_ERR(xcvr->regmap)) { +- dev_err(dev, "failed to init XCVR regmap: %ld\n", +- PTR_ERR(xcvr->regmap)); +- return PTR_ERR(xcvr->regmap); +- } ++ if (IS_ERR(xcvr->regmap)) ++ return dev_err_probe(dev, PTR_ERR(xcvr->regmap), "failed to init XCVR regmap\n"); + + if (xcvr->soc_data->use_phy) { + xcvr->regmap_phy = devm_regmap_init(dev, NULL, xcvr, + &fsl_xcvr_regmap_phy_cfg); +- if (IS_ERR(xcvr->regmap_phy)) { +- dev_err(dev, "failed to init XCVR PHY regmap: %ld\n", +- PTR_ERR(xcvr->regmap_phy)); +- return PTR_ERR(xcvr->regmap_phy); +- } ++ if (IS_ERR(xcvr->regmap_phy)) ++ return dev_err_probe(dev, PTR_ERR(xcvr->regmap_phy), ++ "failed to init XCVR PHY regmap\n"); + + switch (xcvr->soc_data->pll_ver) { + case PLL_MX8MP: + xcvr->regmap_pll = devm_regmap_init(dev, NULL, xcvr, + &fsl_xcvr_regmap_pllv0_cfg); +- if (IS_ERR(xcvr->regmap_pll)) { +- dev_err(dev, "failed to init XCVR PLL regmap: %ld\n", +- PTR_ERR(xcvr->regmap_pll)); +- return PTR_ERR(xcvr->regmap_pll); +- } ++ if (IS_ERR(xcvr->regmap_pll)) ++ return dev_err_probe(dev, PTR_ERR(xcvr->regmap_pll), ++ "failed to init XCVR PLL regmap\n"); + break; + case PLL_MX95: + xcvr->regmap_pll = devm_regmap_init(dev, NULL, xcvr, + &fsl_xcvr_regmap_pllv1_cfg); +- if (IS_ERR(xcvr->regmap_pll)) { +- dev_err(dev, "failed to init XCVR PLL regmap: %ld\n", +- PTR_ERR(xcvr->regmap_pll)); +- return PTR_ERR(xcvr->regmap_pll); +- } ++ if (IS_ERR(xcvr->regmap_pll)) ++ return dev_err_probe(dev, PTR_ERR(xcvr->regmap_pll), ++ "failed to init XCVR PLL regmap\n"); + break; + default: +- dev_err(dev, "Error for PLL version %d\n", xcvr->soc_data->pll_ver); +- return -EINVAL; ++ return dev_err_probe(dev, -EINVAL, ++ "Error for PLL version %d\n", ++ xcvr->soc_data->pll_ver); + } + } + + xcvr->reset = devm_reset_control_get_optional_exclusive(dev, NULL); +- if (IS_ERR(xcvr->reset)) { +- dev_err(dev, "failed to get XCVR reset control\n"); +- return PTR_ERR(xcvr->reset); +- } ++ if (IS_ERR(xcvr->reset)) ++ return dev_err_probe(dev, PTR_ERR(xcvr->reset), ++ "failed to get XCVR reset control\n"); + + /* get IRQs */ + irq = platform_get_irq(pdev, 0); +@@ -1645,17 +1632,13 @@ static int fsl_xcvr_probe(struct platfor + return irq; + + ret = devm_request_irq(dev, irq, irq0_isr, 0, pdev->name, xcvr); +- if (ret) { +- dev_err(dev, "failed to claim IRQ0: %i\n", ret); +- return ret; +- } ++ if (ret) ++ return dev_err_probe(dev, ret, "failed to claim IRQ0\n"); + + rx_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "rxfifo"); + tx_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "txfifo"); +- if (!rx_res || !tx_res) { +- dev_err(dev, "could not find rxfifo or txfifo resource\n"); +- return -EINVAL; +- } ++ if (!rx_res || !tx_res) ++ return dev_err_probe(dev, -EINVAL, "could not find rxfifo or txfifo resource\n"); + xcvr->dma_prms_rx.chan_name = "rx"; + xcvr->dma_prms_tx.chan_name = "tx"; + xcvr->dma_prms_rx.addr = rx_res->start; +@@ -1678,8 +1661,7 @@ static int fsl_xcvr_probe(struct platfor + ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0); + if (ret) { + pm_runtime_disable(dev); +- dev_err(dev, "failed to pcm register\n"); +- return ret; ++ return dev_err_probe(dev, ret, "failed to pcm register\n"); + } + + ret = devm_snd_soc_register_component(dev, &fsl_xcvr_comp, diff --git a/queue-6.18/ipmi-fix-use-after-free-and-list-corruption-on-sender-error.patch b/queue-6.18/ipmi-fix-use-after-free-and-list-corruption-on-sender-error.patch new file mode 100644 index 0000000000..622f16d044 --- /dev/null +++ b/queue-6.18/ipmi-fix-use-after-free-and-list-corruption-on-sender-error.patch @@ -0,0 +1,70 @@ +From 594c11d0e1d445f580898a2b8c850f2e3f099368 Mon Sep 17 00:00:00 2001 +From: Corey Minyard +Date: Tue, 27 Jan 2026 07:22:35 -0600 +Subject: ipmi: Fix use-after-free and list corruption on sender error + +From: Corey Minyard + +commit 594c11d0e1d445f580898a2b8c850f2e3f099368 upstream. + +The analysis from Breno: + +When the SMI sender returns an error, smi_work() delivers an error +response but then jumps back to restart without cleaning up properly: + +1. intf->curr_msg is not cleared, so no new message is pulled +2. newmsg still points to the message, causing sender() to be called + again with the same message +3. If sender() fails again, deliver_err_response() is called with + the same recv_msg that was already queued for delivery + +This causes list_add corruption ("list_add double add") because the +recv_msg is added to the user_msgs list twice. Subsequently, the +corrupted list leads to use-after-free when the memory is freed and +reused, and eventually a NULL pointer dereference when accessing +recv_msg->done. + +The buggy sequence: + + sender() fails + -> deliver_err_response(recv_msg) // recv_msg queued for delivery + -> goto restart // curr_msg not cleared! + sender() fails again (same message!) + -> deliver_err_response(recv_msg) // tries to queue same recv_msg + -> LIST CORRUPTION + +Fix this by freeing the message and setting it to NULL on a send error. +Also, always free the newmsg on a send error, otherwise it will leak. + +Reported-by: Breno Leitao +Closes: https://lore.kernel.org/lkml/20260127-ipmi-v1-0-ba5cc90f516f@debian.org/ +Fixes: 9cf93a8fa9513 ("ipmi: Allow an SMI sender to return an error") +Cc: stable@vger.kernel.org # 4.18 +Reviewed-by: Breno Leitao +Signed-off-by: Corey Minyard +Signed-off-by: Breno Leitao +Signed-off-by: Greg Kroah-Hartman +--- + drivers/char/ipmi/ipmi_msghandler.c | 11 +++++++++-- + 1 file changed, 9 insertions(+), 2 deletions(-) + +--- a/drivers/char/ipmi/ipmi_msghandler.c ++++ b/drivers/char/ipmi/ipmi_msghandler.c +@@ -4848,8 +4848,15 @@ restart: + if (newmsg->recv_msg) + deliver_err_response(intf, + newmsg->recv_msg, cc); +- else +- ipmi_free_smi_msg(newmsg); ++ if (!run_to_completion) ++ spin_lock_irqsave(&intf->xmit_msgs_lock, ++ flags); ++ intf->curr_msg = NULL; ++ if (!run_to_completion) ++ spin_unlock_irqrestore(&intf->xmit_msgs_lock, ++ flags); ++ ipmi_free_smi_msg(newmsg); ++ newmsg = NULL; + goto restart; + } + } diff --git a/queue-6.18/ksmbd-call-ksmbd_vfs_kern_path_end_removing-on-some-error-paths.patch b/queue-6.18/ksmbd-call-ksmbd_vfs_kern_path_end_removing-on-some-error-paths.patch new file mode 100644 index 0000000000..529314e613 --- /dev/null +++ b/queue-6.18/ksmbd-call-ksmbd_vfs_kern_path_end_removing-on-some-error-paths.patch @@ -0,0 +1,68 @@ +From stable+bounces-219117-greg=kroah.com@vger.kernel.org Wed Feb 25 02:57:11 2026 +From: Sasha Levin +Date: Tue, 24 Feb 2026 20:49:44 -0500 +Subject: ksmbd: call ksmbd_vfs_kern_path_end_removing() on some error paths +To: stable@vger.kernel.org +Cc: Fedor Pchelkin , Namjae Jeon , Steve French , Sasha Levin +Message-ID: <20260225014944.3768468-1-sashal@kernel.org> + +From: Fedor Pchelkin + +[ Upstream commit a09dc10d1353f0e92c21eae2a79af1c2b1ddcde8 ] + +There are two places where ksmbd_vfs_kern_path_end_removing() needs to be +called in order to balance what the corresponding successful call to +ksmbd_vfs_kern_path_start_removing() has done, i.e. drop inode locks and +put the taken references. Otherwise there might be potential deadlocks +and unbalanced locks which are caught like: + +BUG: workqueue leaked lock or atomic: kworker/5:21/0x00000000/7596 + last function: handle_ksmbd_work +2 locks held by kworker/5:21/7596: + #0: ffff8881051ae448 (sb_writers#3){.+.+}-{0:0}, at: ksmbd_vfs_kern_path_locked+0x142/0x660 + #1: ffff888130e966c0 (&type->i_mutex_dir_key#3/1){+.+.}-{4:4}, at: ksmbd_vfs_kern_path_locked+0x17d/0x660 +CPU: 5 PID: 7596 Comm: kworker/5:21 Not tainted 6.1.162-00456-gc29b353f383b #138 +Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 +Workqueue: ksmbd-io handle_ksmbd_work +Call Trace: + + dump_stack_lvl+0x44/0x5b + process_one_work.cold+0x57/0x5c + worker_thread+0x82/0x600 + kthread+0x153/0x190 + ret_from_fork+0x22/0x30 + + +Found by Linux Verification Center (linuxtesting.org). + +Fixes: d5fc1400a34b ("smb/server: avoid deadlock when linking with ReplaceIfExists") +Cc: stable@vger.kernel.org +Signed-off-by: Fedor Pchelkin +Acked-by: Namjae Jeon +Signed-off-by: Steve French +[ ksmbd_vfs_kern_path_end_removing() -> ksmbd_vfs_kern_path_unlock() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/server/smb2pdu.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +--- a/fs/smb/server/smb2pdu.c ++++ b/fs/smb/server/smb2pdu.c +@@ -6117,14 +6117,14 @@ static int smb2_create_link(struct ksmbd + rc = -EINVAL; + ksmbd_debug(SMB, "cannot delete %s\n", + link_name); +- goto out; + } + } else { + rc = -EEXIST; + ksmbd_debug(SMB, "link already exists\n"); +- goto out; + } + ksmbd_vfs_kern_path_unlock(&path); ++ if (rc) ++ goto out; + } + rc = ksmbd_vfs_link(work, target_name, link_name); + if (rc) diff --git a/queue-6.18/platform-x86-hp-bioscfg-support-allocations-of-larger-data.patch b/queue-6.18/platform-x86-hp-bioscfg-support-allocations-of-larger-data.patch new file mode 100644 index 0000000000..f6ba691f94 --- /dev/null +++ b/queue-6.18/platform-x86-hp-bioscfg-support-allocations-of-larger-data.patch @@ -0,0 +1,57 @@ +From stable+bounces-223612-greg=kroah.com@vger.kernel.org Mon Mar 9 12:28:43 2026 +From: Sasha Levin +Date: Mon, 9 Mar 2026 07:24:45 -0400 +Subject: platform/x86: hp-bioscfg: Support allocations of larger data +To: stable@vger.kernel.org +Cc: "Mario Limonciello" , "Paul Kerry" , "Ilpo Järvinen" , "Sasha Levin" +Message-ID: <20260309112445.817434-1-sashal@kernel.org> + +From: Mario Limonciello + +[ Upstream commit 916727cfdb72cd01fef3fa6746e648f8cb70e713 ] + +Some systems have much larger amounts of enumeration attributes +than have been previously encountered. This can lead to page allocation +failures when using kcalloc(). Switch over to using kvcalloc() to +allow larger allocations. + +Fixes: 6b2770bfd6f92 ("platform/x86: hp-bioscfg: enum-attributes") +Cc: stable@vger.kernel.org +Reported-by: Paul Kerry +Tested-by: Paul Kerry +Closes: https://bugs.debian.org/1127612 +Signed-off-by: Mario Limonciello +Link: https://patch.msgid.link/20260225210646.59381-1-mario.limonciello@amd.com +Reviewed-by: Ilpo Järvinen +Signed-off-by: Ilpo Järvinen +[ kcalloc() => kvcalloc() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c | 9 ++++++--- + 1 file changed, 6 insertions(+), 3 deletions(-) + +--- a/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c ++++ b/drivers/platform/x86/hp/hp-bioscfg/enum-attributes.c +@@ -94,8 +94,11 @@ int hp_alloc_enumeration_data(void) + bioscfg_drv.enumeration_instances_count = + hp_get_instance_count(HP_WMI_BIOS_ENUMERATION_GUID); + +- bioscfg_drv.enumeration_data = kcalloc(bioscfg_drv.enumeration_instances_count, +- sizeof(*bioscfg_drv.enumeration_data), GFP_KERNEL); ++ if (!bioscfg_drv.enumeration_instances_count) ++ return -EINVAL; ++ bioscfg_drv.enumeration_data = kvcalloc(bioscfg_drv.enumeration_instances_count, ++ sizeof(*bioscfg_drv.enumeration_data), GFP_KERNEL); ++ + if (!bioscfg_drv.enumeration_data) { + bioscfg_drv.enumeration_instances_count = 0; + return -ENOMEM; +@@ -444,6 +447,6 @@ void hp_exit_enumeration_attributes(void + } + bioscfg_drv.enumeration_instances_count = 0; + +- kfree(bioscfg_drv.enumeration_data); ++ kvfree(bioscfg_drv.enumeration_data); + bioscfg_drv.enumeration_data = NULL; + } diff --git a/queue-6.18/revert-netfilter-nft_set_rbtree-validate-open-interval-overlap.patch b/queue-6.18/revert-netfilter-nft_set_rbtree-validate-open-interval-overlap.patch new file mode 100644 index 0000000000..63ff950dc7 --- /dev/null +++ b/queue-6.18/revert-netfilter-nft_set_rbtree-validate-open-interval-overlap.patch @@ -0,0 +1,261 @@ +From 3f23cf8602d22da4f75e11a6492ebd9458b233d5 Mon Sep 17 00:00:00 2001 +From: Greg Kroah-Hartman +Date: Mon, 9 Mar 2026 14:30:49 +0100 +Subject: Revert "netfilter: nft_set_rbtree: validate open interval overlap" + +From: Greg Kroah-Hartman + +This reverts commit 12b1681793e9b7552495290785a3570c539f409d which is +commit 648946966a08e4cb1a71619e3d1b12bd7642de7b upstream. + +It is causing netfilter issues, so revert it for now. + +Link: https://lore.kernel.org/r/aaeEd8UqYQ33Af7_@chamomile +Cc: Pablo Neira Ayuso +Cc: Florian Westphal +Signed-off-by: Greg Kroah-Hartman +--- + include/net/netfilter/nf_tables.h | 4 -- + net/netfilter/nf_tables_api.c | 21 ++--------- + net/netfilter/nft_set_rbtree.c | 71 +++++--------------------------------- + 3 files changed, 14 insertions(+), 82 deletions(-) + +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -278,8 +278,6 @@ struct nft_userdata { + unsigned char data[]; + }; + +-#define NFT_SET_ELEM_INTERNAL_LAST 0x1 +- + /* placeholder structure for opaque set element backend representation. */ + struct nft_elem_priv { }; + +@@ -289,7 +287,6 @@ struct nft_elem_priv { }; + * @key: element key + * @key_end: closing element key + * @data: element data +- * @flags: flags + * @priv: element private data and extensions + */ + struct nft_set_elem { +@@ -305,7 +302,6 @@ struct nft_set_elem { + u32 buf[NFT_DATA_VALUE_MAXLEN / sizeof(u32)]; + struct nft_data val; + } data; +- u32 flags; + struct nft_elem_priv *priv; + }; + +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -7272,8 +7272,7 @@ static u32 nft_set_maxsize(const struct + } + + static int nft_add_set_elem(struct nft_ctx *ctx, struct nft_set *set, +- const struct nlattr *attr, u32 nlmsg_flags, +- bool last) ++ const struct nlattr *attr, u32 nlmsg_flags) + { + struct nft_expr *expr_array[NFT_SET_EXPR_MAX] = {}; + struct nlattr *nla[NFTA_SET_ELEM_MAX + 1]; +@@ -7559,11 +7558,6 @@ static int nft_add_set_elem(struct nft_c + if (flags) + *nft_set_ext_flags(ext) = flags; + +- if (last) +- elem.flags = NFT_SET_ELEM_INTERNAL_LAST; +- else +- elem.flags = 0; +- + if (obj) + *nft_set_ext_obj(ext) = obj; + +@@ -7727,8 +7721,7 @@ static int nf_tables_newsetelem(struct s + nft_ctx_init(&ctx, net, skb, info->nlh, family, table, NULL, nla); + + nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { +- err = nft_add_set_elem(&ctx, set, attr, info->nlh->nlmsg_flags, +- nla_is_last(attr, rem)); ++ err = nft_add_set_elem(&ctx, set, attr, info->nlh->nlmsg_flags); + if (err < 0) { + NL_SET_BAD_ATTR(extack, attr); + return err; +@@ -7852,7 +7845,7 @@ static void nft_trans_elems_destroy_abor + } + + static int nft_del_setelem(struct nft_ctx *ctx, struct nft_set *set, +- const struct nlattr *attr, bool last) ++ const struct nlattr *attr) + { + struct nlattr *nla[NFTA_SET_ELEM_MAX + 1]; + struct nft_set_ext_tmpl tmpl; +@@ -7920,11 +7913,6 @@ static int nft_del_setelem(struct nft_ct + if (flags) + *nft_set_ext_flags(ext) = flags; + +- if (last) +- elem.flags = NFT_SET_ELEM_INTERNAL_LAST; +- else +- elem.flags = 0; +- + trans = nft_trans_elem_alloc(ctx, NFT_MSG_DELSETELEM, set); + if (trans == NULL) + goto fail_trans; +@@ -8072,8 +8060,7 @@ static int nf_tables_delsetelem(struct s + return nft_set_flush(&ctx, set, genmask); + + nla_for_each_nested(attr, nla[NFTA_SET_ELEM_LIST_ELEMENTS], rem) { +- err = nft_del_setelem(&ctx, set, attr, +- nla_is_last(attr, rem)); ++ err = nft_del_setelem(&ctx, set, attr); + if (err == -ENOENT && + NFNL_MSG_TYPE(info->nlh->nlmsg_type) == NFT_MSG_DESTROYSETELEM) + continue; +--- a/net/netfilter/nft_set_rbtree.c ++++ b/net/netfilter/nft_set_rbtree.c +@@ -304,19 +304,10 @@ static void nft_rbtree_set_start_cookie( + priv->start_rbe_cookie = (unsigned long)rbe; + } + +-static void nft_rbtree_set_start_cookie_open(struct nft_rbtree *priv, +- const struct nft_rbtree_elem *rbe, +- unsigned long open_interval) +-{ +- priv->start_rbe_cookie = (unsigned long)rbe | open_interval; +-} +- +-#define NFT_RBTREE_OPEN_INTERVAL 1UL +- + static bool nft_rbtree_cmp_start_cookie(struct nft_rbtree *priv, + const struct nft_rbtree_elem *rbe) + { +- return (priv->start_rbe_cookie & ~NFT_RBTREE_OPEN_INTERVAL) == (unsigned long)rbe; ++ return priv->start_rbe_cookie == (unsigned long)rbe; + } + + static bool nft_rbtree_insert_same_interval(const struct net *net, +@@ -346,14 +337,13 @@ static bool nft_rbtree_insert_same_inter + + static int __nft_rbtree_insert(const struct net *net, const struct nft_set *set, + struct nft_rbtree_elem *new, +- struct nft_elem_priv **elem_priv, u64 tstamp, bool last) ++ struct nft_elem_priv **elem_priv, u64 tstamp) + { + struct nft_rbtree_elem *rbe, *rbe_le = NULL, *rbe_ge = NULL, *rbe_prev; + struct rb_node *node, *next, *parent, **p, *first = NULL; + struct nft_rbtree *priv = nft_set_priv(set); + u8 cur_genmask = nft_genmask_cur(net); + u8 genmask = nft_genmask_next(net); +- unsigned long open_interval = 0; + int d; + + /* Descend the tree to search for an existing element greater than the +@@ -459,18 +449,10 @@ static int __nft_rbtree_insert(const str + } + } + +- if (nft_rbtree_interval_null(set, new)) { ++ if (nft_rbtree_interval_null(set, new)) ++ priv->start_rbe_cookie = 0; ++ else if (nft_rbtree_interval_start(new) && priv->start_rbe_cookie) + priv->start_rbe_cookie = 0; +- } else if (nft_rbtree_interval_start(new) && priv->start_rbe_cookie) { +- if (nft_set_is_anonymous(set)) { +- priv->start_rbe_cookie = 0; +- } else if (priv->start_rbe_cookie & NFT_RBTREE_OPEN_INTERVAL) { +- /* Previous element is an open interval that partially +- * overlaps with an existing non-open interval. +- */ +- return -ENOTEMPTY; +- } +- } + + /* - new start element matching existing start element: full overlap + * reported as -EEXIST, cleared by caller if NLM_F_EXCL is not given. +@@ -478,27 +460,7 @@ static int __nft_rbtree_insert(const str + if (rbe_ge && !nft_rbtree_cmp(set, new, rbe_ge) && + nft_rbtree_interval_start(rbe_ge) == nft_rbtree_interval_start(new)) { + *elem_priv = &rbe_ge->priv; +- +- /* - Corner case: new start element of open interval (which +- * comes as last element in the batch) overlaps the start of +- * an existing interval with an end element: partial overlap. +- */ +- node = rb_first(&priv->root); +- rbe = __nft_rbtree_next_active(node, genmask); +- if (rbe && nft_rbtree_interval_end(rbe)) { +- rbe = nft_rbtree_next_active(rbe, genmask); +- if (rbe && +- nft_rbtree_interval_start(rbe) && +- !nft_rbtree_cmp(set, new, rbe)) { +- if (last) +- return -ENOTEMPTY; +- +- /* Maybe open interval? */ +- open_interval = NFT_RBTREE_OPEN_INTERVAL; +- } +- } +- nft_rbtree_set_start_cookie_open(priv, rbe_ge, open_interval); +- ++ nft_rbtree_set_start_cookie(priv, rbe_ge); + return -EEXIST; + } + +@@ -553,12 +515,6 @@ static int __nft_rbtree_insert(const str + nft_rbtree_interval_end(rbe_ge) && nft_rbtree_interval_end(new)) + return -ENOTEMPTY; + +- /* - start element overlaps an open interval but end element is new: +- * partial overlap, reported as -ENOEMPTY. +- */ +- if (!rbe_ge && priv->start_rbe_cookie && nft_rbtree_interval_end(new)) +- return -ENOTEMPTY; +- + /* Accepted element: pick insertion point depending on key value */ + parent = NULL; + p = &priv->root.rb_node; +@@ -668,7 +624,6 @@ static int nft_rbtree_insert(const struc + struct nft_elem_priv **elem_priv) + { + struct nft_rbtree_elem *rbe = nft_elem_priv_cast(elem->priv); +- bool last = !!(elem->flags & NFT_SET_ELEM_INTERNAL_LAST); + struct nft_rbtree *priv = nft_set_priv(set); + u64 tstamp = nft_net_tstamp(net); + int err; +@@ -685,12 +640,8 @@ static int nft_rbtree_insert(const struc + cond_resched(); + + write_lock_bh(&priv->lock); +- err = __nft_rbtree_insert(net, set, rbe, elem_priv, tstamp, last); ++ err = __nft_rbtree_insert(net, set, rbe, elem_priv, tstamp); + write_unlock_bh(&priv->lock); +- +- if (nft_rbtree_interval_end(rbe)) +- priv->start_rbe_cookie = 0; +- + } while (err == -EAGAIN); + + return err; +@@ -778,7 +729,6 @@ nft_rbtree_deactivate(const struct net * + const struct nft_set_elem *elem) + { + struct nft_rbtree_elem *rbe, *this = nft_elem_priv_cast(elem->priv); +- bool last = !!(elem->flags & NFT_SET_ELEM_INTERNAL_LAST); + struct nft_rbtree *priv = nft_set_priv(set); + const struct rb_node *parent = priv->root.rb_node; + u8 genmask = nft_genmask_next(net); +@@ -819,10 +769,9 @@ nft_rbtree_deactivate(const struct net * + continue; + } + +- if (nft_rbtree_interval_start(rbe)) { +- if (!last) +- nft_rbtree_set_start_cookie(priv, rbe); +- } else if (!nft_rbtree_deactivate_same_interval(net, priv, rbe)) ++ if (nft_rbtree_interval_start(rbe)) ++ nft_rbtree_set_start_cookie(priv, rbe); ++ else if (!nft_rbtree_deactivate_same_interval(net, priv, rbe)) + return NULL; + + nft_rbtree_flush(net, set, &rbe->priv); diff --git a/queue-6.18/series b/queue-6.18/series index 2ebb705b69..1a8f832f36 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -192,3 +192,10 @@ selftests-mptcp-more-stable-simult_flows-tests.patch selftests-mptcp-join-check-rm_addr-not-sent-over-same-subflow.patch selftests-mptcp-join-check-removing-signal-subflow-endp.patch kbuild-split-.modinfo-out-from-elf_details.patch +revert-netfilter-nft_set_rbtree-validate-open-interval-overlap.patch +arm-clean-up-the-memset64-c-wrapper.patch +asoc-fsl_xcvr-use-dev_err_probe-replacing-dev_err-return.patch +asoc-fsl_xcvr-provide-regmap-names.patch +ipmi-fix-use-after-free-and-list-corruption-on-sender-error.patch +ksmbd-call-ksmbd_vfs_kern_path_end_removing-on-some-error-paths.patch +platform-x86-hp-bioscfg-support-allocations-of-larger-data.patch