From: Alexandre Ghiti alexghiti@rivosinc.com
mainline inclusion from mainline-v6.8-rc1 commit 420370f3ae3d3b883813fd3051a38805160b2b9f category: bugfix bugzilla: https://gitee.com/src-openeuler/kernel/issues/I9Q9F3 CVE: CVE-2023-52677
Reference: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?i...
--------------------------------
Otherwise we fall through to vmalloc_to_page() which panics since the address does not lie in the vmalloc region.
Fixes: 043cb41a85de ("riscv: introduce interfaces to patch kernel code") Signed-off-by: Alexandre Ghiti alexghiti@rivosinc.com Reviewed-by: Charlie Jenkins charlie@rivosinc.com Link: https://lore.kernel.org/r/20231214091926.203439-1-alexghiti@rivosinc.com Signed-off-by: Palmer Dabbelt palmer@rivosinc.com Conflicts: arch/riscv/include/asm/sections.h arch/riscv/kernel/patch.c arch/riscv/kernel/vmlinux.lds.S [modify context] Signed-off-by: Yuntao Liu liuyuntao12@huawei.com --- arch/riscv/include/asm/sections.h | 1 + arch/riscv/kernel/patch.c | 11 ++++++++++- arch/riscv/kernel/vmlinux.lds.S | 3 +++ 3 files changed, 14 insertions(+), 1 deletion(-)
diff --git a/arch/riscv/include/asm/sections.h b/arch/riscv/include/asm/sections.h index 3a9971b1210f..bc28170ad186 100644 --- a/arch/riscv/include/asm/sections.h +++ b/arch/riscv/include/asm/sections.h @@ -9,5 +9,6 @@
extern char _start[]; extern char _start_kernel[]; +extern char __exittext_begin[], __exittext_end[];
#endif /* __ASM_SECTIONS_H */ diff --git a/arch/riscv/kernel/patch.c b/arch/riscv/kernel/patch.c index c3fced410e74..b0e0780f3cca 100644 --- a/arch/riscv/kernel/patch.c +++ b/arch/riscv/kernel/patch.c @@ -13,6 +13,7 @@ #include <asm/fixmap.h> #include <asm/ftrace.h> #include <asm/patch.h> +#include <asm/sections.h>
struct patch_insn { void *addr; @@ -23,12 +24,20 @@ struct patch_insn { int riscv_patch_in_stop_machine = false;
#ifdef CONFIG_MMU + +static inline bool is_kernel_exittext(uintptr_t addr) +{ + return system_state < SYSTEM_RUNNING && + addr >= (uintptr_t)__exittext_begin && + addr < (uintptr_t)__exittext_end; +} + static void *patch_map(void *addr, int fixmap) { uintptr_t uintaddr = (uintptr_t) addr; struct page *page;
- if (core_kernel_text(uintaddr)) + if (core_kernel_text(uintaddr) || is_kernel_exittext(uintaddr)) page = phys_to_page(__pa_symbol(addr)); else if (IS_ENABLED(CONFIG_STRICT_MODULE_RWX)) page = vmalloc_to_page(addr); diff --git a/arch/riscv/kernel/vmlinux.lds.S b/arch/riscv/kernel/vmlinux.lds.S index 3ffbd6cbdb86..e1c52b1c6f38 100644 --- a/arch/riscv/kernel/vmlinux.lds.S +++ b/arch/riscv/kernel/vmlinux.lds.S @@ -43,10 +43,13 @@ SECTIONS __soc_builtin_dtb_table_end = .; } /* we have to discard exit text and such at runtime, not link time */ + __exittext_begin = .; .exit.text : { EXIT_TEXT } + __exittext_end = .; + .exit.data : { EXIT_DATA