FAILED: patch "[PATCH] powerpc/kexec_file: Prevent kexec range truncation" failed to apply to 6.1-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.1-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
To reproduce the conflict and resubmit, you may use the following commands:
git fetch https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/ linux-6.1.y
git checkout FETCH_HEAD
git cherry-pick -x fa40f9dbdd4af53e7445d9135b5b207eb8adf372
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2026090925-speech-sitting-aadd@gregkh' --subject-prefix 'PATCH 6.1.y' 'HEAD^..'
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From fa40f9dbdd4af53e7445d9135b5b207eb8adf372 Mon Sep 17 00:00:00 2001
From: Jinjie Ruan <[email protected]>
Date: Wed, 29 Jul 2026 09:29:48 +0800
Subject: [PATCH] powerpc/kexec_file: Prevent kexec range truncation
Sashiko AI review pointed out the following issue.
The __merge_memory_ranges() function incorrectly handles overlapping memory ranges when merging them. Although sort_memory_ranges() sorts all ranges by their start address in ascending order beforehand, the merge logic remains defective in two ways:
1. It compares the current range's start against the previous element (i-1) instead of the running target index (idx)
2. It unconditionally overwrites 'ranges[idx].end' with 'ranges[i].end'.
This logic flaw leads to critical memory truncation when a larger memory range completely subsumes subsequent smaller ranges.
For example, consider a sorted input array with three ranges:
Range A (idx=0): [0x1000 - 0x9000]
Range B (i=1): [0x2000 - 0x5000] (completely inside Range A)
Range C (i=2): [0x6000 - 0x8000] (completely inside Range A)
1. When i=1 (Range B):
ranges[1].start (0x2000) <= ranges[0].end + 1 (0x9001) is TRUE. The code executes: ranges[0].end = ranges[1].end, which erroneously shrinks Range A's end from 0x9000 down to 0x5000.
2. When i=2 (Range C):
ranges[2].start (0x6000) <= ranges[1].end + 1 (0x5001) is FALSE. The code falls into the else block, creating a broken new range.
As a result, valid memory fragments [0x5001 - 0x5fff] and [0x8001 - 0x9000] are completely lost from the kexec exclude lists, potentially allowing the crash kernel to overwrite active memory, causing data corruption or crashes.
Fix this by ensuring the start of the current range is compared against the end of the active merged range (idx), and use max() to safely prevent the outer boundary from being truncated.
arch/powerpc/kexec/ranges.c +5 -7
@@ -21,6 +21,7 @@#include <linux/of.h> #include <linux/slab.h> #include <linux/memblock.h> +#include <linux/minmax.h> #include <linux/crash_core.h> #include <asm/sections.h> #include <asm/kexec_ranges.h>
@@ -105,19 +106,16 @@ static void __merge_memory_ranges(struct crash_mem *mem_rngs)struct range *ranges;int i, idx; -if (!mem_rngs) +if (!mem_rngs || mem_rngs->nr_ranges <=1 )return ; idx =0 ; - ranges = &(mem_rngs->ranges[0 ]); + ranges = mem_rngs->ranges;for (i =1 ; i < mem_rngs->nr_ranges; i++) { -if (ranges[i].start <= (ranges[i-1 ].end +1 )) - ranges[idx].end = ranges[i].end; +if (ranges[i].start <= (ranges[idx].end +1 )) + ranges[idx].end =max (ranges[idx].end, ranges[i].end);else { idx++; -if (i == idx) -continue ; - ranges[idx] = ranges[i]; } }
Sasha Levin
maintainerPATCH 1/2 powerpc/kexec: move *_memory_ranges functions to ranges.c
From: Sourabh Jain <[email protected]>
[ Upstream commit f5f0da5a7b18fab383bac92044fd8f4f288c9d38 ]
Move the following functions form kexec/{file_load_64.c => ranges.c} and make them public so that components other than KEXEC_FILE can also use these functions.
1. get_exclude_memory_ranges
2. get_reserved_memory_ranges
3. get_crash_memory_ranges
4. get_usable_memory_ranges
Later in the series get_crash_memory_ranges function is utilized for in-kernel updates to kdump image during CPU/Memory hotplug or online/offline events for both kexec_load and kexec_file_load syscalls.
Since the above functions are moved to ranges.c, some of the helper functions in ranges.c are no longer required to be public. Mark them as static and removed them from kexec_ranges.h header file.
Finally, remove the CONFIG_KEXEC_FILE build dependency for range.c because it is required for other config, such as CONFIG_CRASH_DUMP.
No functional changes are intended.
[Stable dependency adaptation for fa40f9dbdd4af53e7445d9135b5b207eb8adf372:
Keep only the linux/memblock.h and linux/crash_core.h include additions in ranges.c. The target inserts linux/minmax.h between these headers; without them its header hunk conflicts, while its range-merging fix already merges cleanly with the stable implementation.
Drop the helper moves, visibility changes, and build-rule changes. This stable tree predates the KEXEC_FILE/CRASH_DUMP split and keeps crash_mem under CONFIG_KEXEC_FILE, so importing the broader refactor is unnecessary for this fix. Retain the existing functions and configuration dependencies. No functions or runtime behavior are added by this dependency.]
[ sashal: Reduced backport -- upstream f5f0da5a7b18f touches 4 file(s), this
backport carries 1. Not backported here:
arch/powerpc/include/asm/kexec_ranges.h arch/powerpc/kexec/file_load_64.c
arch/powerpc/kexec/Makefile
This note is generated from the file lists only; see the resolution record for the reasoning. ]
Stable-dep-of: fa40f9dbdd4a ("powerpc/kexec_file: Prevent kexec range truncation")
--- arch/powerpc/kexec/ranges.c | 2 ++ 1 file changed, 2 insertions(+)
arch/powerpc/kexec/ranges.c +2 -0
@@ -20,6 +20,8 @@#include <linux/kexec.h> #include <linux/of_device.h> #include <linux/slab.h> +#include <linux/memblock.h> +#include <linux/crash_core.h> #include <asm/sections.h> #include <asm/kexec_ranges.h>
Signature · 1 line
2.53.0
Sasha Levin
maintainerPATCH 2/2 powerpc/kexec_file: Prevent kexec range truncation
From: Jinjie Ruan <[email protected]>
[ Upstream commit fa40f9dbdd4af53e7445d9135b5b207eb8adf372 ]
Sashiko AI review pointed out the following issue.
The __merge_memory_ranges() function incorrectly handles overlapping memory ranges when merging them. Although sort_memory_ranges() sorts all ranges by their start address in ascending order beforehand, the merge logic remains defective in two ways:
1. It compares the current range's start against the previous element (i-1) instead of the running target index (idx)
2. It unconditionally overwrites 'ranges[idx].end' with 'ranges[i].end'.
This logic flaw leads to critical memory truncation when a larger memory range completely subsumes subsequent smaller ranges.
For example, consider a sorted input array with three ranges:
Range A (idx=0): [0x1000 - 0x9000]
Range B (i=1): [0x2000 - 0x5000] (completely inside Range A)
Range C (i=2): [0x6000 - 0x8000] (completely inside Range A)
1. When i=1 (Range B):
ranges[1].start (0x2000) <= ranges[0].end + 1 (0x9001) is TRUE. The code executes: ranges[0].end = ranges[1].end, which erroneously shrinks Range A's end from 0x9000 down to 0x5000.
2. When i=2 (Range C):
ranges[2].start (0x6000) <= ranges[1].end + 1 (0x5001) is FALSE. The code falls into the else block, creating a broken new range.
As a result, valid memory fragments [0x5001 - 0x5fff] and [0x8001 - 0x9000] are completely lost from the kexec exclude lists, potentially allowing the crash kernel to overwrite active memory, causing data corruption or crashes.
Fix this by ensuring the start of the current range is compared against the end of the active merged range (idx), and use max() to safely prevent the outer boundary from being truncated.
--- arch/powerpc/kexec/ranges.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
arch/powerpc/kexec/ranges.c +5 -7
@@ -21,6 +21,7 @@#include <linux/of_device.h> #include <linux/slab.h> #include <linux/memblock.h> +#include <linux/minmax.h> #include <linux/crash_core.h> #include <asm/sections.h> #include <asm/kexec_ranges.h>
@@ -103,19 +104,16 @@ static void __merge_memory_ranges(struct crash_mem *mem_rngs)struct crash_mem_range *ranges;int i, idx; -if (!mem_rngs) +if (!mem_rngs || mem_rngs->nr_ranges <=1 )return ; idx =0 ; - ranges = &(mem_rngs->ranges[0 ]); + ranges = mem_rngs->ranges;for (i =1 ; i < mem_rngs->nr_ranges; i++) { -if (ranges[i].start <= (ranges[i-1 ].end +1 )) - ranges[idx].end = ranges[i].end; +if (ranges[i].start <= (ranges[idx].end +1 )) + ranges[idx].end =max (ranges[idx].end, ranges[i].end);else { idx++; -if (i == idx) -continue ; - ranges[idx] = ranges[i]; } }
Signature · 1 line
2.53.0