FAILED: patch "[PATCH] arm64: map [_text, _stext) virtual address range" failed to apply to 6.6-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 6.6-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.6.y
git checkout FETCH_HEAD
git cherry-pick -x 5973a62efa34c80c9a4e5eac1fca6f6209b902af
# <resolve conflicts, build, test, etc.>
git commit -s
git send-email --to '<[email protected]>' --in-reply-to '2025101548-stiffly-eagle-d9a5@gregkh' --subject-prefix 'PATCH 6.6.y' HEAD^..
Possible dependencies:
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From 5973a62efa34c80c9a4e5eac1fca6f6209b902af Mon Sep 17 00:00:00 2001
From: Omar Sandoval <[email protected]>
Date: Fri, 19 Sep 2025 14:27:51 -0700
Subject: [PATCH] arm64: map [_text, _stext) virtual address range
non-executable+read-only
Since the referenced fixes commit, the kernel's .text section is only mapped starting from _stext; the region [_text, _stext) is omitted. As a result, other vmalloc/vmap allocations may use the virtual addresses nominally in the range [_text, _stext). This address reuse confuses multiple things:
1. crash_prepare_elf64_headers() sets up a segment in /proc/vmcore mapping the entire range [_text, _end) to [__pa_symbol(_text), __pa_symbol(_end)). Reading an address in [_text, _stext) from /proc/vmcore therefore gives the incorrect result.
2. Tools doing symbolization (either by reading /proc/kallsyms or based on the vmlinux ELF file) will incorrectly identify vmalloc/vmap allocations in [_text, _stext) as kernel symbols.
In practice, both of these issues affect the drgn debugger. Specifically, there were cases where the vmap IRQ stacks for some CPUs were allocated in [_text, _stext). As a result, drgn could not get the stack trace for a crash in an IRQ handler because the core dump contained invalid data for the IRQ stack address. The stack addresses were also symbolized as being in the _text symbol.
Fix this by bringing back the mapping of [_text, _stext), but now make it non-executable and read-only. This prevents other allocations from using it while still achieving the original goal of not mapping unpredictable data as executable. Other than the changed protection, this is effectively a revert of the fixes commit.
arch/arm64/kernel/pi/map_kernel.c +6 -0
@@ -78,6 +78,12 @@ static void __init map_kernel(u64 kaslr_offset, u64 va_offset, int root_level) twopass |= enable_scs; prot = twopass ? data_prot : text_prot; +/* +* [_stext, _text) isn't executed after boot and contains some +* non-executable, unpredictable data, so map it non-executable. +*/ +map_segment (init_pg_dir, &pgdp, va_offset, _text, _stext, data_prot, + false, root_level);map_segment (init_pg_dir, &pgdp, va_offset, _stext, _etext, prot, !twopass, root_level); map_segment(init_pg_dir, &pgdp, va_offset, __start_rodata,
arch/arm64/kernel/setup.c +2 -2
@@ -214,7 +214,7 @@ static void __init request_standard_resources(void)unsigned long i =0 ;size_t res_size; - kernel_code.start =__pa_symbol (_stext); + kernel_code.start =__pa_symbol (_text); kernel_code.end =__pa_symbol (__init_begin -1 ); kernel_data.start =__pa_symbol (_sdata); kernel_data.end =__pa_symbol (_end -1 );
@@ -280,7 +280,7 @@ u64 cpu_logical_map(unsigned int cpu) void __init __no_sanitize_address setup_arch(char **cmdline_p) { -setup_initial_init_mm (_stext, _etext, _edata, _end); +setup_initial_init_mm (_text, _etext, _edata, _end); *cmdline_p = boot_command_line;
arch/arm64/mm/init.c +1 -1
@@ -279,7 +279,7 @@ void __init arm64_memblock_init(void)* Register the kernel text, kernel data, initrd, and initial * pagetables with memblock. */ -memblock_reserve (__pa_symbol (_stext), _end - _stext); +memblock_reserve (__pa_symbol (_text), _end - _text);if (IS_ENABLED (CONFIG_BLK_DEV_INITRD ) && phys_initrd_size) {/* the generic initrd code expects virtual addresses */ initrd_start =__phys_to_virt (phys_initrd_start);
arch/arm64/mm/mmu.c +9 -5
@@ -965,8 +965,8 @@ void __init mark_linear_text_alias_ro(void)/* * Remove the write permissions from the linear alias of .text/.rodata */ -update_mapping_prot (__pa_symbol (_stext), (unsigned long )lm_alias (_stext), - (unsigned long )__init_begin - (unsigned long )_stext, +update_mapping_prot (__pa_symbol (_text), (unsigned long )lm_alias (_text), + (unsigned long )__init_begin - (unsigned long )_text,PAGE_KERNEL_RO ); }
@@ -1037,7 +1037,7 @@ static inline bool force_pte_mapping(void)static void __init map_mem (pgd_t *pgdp) {static const u64 direct_map_end =_PAGE_END (VA_BITS_MIN ); -phys_addr_t kernel_start =__pa_symbol (_stext); +phys_addr_t kernel_start =__pa_symbol (_text);phys_addr_t kernel_end =__pa_symbol (__init_begin);phys_addr_t start, end;phys_addr_t early_kfence_pool;
@@ -1086,7 +1086,7 @@ static void __init map_mem(pgd_t *pgdp) }/* -* Map the linear alias of the [_stext, __init_begin) interval +* Map the linear alias of the [_text, __init_begin) interval * as non-executable now, and remove the write permission in * mark_linear_text_alias_ro() below (which will be called after * alternative patching has completed). This makes the contents
@@ -1113,6 +1113,10 @@ void mark_rodata_ro(void)WRITE_ONCE (rodata_is_rw, false);update_mapping_prot (__pa_symbol (__start_rodata), (unsigned long )__start_rodata, section_size,PAGE_KERNEL_RO ); +/* mark the range between _text and _stext as read only. */ +update_mapping_prot (__pa_symbol (_text), (unsigned long )_text, + (unsigned long )_stext - (unsigned long )_text, +PAGE_KERNEL_RO ); } static void __init declare_vma(struct vm_struct *vma,
@@ -1183,7 +1187,7 @@ static void __init declare_kernel_vmas(void) {static struct vm_struct vmlinux_seg[KERNEL_SEGMENT_COUNT ]; -declare_vma (&vmlinux_seg[0 ], _stext, _etext,VM_NO_GUARD ); +declare_vma (&vmlinux_seg[0 ], _text, _etext,VM_NO_GUARD );declare_vma (&vmlinux_seg[1 ], __start_rodata, __inittext_begin,VM_NO_GUARD );declare_vma (&vmlinux_seg[2 ], __inittext_begin, __inittext_end,VM_NO_GUARD );declare_vma (&vmlinux_seg[3 ], __initdata_begin, __initdata_end,VM_NO_GUARD );