From: Greg Kroah-Hartman Date: Tue, 24 Feb 2026 21:53:18 +0000 (-0800) Subject: 6.1-stable patches X-Git-Tag: v6.18.14~21 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=aacb6da5114e194f198843cb2d1f11ef2c4c73a2;p=thirdparty%2Fkernel%2Fstable-queue.git 6.1-stable patches added patches: ata-libata-scsi-refactor-ata_scsi_translate.patch ata-pata_ftide010-fix-some-dma-timings.patch ext4-don-t-cache-extent-during-splitting-extent.patch ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch --- diff --git a/queue-6.1/ata-libata-scsi-refactor-ata_scsi_translate.patch b/queue-6.1/ata-libata-scsi-refactor-ata_scsi_translate.patch new file mode 100644 index 0000000000..2ed1c152b6 --- /dev/null +++ b/queue-6.1/ata-libata-scsi-refactor-ata_scsi_translate.patch @@ -0,0 +1,155 @@ +From bb3a8154b1a1dc2c86d037482c0a2cf9186829ed Mon Sep 17 00:00:00 2001 +From: Damien Le Moal +Date: Wed, 17 Dec 2025 14:05:25 +0900 +Subject: ata: libata-scsi: refactor ata_scsi_translate() + +From: Damien Le Moal + +commit bb3a8154b1a1dc2c86d037482c0a2cf9186829ed upstream. + +Factor out of ata_scsi_translate() the code handling queued command +deferral using the port qc_defer callback and issuing the queued +command with ata_qc_issue() into the new function ata_scsi_qc_issue(), +and simplify the goto used in ata_scsi_translate(). +While at it, also add a lockdep annotation to check that the port lock +is held when ata_scsi_translate() is called. + +No functional changes. + +Cc: stable@vger.kernel.org +Signed-off-by: Damien Le Moal +Reviewed-by: Niklas Cassel +Reviewed-by: Martin K. Petersen +Reviewed-by: John Garry +Reviewed-by: Igor Pylypiv +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/libata-scsi.c | 81 ++++++++++++++++++++++++++++------------------ + 1 file changed, 50 insertions(+), 31 deletions(-) + +--- a/drivers/ata/libata-scsi.c ++++ b/drivers/ata/libata-scsi.c +@@ -1724,6 +1724,42 @@ static void ata_scsi_qc_complete(struct + ata_qc_done(qc); + } + ++static int ata_scsi_qc_issue(struct ata_port *ap, struct ata_queued_cmd *qc) ++{ ++ int ret; ++ ++ if (!ap->ops->qc_defer) ++ goto issue; ++ ++ /* Check if the command needs to be deferred. */ ++ ret = ap->ops->qc_defer(qc); ++ switch (ret) { ++ case 0: ++ break; ++ case ATA_DEFER_LINK: ++ ret = SCSI_MLQUEUE_DEVICE_BUSY; ++ break; ++ case ATA_DEFER_PORT: ++ ret = SCSI_MLQUEUE_HOST_BUSY; ++ break; ++ default: ++ WARN_ON_ONCE(1); ++ ret = SCSI_MLQUEUE_HOST_BUSY; ++ break; ++ } ++ ++ if (ret) { ++ /* Force a requeue of the command to defer its execution. */ ++ ata_qc_free(qc); ++ return ret; ++ } ++ ++issue: ++ ata_qc_issue(qc); ++ ++ return 0; ++} ++ + /** + * ata_scsi_translate - Translate then issue SCSI command to ATA device + * @dev: ATA device to which the command is addressed +@@ -1747,66 +1783,49 @@ static void ata_scsi_qc_complete(struct + * spin_lock_irqsave(host lock) + * + * RETURNS: +- * 0 on success, SCSI_ML_QUEUE_DEVICE_BUSY if the command +- * needs to be deferred. ++ * 0 on success, SCSI_ML_QUEUE_DEVICE_BUSY or SCSI_MLQUEUE_HOST_BUSY if the ++ * command needs to be deferred. + */ + static int ata_scsi_translate(struct ata_device *dev, struct scsi_cmnd *cmd, + ata_xlat_func_t xlat_func) + { + struct ata_port *ap = dev->link->ap; + struct ata_queued_cmd *qc; +- int rc; + ++ lockdep_assert_held(ap->lock); ++ ++ /* ++ * ata_scsi_qc_new() calls scsi_done(cmd) in case of failure. So we ++ * have nothing further to do when allocating a qc fails. ++ */ + qc = ata_scsi_qc_new(dev, cmd); + if (!qc) +- goto err_mem; ++ return 0; + + /* data is present; dma-map it */ + if (cmd->sc_data_direction == DMA_FROM_DEVICE || + cmd->sc_data_direction == DMA_TO_DEVICE) { + if (unlikely(scsi_bufflen(cmd) < 1)) { + ata_dev_warn(dev, "WARNING: zero len r/w req\n"); +- goto err_did; ++ cmd->result = (DID_ERROR << 16); ++ goto done; + } + + ata_sg_init(qc, scsi_sglist(cmd), scsi_sg_count(cmd)); +- + qc->dma_dir = cmd->sc_data_direction; + } + + qc->complete_fn = ata_scsi_qc_complete; + + if (xlat_func(qc)) +- goto early_finish; +- +- if (ap->ops->qc_defer) { +- if ((rc = ap->ops->qc_defer(qc))) +- goto defer; +- } +- +- /* select device, send command to hardware */ +- ata_qc_issue(qc); +- +- return 0; ++ goto done; + +-early_finish: +- ata_qc_free(qc); +- scsi_done(cmd); +- return 0; ++ return ata_scsi_qc_issue(ap, qc); + +-err_did: ++done: + ata_qc_free(qc); +- cmd->result = (DID_ERROR << 16); + scsi_done(cmd); +-err_mem: + return 0; +- +-defer: +- ata_qc_free(qc); +- if (rc == ATA_DEFER_LINK) +- return SCSI_MLQUEUE_DEVICE_BUSY; +- else +- return SCSI_MLQUEUE_HOST_BUSY; + } + + struct ata_scsi_args { diff --git a/queue-6.1/ata-pata_ftide010-fix-some-dma-timings.patch b/queue-6.1/ata-pata_ftide010-fix-some-dma-timings.patch new file mode 100644 index 0000000000..0d282bbfde --- /dev/null +++ b/queue-6.1/ata-pata_ftide010-fix-some-dma-timings.patch @@ -0,0 +1,39 @@ +From ff4a46c278ac6a4b3f39be1492a4568b6dcc6105 Mon Sep 17 00:00:00 2001 +From: Linus Walleij +Date: Tue, 3 Feb 2026 11:23:01 +0100 +Subject: ata: pata_ftide010: Fix some DMA timings + +From: Linus Walleij + +commit ff4a46c278ac6a4b3f39be1492a4568b6dcc6105 upstream. + +The FTIDE010 has been missing some timing settings since its +inception, since the upstream OpenWrt patch was missing these. + +The community has since come up with the appropriate timings. + +Fixes: be4e456ed3a5 ("ata: Add driver for Faraday Technology FTIDE010") +Cc: stable@vger.kernel.org +Signed-off-by: Linus Walleij +Signed-off-by: Niklas Cassel +Signed-off-by: Greg Kroah-Hartman +--- + drivers/ata/pata_ftide010.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/drivers/ata/pata_ftide010.c ++++ b/drivers/ata/pata_ftide010.c +@@ -123,10 +123,10 @@ static const u8 mwdma_50_active_time[3] + static const u8 mwdma_50_recovery_time[3] = {6, 2, 1}; + static const u8 mwdma_66_active_time[3] = {8, 3, 3}; + static const u8 mwdma_66_recovery_time[3] = {8, 2, 1}; +-static const u8 udma_50_setup_time[6] = {3, 3, 2, 2, 1, 1}; ++static const u8 udma_50_setup_time[6] = {3, 3, 2, 2, 1, 9}; + static const u8 udma_50_hold_time[6] = {3, 1, 1, 1, 1, 1}; +-static const u8 udma_66_setup_time[7] = {4, 4, 3, 2, }; +-static const u8 udma_66_hold_time[7] = {}; ++static const u8 udma_66_setup_time[7] = {4, 4, 3, 2, 1, 9, 9}; ++static const u8 udma_66_hold_time[7] = {4, 2, 1, 1, 1, 1, 1}; + + /* + * We set 66 MHz for all MWDMA modes diff --git a/queue-6.1/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch b/queue-6.1/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch index a2981b02b2..f38f81248d 100644 --- a/queue-6.1/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch +++ b/queue-6.1/drm-amd-display-use-same-max-plane-scaling-limits-fo.patch @@ -50,14 +50,12 @@ Cc: Leo Li Signed-off-by: Alex Deucher Signed-off-by: Sasha Levin --- - drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++ + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c | 5 +++++ 1 file changed, 5 insertions(+) -diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -index df4cbf81c6b50..b3a1dbeac4839 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_plane.c -@@ -970,10 +970,15 @@ static void get_min_max_dc_plane_scaling(struct drm_device *dev, +@@ -970,10 +970,15 @@ static void get_min_max_dc_plane_scaling *min_downscale = plane_cap->max_downscale_factor.nv12; break; @@ -73,6 +71,3 @@ index df4cbf81c6b50..b3a1dbeac4839 100644 *max_upscale = plane_cap->max_upscale_factor.fp16; *min_downscale = plane_cap->max_downscale_factor.fp16; break; --- -2.51.0 - diff --git a/queue-6.1/ext4-don-t-cache-extent-during-splitting-extent.patch b/queue-6.1/ext4-don-t-cache-extent-during-splitting-extent.patch new file mode 100644 index 0000000000..939bee6d3f --- /dev/null +++ b/queue-6.1/ext4-don-t-cache-extent-during-splitting-extent.patch @@ -0,0 +1,74 @@ +From 8b4b19a2f96348d70bfa306ef7d4a13b0bcbea79 Mon Sep 17 00:00:00 2001 +From: Zhang Yi +Date: Sat, 29 Nov 2025 18:32:37 +0800 +Subject: ext4: don't cache extent during splitting extent + +From: Zhang Yi + +commit 8b4b19a2f96348d70bfa306ef7d4a13b0bcbea79 upstream. + +Caching extents during the splitting process is risky, as it may result +in stale extents remaining in the status tree. Moreover, in most cases, +the corresponding extent block entries are likely already cached before +the split happens, making caching here not particularly useful. + +Assume we have an unwritten extent, and then DIO writes the first half. + + [UUUUUUUUUUUUUUUU] on-disk extent U: unwritten extent + [UUUUUUUUUUUUUUUU] extent status tree + |<- ->| ----> dio write this range + +First, when ext4_split_extent_at() splits this extent, it truncates the +existing extent and then inserts a new one. During this process, this +extent status entry may be shrunk, and calls to ext4_find_extent() and +ext4_cache_extents() may occur, which could potentially insert the +truncated range as a hole into the extent status tree. After the split +is completed, this hole is not replaced with the correct status. + + [UUUUUUU|UUUUUUUU] on-disk extent U: unwritten extent + [UUUUUUU|HHHHHHHH] extent status tree H: hole + +Then, the outer calling functions will not correct this remaining hole +extent either. Finally, if we perform a delayed buffer write on this +latter part, it will re-insert the delayed extent and cause an error in +space accounting. + +In adition, if the unwritten extent cache is not shrunk during the +splitting, ext4_cache_extents() also conflicts with existing extents +when caching extents. In the future, we will add checks when caching +extents, which will trigger a warning. Therefore, Do not cache extents +that are being split. + +Signed-off-by: Zhang Yi +Reviewed-by: Ojaswin Mujoo +Reviewed-by: Baokun Li +Cc: stable@kernel.org +Message-ID: <20251129103247.686136-6-yi.zhang@huaweicloud.com> +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/extents.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -3174,6 +3174,9 @@ static int ext4_split_extent_at(handle_t + BUG_ON((split_flag & (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2)) == + (EXT4_EXT_DATA_VALID1 | EXT4_EXT_DATA_VALID2)); + ++ /* Do not cache extents that are in the process of being modified. */ ++ flags |= EXT4_EX_NOCACHE; ++ + ext_debug(inode, "logical block %llu\n", (unsigned long long)split); + + ext4_ext_show_leaf(inode, path); +@@ -3344,6 +3347,9 @@ static int ext4_split_extent(handle_t *h + ee_len = ext4_ext_get_actual_len(ex); + unwritten = ext4_ext_is_unwritten(ex); + ++ /* Do not cache extents that are in the process of being modified. */ ++ flags |= EXT4_EX_NOCACHE; ++ + if (map->m_lblk + map->m_len < ee_block + ee_len) { + split_flag1 = split_flag & EXT4_EXT_MAY_ZEROOUT; + flags1 = flags | EXT4_GET_BLOCKS_PRE_IO; diff --git a/queue-6.1/ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch b/queue-6.1/ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch new file mode 100644 index 0000000000..b2f902e815 --- /dev/null +++ b/queue-6.1/ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch @@ -0,0 +1,40 @@ +From ca81109d4a8f192dc1cbad4a1ee25246363c2833 Mon Sep 17 00:00:00 2001 +From: Zilin Guan +Date: Thu, 25 Dec 2025 08:48:00 +0000 +Subject: ext4: fix memory leak in ext4_ext_shift_extents() + +From: Zilin Guan + +commit ca81109d4a8f192dc1cbad4a1ee25246363c2833 upstream. + +In ext4_ext_shift_extents(), if the extent is NULL in the while loop, the +function returns immediately without releasing the path obtained via +ext4_find_extent(), leading to a memory leak. + +Fix this by jumping to the out label to ensure the path is properly +released. + +Fixes: a18ed359bdddc ("ext4: always check ext4_ext_find_extent result") +Signed-off-by: Zilin Guan +Reviewed-by: Zhang Yi +Reviewed-by: Baokun Li +Link: https://patch.msgid.link/20251225084800.905701-1-zilin@seu.edu.cn +Signed-off-by: Theodore Ts'o +Cc: stable@kernel.org +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/extents.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +--- a/fs/ext4/extents.c ++++ b/fs/ext4/extents.c +@@ -5262,7 +5262,8 @@ again: + if (!extent) { + EXT4_ERROR_INODE(inode, "unexpected hole at %lu", + (unsigned long) *iterator); +- return -EFSCORRUPTED; ++ ret = -EFSCORRUPTED; ++ goto out; + } + if (SHIFT == SHIFT_LEFT && *iterator > + le32_to_cpu(extent->ee_block)) { diff --git a/queue-6.1/ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch b/queue-6.1/ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch new file mode 100644 index 0000000000..ba58304adb --- /dev/null +++ b/queue-6.1/ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch @@ -0,0 +1,43 @@ +From 3574c322b1d0eb32dbd76b469cb08f9a67641599 Mon Sep 17 00:00:00 2001 +From: Jan Kara +Date: Wed, 14 Jan 2026 19:28:19 +0100 +Subject: ext4: use optimized mballoc scanning regardless of inode format + +From: Jan Kara + +commit 3574c322b1d0eb32dbd76b469cb08f9a67641599 upstream. + +Currently we don't used mballoc optimized scanning (using max free +extent order and avg free extent order group lists) for inodes with +indirect block based format. This is confusing for users and I don't see +a good reason for that. Even with indirect block based inode format we +can spend big amount of time searching for free blocks for large +filesystems with fragmented free space. To add to the confusion before +commit 077d0c2c78df ("ext4: make mb_optimize_scan performance mount +option work with extents") optimized scanning was applied *only* to +indirect block based inodes so that commit appears as a performance +regression to some users. Just use optimized scanning whenever it is +enabled by mount options. + +Reviewed-by: Baokun Li +Reviewed-by: Zhang Yi +Signed-off-by: Jan Kara +Cc: stable@kernel.org +Link: https://patch.msgid.link/20260114182836.14120-4-jack@suse.cz +Signed-off-by: Theodore Ts'o +Signed-off-by: Greg Kroah-Hartman +--- + fs/ext4/mballoc.c | 2 -- + 1 file changed, 2 deletions(-) + +--- a/fs/ext4/mballoc.c ++++ b/fs/ext4/mballoc.c +@@ -974,8 +974,6 @@ static inline int should_optimize_scan(s + return 0; + if (ac->ac_criteria >= 2) + return 0; +- if (!ext4_test_inode_flag(ac->ac_inode, EXT4_INODE_EXTENTS)) +- return 0; + return 1; + } + diff --git a/queue-6.1/fbdev-of_display_timing-fix-device-node-reference-le.patch b/queue-6.1/fbdev-of_display_timing-fix-device-node-reference-le.patch deleted file mode 100644 index 95f0dba183..0000000000 --- a/queue-6.1/fbdev-of_display_timing-fix-device-node-reference-le.patch +++ /dev/null @@ -1,56 +0,0 @@ -From 9d7d9d4aaac187f5e607e10813f6eebe16af4699 Mon Sep 17 00:00:00 2001 -From: Sasha Levin -Date: Sat, 31 Jan 2026 20:48:33 +0800 -Subject: fbdev: of_display_timing: Fix device node reference leak in - of_get_display_timings() - -From: Felix Gu - -[ Upstream commit c39ee2d264f98efa14aa46c9942114cb03c7baa6 ] - -Use for_each_child_of_node_scoped instead of for_each_child_of_node -to ensure automatic of_node_put on early exit paths, preventing -device node reference leak. - -Fixes: cc3f414cf2e4 ("video: add of helper for display timings/videomode") -Signed-off-by: Felix Gu -Signed-off-by: Helge Deller -Signed-off-by: Sasha Levin ---- - drivers/video/of_display_timing.c | 6 +++--- - 1 file changed, 3 insertions(+), 3 deletions(-) - -diff --git a/drivers/video/of_display_timing.c b/drivers/video/of_display_timing.c -index bebd371c6b93e..a4cd446ac5a59 100644 ---- a/drivers/video/of_display_timing.c -+++ b/drivers/video/of_display_timing.c -@@ -195,7 +195,7 @@ struct display_timings *of_get_display_timings(const struct device_node *np) - disp->num_timings = 0; - disp->native_mode = 0; - -- for_each_child_of_node(timings_np, entry) { -+ for_each_child_of_node_scoped(timings_np, child) { - struct display_timing *dt; - int r; - -@@ -206,7 +206,7 @@ struct display_timings *of_get_display_timings(const struct device_node *np) - goto timingfail; - } - -- r = of_parse_display_timing(entry, dt); -+ r = of_parse_display_timing(child, dt); - if (r) { - /* - * to not encourage wrong devicetrees, fail in case of -@@ -218,7 +218,7 @@ struct display_timings *of_get_display_timings(const struct device_node *np) - goto timingfail; - } - -- if (native_mode == entry) -+ if (native_mode == child) - disp->native_mode = disp->num_timings; - - disp->timings[disp->num_timings] = dt; --- -2.51.0 - diff --git a/queue-6.1/mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch b/queue-6.1/mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch new file mode 100644 index 0000000000..870ae4d703 --- /dev/null +++ b/queue-6.1/mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch @@ -0,0 +1,103 @@ +From 30bfc2d6a1132a89a5f1c3b96c59cf3e4d076ea3 Mon Sep 17 00:00:00 2001 +From: Yao Zi +Date: Thu, 5 Feb 2026 15:56:44 +0000 +Subject: MIPS: Work around LLVM bug when gp is used as global register variable + +From: Yao Zi + +commit 30bfc2d6a1132a89a5f1c3b96c59cf3e4d076ea3 upstream. + +On MIPS, __current_thread_info is defined as global register variable +locating in $gp, and is simply assigned with new address during kernel +relocation. + +This however is broken with LLVM, which always restores $gp if it finds +$gp is clobbered in any form, including when intentionally through a +global register variable. This is against GCC's documentation[1], which +requires a callee-saved register used as global register variable not to +be restored if it's clobbered. + +As a result, $gp will continue to point to the unrelocated kernel after +the epilog of relocate_kernel(), leading to an early crash in init_idle, + +[ 0.000000] CPU 0 Unable to handle kernel paging request at virtual address 0000000000000000, epc == ffffffff81afada8, ra == ffffffff81afad90 +[ 0.000000] Oops[#1]: +[ 0.000000] CPU: 0 UID: 0 PID: 0 Comm: swapper Tainted: G W 6.19.0-rc5-00262-gd3eeb99bbc99-dirty #188 VOLUNTARY +[ 0.000000] Tainted: [W]=WARN +[ 0.000000] Hardware name: loongson,loongson64v-4core-virtio +[ 0.000000] $ 0 : 0000000000000000 0000000000000000 0000000000000001 0000000000000000 +[ 0.000000] $ 4 : ffffffff80b80ec0 ffffffff80b53d48 0000000000000000 00000000000f4240 +[ 0.000000] $ 8 : 0000000000000100 ffffffff81d82f80 ffffffff81d82f80 0000000000000001 +[ 0.000000] $12 : 0000000000000000 ffffffff81776f58 00000000000005da 0000000000000002 +[ 0.000000] $16 : ffffffff80b80e40 0000000000000000 ffffffff80b81614 9800000005dfbe80 +[ 0.000000] $20 : 00000000540000e0 ffffffff81980000 0000000000000000 ffffffff80f81c80 +[ 0.000000] $24 : 0000000000000a26 ffffffff8114fb90 +[ 0.000000] $28 : ffffffff80b50000 ffffffff80b53d40 0000000000000000 ffffffff81afad90 +[ 0.000000] Hi : 0000000000000000 +[ 0.000000] Lo : 0000000000000000 +[ 0.000000] epc : ffffffff81afada8 init_idle+0x130/0x270 +[ 0.000000] ra : ffffffff81afad90 init_idle+0x118/0x270 +[ 0.000000] Status: 540000e2 KX SX UX KERNEL EXL +[ 0.000000] Cause : 00000008 (ExcCode 02) +[ 0.000000] BadVA : 0000000000000000 +[ 0.000000] PrId : 00006305 (ICT Loongson-3) +[ 0.000000] Process swapper (pid: 0, threadinfo=(____ptrval____), task=(____ptrval____), tls=0000000000000000) +[ 0.000000] Stack : 9800000005dfbf00 ffffffff8178e950 0000000000000000 0000000000000000 +[ 0.000000] 0000000000000000 ffffffff81970000 000000000000003f ffffffff810a6528 +[ 0.000000] 0000000000000001 9800000005dfbe80 9800000005dfbf00 ffffffff81980000 +[ 0.000000] ffffffff810a6450 ffffffff81afb6c0 0000000000000000 ffffffff810a2258 +[ 0.000000] ffffffff81d82ec8 ffffffff8198d010 ffffffff81b67e80 ffffffff8197dd98 +[ 0.000000] ffffffff81d81c80 ffffffff81930000 0000000000000040 0000000000000000 +[ 0.000000] 0000000000000000 0000000000000000 0000000000000000 0000000000000000 +[ 0.000000] 0000000000000000 000000000000009e ffffffff9fc01000 0000000000000000 +[ 0.000000] 0000000000000000 0000000000000000 0000000000000000 0000000000000000 +[ 0.000000] 0000000000000000 ffffffff81ae86dc ffffffff81b3c741 0000000000000002 +[ 0.000000] ... +[ 0.000000] Call Trace: +[ 0.000000] [] init_idle+0x130/0x270 +[ 0.000000] [] sched_init+0x5c8/0x6c0 +[ 0.000000] [] start_kernel+0x27c/0x7a8 + +This bug has been reported to LLVM[2] and affects version from (at +least) 18 to 21. Let's work around this by using inline assembly to +assign $gp before a fix is widely available. + +Cc: stable@vger.kernel.org +Link: https://gcc.gnu.org/onlinedocs/gcc-15.2.0/gcc/Global-Register-Variables.html # [1] +Link: https://github.com/llvm/llvm-project/issues/176546 # [2] +Signed-off-by: Yao Zi +Acked-by: Nathan Chancellor +Signed-off-by: Thomas Bogendoerfer +Signed-off-by: Greg Kroah-Hartman +--- + arch/mips/kernel/relocate.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/arch/mips/kernel/relocate.c b/arch/mips/kernel/relocate.c +index 7f1c136ad850..59833210542f 100644 +--- a/arch/mips/kernel/relocate.c ++++ b/arch/mips/kernel/relocate.c +@@ -420,7 +420,20 @@ void *__init relocate_kernel(void) + goto out; + + /* The current thread is now within the relocated image */ ++#ifndef CONFIG_CC_IS_CLANG + __current_thread_info = RELOCATED(&init_thread_union); ++#else ++ /* ++ * LLVM may wrongly restore $gp ($28) in epilog even if it's ++ * intentionally modified. Work around this by using inline ++ * assembly to assign $gp. $gp couldn't be listed as output or ++ * clobber, or LLVM will still restore its original value. ++ * See also LLVM upstream issue ++ * https://github.com/llvm/llvm-project/issues/176546 ++ */ ++ asm volatile("move $28, %0" : : ++ "r" (RELOCATED(&init_thread_union))); ++#endif + + /* Return the new kernel's entry point */ + kernel_entry = RELOCATED(start_kernel); +-- +2.53.0 + diff --git a/queue-6.1/series b/queue-6.1/series index 806c2bc496..d1ec1bc161 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -167,7 +167,14 @@ nvdimm-virtio_pmem-serialize-flush-requests.patch fs-nfs-fix-readdir-slow-start-regression.patch tracing-properly-process-error-handling-in-event_his.patch tracing-remove-duplicate-enable_event_str-and-disabl.patch -fbdev-of_display_timing-fix-device-node-reference-le.patch +mips-work-around-llvm-bug-when-gp-is-used-as-global-register-variable.patch +ext4-don-t-cache-extent-during-splitting-extent.patch +ext4-fix-memory-leak-in-ext4_ext_shift_extents.patch +ext4-use-optimized-mballoc-scanning-regardless-of-inode-format.patch +ata-pata_ftide010-fix-some-dma-timings.patch +ata-libata-scsi-refactor-ata_scsi_translate.patch +sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch +sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch fbdev-au1200fb-fix-a-memory-leak-in-au1200fb_drv_pro.patch clk-qcom-rcg2-compute-2d-using-duty-fraction-directl.patch clk-meson-gxbb-limit-the-hdmi-pll-od-to-4-on-gxl-gxm.patch diff --git a/queue-6.1/sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch b/queue-6.1/sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch new file mode 100644 index 0000000000..1758317294 --- /dev/null +++ b/queue-6.1/sunrpc-auth_gss-fix-memory-leaks-in-xdr-decoding-error-paths.patch @@ -0,0 +1,222 @@ +From 3e6397b056335cc56ef0e9da36c95946a19f5118 Mon Sep 17 00:00:00 2001 +From: Chuck Lever +Date: Fri, 26 Dec 2025 10:15:32 -0500 +Subject: SUNRPC: auth_gss: fix memory leaks in XDR decoding error paths + +From: Chuck Lever + +commit 3e6397b056335cc56ef0e9da36c95946a19f5118 upstream. + +The gssx_dec_ctx(), gssx_dec_status(), and gssx_dec_name() +functions allocate memory via gssx_dec_buffer(), which calls +kmemdup(). When a subsequent decode operation fails, these +functions return immediately without freeing previously +allocated buffers, causing memory leaks. + +The leak in gssx_dec_ctx() is particularly relevant because +the caller (gssp_accept_sec_context_upcall) initializes several +buffer length fields to non-zero values, resulting in memory +allocation: + + struct gssx_ctx rctxh = { + .exported_context_token.len = GSSX_max_output_handle_sz, + .mech.len = GSS_OID_MAX_LEN, + .src_name.display_name.len = GSSX_max_princ_sz, + .targ_name.display_name.len = GSSX_max_princ_sz + }; + +If, for example, gssx_dec_name() succeeds for src_name but +fails for targ_name, the memory allocated for +exported_context_token, mech, and src_name.display_name +remains unreferenced and cannot be reclaimed. + +Add error handling with goto-based cleanup to free any +previously allocated buffers before returning an error. + +Reported-by: Xingjing Deng +Closes: https://lore.kernel.org/linux-nfs/CAK+ZN9qttsFDu6h1FoqGadXjMx1QXqPMoYQ=6O9RY4SxVTvKng@mail.gmail.com/ +Fixes: 1d658336b05f ("SUNRPC: Add RPC based upcall mechanism for RPCGSS auth") +Cc: stable@vger.kernel.org +Reviewed-by: Jeff Layton +Signed-off-by: Chuck Lever +Signed-off-by: Greg Kroah-Hartman +--- + net/sunrpc/auth_gss/gss_rpc_xdr.c | 82 +++++++++++++++++++++++++++++--------- + 1 file changed, 64 insertions(+), 18 deletions(-) + +--- a/net/sunrpc/auth_gss/gss_rpc_xdr.c ++++ b/net/sunrpc/auth_gss/gss_rpc_xdr.c +@@ -320,29 +320,47 @@ static int gssx_dec_status(struct xdr_st + + /* status->minor_status */ + p = xdr_inline_decode(xdr, 8); +- if (unlikely(p == NULL)) +- return -ENOSPC; ++ if (unlikely(p == NULL)) { ++ err = -ENOSPC; ++ goto out_free_mech; ++ } + p = xdr_decode_hyper(p, &status->minor_status); + + /* status->major_status_string */ + err = gssx_dec_buffer(xdr, &status->major_status_string); + if (err) +- return err; ++ goto out_free_mech; + + /* status->minor_status_string */ + err = gssx_dec_buffer(xdr, &status->minor_status_string); + if (err) +- return err; ++ goto out_free_major_status_string; + + /* status->server_ctx */ + err = gssx_dec_buffer(xdr, &status->server_ctx); + if (err) +- return err; ++ goto out_free_minor_status_string; + + /* we assume we have no options for now, so simply consume them */ + /* status->options */ + err = dummy_dec_opt_array(xdr, &status->options); ++ if (err) ++ goto out_free_server_ctx; + ++ return 0; ++ ++out_free_server_ctx: ++ kfree(status->server_ctx.data); ++ status->server_ctx.data = NULL; ++out_free_minor_status_string: ++ kfree(status->minor_status_string.data); ++ status->minor_status_string.data = NULL; ++out_free_major_status_string: ++ kfree(status->major_status_string.data); ++ status->major_status_string.data = NULL; ++out_free_mech: ++ kfree(status->mech.data); ++ status->mech.data = NULL; + return err; + } + +@@ -505,28 +523,35 @@ static int gssx_dec_name(struct xdr_stre + /* name->name_type */ + err = gssx_dec_buffer(xdr, &dummy_netobj); + if (err) +- return err; ++ goto out_free_display_name; + + /* name->exported_name */ + err = gssx_dec_buffer(xdr, &dummy_netobj); + if (err) +- return err; ++ goto out_free_display_name; + + /* name->exported_composite_name */ + err = gssx_dec_buffer(xdr, &dummy_netobj); + if (err) +- return err; ++ goto out_free_display_name; + + /* we assume we have no attributes for now, so simply consume them */ + /* name->name_attributes */ + err = dummy_dec_nameattr_array(xdr, &dummy_name_attr_array); + if (err) +- return err; ++ goto out_free_display_name; + + /* we assume we have no options for now, so simply consume them */ + /* name->extensions */ + err = dummy_dec_opt_array(xdr, &dummy_option_array); ++ if (err) ++ goto out_free_display_name; + ++ return 0; ++ ++out_free_display_name: ++ kfree(name->display_name.data); ++ name->display_name.data = NULL; + return err; + } + +@@ -649,32 +674,34 @@ static int gssx_dec_ctx(struct xdr_strea + /* ctx->state */ + err = gssx_dec_buffer(xdr, &ctx->state); + if (err) +- return err; ++ goto out_free_exported_context_token; + + /* ctx->need_release */ + err = gssx_dec_bool(xdr, &ctx->need_release); + if (err) +- return err; ++ goto out_free_state; + + /* ctx->mech */ + err = gssx_dec_buffer(xdr, &ctx->mech); + if (err) +- return err; ++ goto out_free_state; + + /* ctx->src_name */ + err = gssx_dec_name(xdr, &ctx->src_name); + if (err) +- return err; ++ goto out_free_mech; + + /* ctx->targ_name */ + err = gssx_dec_name(xdr, &ctx->targ_name); + if (err) +- return err; ++ goto out_free_src_name; + + /* ctx->lifetime */ + p = xdr_inline_decode(xdr, 8+8); +- if (unlikely(p == NULL)) +- return -ENOSPC; ++ if (unlikely(p == NULL)) { ++ err = -ENOSPC; ++ goto out_free_targ_name; ++ } + p = xdr_decode_hyper(p, &ctx->lifetime); + + /* ctx->ctx_flags */ +@@ -683,17 +710,36 @@ static int gssx_dec_ctx(struct xdr_strea + /* ctx->locally_initiated */ + err = gssx_dec_bool(xdr, &ctx->locally_initiated); + if (err) +- return err; ++ goto out_free_targ_name; + + /* ctx->open */ + err = gssx_dec_bool(xdr, &ctx->open); + if (err) +- return err; ++ goto out_free_targ_name; + + /* we assume we have no options for now, so simply consume them */ + /* ctx->options */ + err = dummy_dec_opt_array(xdr, &ctx->options); ++ if (err) ++ goto out_free_targ_name; ++ ++ return 0; + ++out_free_targ_name: ++ kfree(ctx->targ_name.display_name.data); ++ ctx->targ_name.display_name.data = NULL; ++out_free_src_name: ++ kfree(ctx->src_name.display_name.data); ++ ctx->src_name.display_name.data = NULL; ++out_free_mech: ++ kfree(ctx->mech.data); ++ ctx->mech.data = NULL; ++out_free_state: ++ kfree(ctx->state.data); ++ ctx->state.data = NULL; ++out_free_exported_context_token: ++ kfree(ctx->exported_context_token.data); ++ ctx->exported_context_token.data = NULL; + return err; + } + diff --git a/queue-6.1/sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch b/queue-6.1/sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch new file mode 100644 index 0000000000..efb9416c69 --- /dev/null +++ b/queue-6.1/sunrpc-fix-gss_auth-kref-leak-in-gss_alloc_msg-error-path.patch @@ -0,0 +1,51 @@ +From dd2fdc3504592d85e549c523b054898a036a6afe Mon Sep 17 00:00:00 2001 +From: Daniel Hodges +Date: Fri, 6 Feb 2026 15:41:46 -0500 +Subject: SUNRPC: fix gss_auth kref leak in gss_alloc_msg error path + +From: Daniel Hodges + +commit dd2fdc3504592d85e549c523b054898a036a6afe upstream. + +Commit 5940d1cf9f42 ("SUNRPC: Rebalance a kref in auth_gss.c") added +a kref_get(&gss_auth->kref) call to balance the gss_put_auth() done +in gss_release_msg(), but forgot to add a corresponding kref_put() +on the error path when kstrdup_const() fails. + +If service_name is non-NULL and kstrdup_const() fails, the function +jumps to err_put_pipe_version which calls put_pipe_version() and +kfree(gss_msg), but never releases the gss_auth reference. This leads +to a kref leak where the gss_auth structure is never freed. + +Add a forward declaration for gss_free_callback() and call kref_put() +in the err_put_pipe_version error path to properly release the +reference taken earlier. + +Fixes: 5940d1cf9f42 ("SUNRPC: Rebalance a kref in auth_gss.c") +Cc: stable@vger.kernel.org +Signed-off-by: Daniel Hodges +Signed-off-by: Anna Schumaker +Signed-off-by: Greg Kroah-Hartman +--- + net/sunrpc/auth_gss/auth_gss.c | 3 +++ + 1 file changed, 3 insertions(+) + +--- a/net/sunrpc/auth_gss/auth_gss.c ++++ b/net/sunrpc/auth_gss/auth_gss.c +@@ -39,6 +39,8 @@ static const struct rpc_authops authgss_ + static const struct rpc_credops gss_credops; + static const struct rpc_credops gss_nullops; + ++static void gss_free_callback(struct kref *kref); ++ + #define GSS_RETRY_EXPIRED 5 + static unsigned int gss_expired_cred_retry_delay = GSS_RETRY_EXPIRED; + +@@ -535,6 +537,7 @@ gss_alloc_msg(struct gss_auth *gss_auth, + } + return gss_msg; + err_put_pipe_version: ++ kref_put(&gss_auth->kref, gss_free_callback); + put_pipe_version(gss_auth->net); + err_free_msg: + kfree(gss_msg);