From: Greg Kroah-Hartman Date: Thu, 11 Oct 2018 09:42:27 +0000 (+0200) Subject: 4.18-stable patches X-Git-Tag: v3.18.124~22 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=ca50b3c7d02ea67e7ba2736bd92f29bc8b28ad3b;p=thirdparty%2Fkernel%2Fstable-queue.git 4.18-stable patches added patches: powerpc-avoid-code-patching-freed-init-sections.patch powerpc-lib-fix-book3s-32-boot-failure-due-to-code-patching.patch --- diff --git a/queue-4.18/powerpc-avoid-code-patching-freed-init-sections.patch b/queue-4.18/powerpc-avoid-code-patching-freed-init-sections.patch new file mode 100644 index 00000000000..e3be35744d2 --- /dev/null +++ b/queue-4.18/powerpc-avoid-code-patching-freed-init-sections.patch @@ -0,0 +1,87 @@ +From 51c3c62b58b357e8d35e4cc32f7b4ec907426fe3 Mon Sep 17 00:00:00 2001 +From: Michael Neuling +Date: Fri, 14 Sep 2018 11:14:11 +1000 +Subject: powerpc: Avoid code patching freed init sections + +From: Michael Neuling + +commit 51c3c62b58b357e8d35e4cc32f7b4ec907426fe3 upstream. + +This stops us from doing code patching in init sections after they've +been freed. + +In this chain: + kvm_guest_init() -> + kvm_use_magic_page() -> + fault_in_pages_readable() -> + __get_user() -> + __get_user_nocheck() -> + barrier_nospec(); + +We have a code patching location at barrier_nospec() and +kvm_guest_init() is an init function. This whole chain gets inlined, +so when we free the init section (hence kvm_guest_init()), this code +goes away and hence should no longer be patched. + +We seen this as userspace memory corruption when using a memory +checker while doing partition migration testing on powervm (this +starts the code patching post migration via +/sys/kernel/mobility/migration). In theory, it could also happen when +using /sys/kernel/debug/powerpc/barrier_nospec. + +Cc: stable@vger.kernel.org # 4.13+ +Signed-off-by: Michael Neuling +Reviewed-by: Nicholas Piggin +Reviewed-by: Christophe Leroy +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/include/asm/setup.h | 1 + + arch/powerpc/lib/code-patching.c | 6 ++++++ + arch/powerpc/mm/mem.c | 2 ++ + 3 files changed, 9 insertions(+) + +--- a/arch/powerpc/include/asm/setup.h ++++ b/arch/powerpc/include/asm/setup.h +@@ -9,6 +9,7 @@ extern void ppc_printk_progress(char *s, + + extern unsigned int rtas_data; + extern unsigned long long memory_limit; ++extern bool init_mem_is_free; + extern unsigned long klimit; + extern void *zalloc_maybe_bootmem(size_t size, gfp_t mask); + +--- a/arch/powerpc/lib/code-patching.c ++++ b/arch/powerpc/lib/code-patching.c +@@ -28,6 +28,12 @@ static int __patch_instruction(unsigned + { + int err; + ++ /* Make sure we aren't patching a freed init section */ ++ if (init_mem_is_free && init_section_contains(exec_addr, 4)) { ++ pr_debug("Skipping init section patching addr: 0x%px\n", exec_addr); ++ return 0; ++ } ++ + __put_user_size(instr, patch_addr, 4, err); + if (err) + return err; +--- a/arch/powerpc/mm/mem.c ++++ b/arch/powerpc/mm/mem.c +@@ -63,6 +63,7 @@ + #endif + + unsigned long long memory_limit; ++bool init_mem_is_free; + + #ifdef CONFIG_HIGHMEM + pte_t *kmap_pte; +@@ -396,6 +397,7 @@ void free_initmem(void) + { + ppc_md.progress = ppc_printk_progress; + mark_initmem_nx(); ++ init_mem_is_free = true; + free_initmem_default(POISON_FREE_INITMEM); + } + diff --git a/queue-4.18/powerpc-lib-fix-book3s-32-boot-failure-due-to-code-patching.patch b/queue-4.18/powerpc-lib-fix-book3s-32-boot-failure-due-to-code-patching.patch new file mode 100644 index 00000000000..3c0d8181f2d --- /dev/null +++ b/queue-4.18/powerpc-lib-fix-book3s-32-boot-failure-due-to-code-patching.patch @@ -0,0 +1,79 @@ +From b45ba4a51cde29b2939365ef0c07ad34c8321789 Mon Sep 17 00:00:00 2001 +From: Christophe Leroy +Date: Mon, 1 Oct 2018 12:21:10 +0000 +Subject: powerpc/lib: fix book3s/32 boot failure due to code patching + +From: Christophe Leroy + +commit b45ba4a51cde29b2939365ef0c07ad34c8321789 upstream. + +Commit 51c3c62b58b3 ("powerpc: Avoid code patching freed init +sections") accesses 'init_mem_is_free' flag too early, before the +kernel is relocated. This provokes early boot failure (before the +console is active). + +As it is not necessary to do this verification that early, this +patch moves the test into patch_instruction() instead of +__patch_instruction(). + +This modification also has the advantage of avoiding unnecessary +remappings. + +Fixes: 51c3c62b58b3 ("powerpc: Avoid code patching freed init sections") +Cc: stable@vger.kernel.org # 4.13+ +Signed-off-by: Christophe Leroy +Signed-off-by: Michael Ellerman +Signed-off-by: Greg Kroah-Hartman + +--- + arch/powerpc/lib/code-patching.c | 20 ++++++++++++-------- + 1 file changed, 12 insertions(+), 8 deletions(-) + +--- a/arch/powerpc/lib/code-patching.c ++++ b/arch/powerpc/lib/code-patching.c +@@ -28,12 +28,6 @@ static int __patch_instruction(unsigned + { + int err; + +- /* Make sure we aren't patching a freed init section */ +- if (init_mem_is_free && init_section_contains(exec_addr, 4)) { +- pr_debug("Skipping init section patching addr: 0x%px\n", exec_addr); +- return 0; +- } +- + __put_user_size(instr, patch_addr, 4, err); + if (err) + return err; +@@ -148,7 +142,7 @@ static inline int unmap_patch_area(unsig + return 0; + } + +-int patch_instruction(unsigned int *addr, unsigned int instr) ++static int do_patch_instruction(unsigned int *addr, unsigned int instr) + { + int err; + unsigned int *patch_addr = NULL; +@@ -188,12 +182,22 @@ out: + } + #else /* !CONFIG_STRICT_KERNEL_RWX */ + +-int patch_instruction(unsigned int *addr, unsigned int instr) ++static int do_patch_instruction(unsigned int *addr, unsigned int instr) + { + return raw_patch_instruction(addr, instr); + } + + #endif /* CONFIG_STRICT_KERNEL_RWX */ ++ ++int patch_instruction(unsigned int *addr, unsigned int instr) ++{ ++ /* Make sure we aren't patching a freed init section */ ++ if (init_mem_is_free && init_section_contains(addr, 4)) { ++ pr_debug("Skipping init section patching addr: 0x%px\n", addr); ++ return 0; ++ } ++ return do_patch_instruction(addr, instr); ++} + NOKPROBE_SYMBOL(patch_instruction); + + int patch_branch(unsigned int *addr, unsigned long target, int flags) diff --git a/queue-4.18/series b/queue-4.18/series index ce280073a67..81bbb68839f 100644 --- a/queue-4.18/series +++ b/queue-4.18/series @@ -33,3 +33,5 @@ usb-serial-option-add-two-endpoints-device-id-flag.patch usb-cdc_acm-do-not-leak-urb-buffers.patch tty-drop-tty-count-on-tty_reopen-failure.patch of-unittest-disable-interrupt-node-tests-for-old-world-mac-systems.patch +powerpc-avoid-code-patching-freed-init-sections.patch +powerpc-lib-fix-book3s-32-boot-failure-due-to-code-patching.patch