From mboxrd@z Thu Jan 1 00:00:00 1970 From: lauraa@codeaurora.org (Laura Abbott) Date: Tue, 24 Feb 2015 15:58:57 -0800 Subject: [PATCH] arm64: Fix text patching logic when using fixmap In-Reply-To: <1424795421-26630-1-git-send-email-marc.zyngier@arm.com> References: <1424795421-26630-1-git-send-email-marc.zyngier@arm.com> Message-ID: <54ED1041.2090708@codeaurora.org> To: linux-arm-kernel@lists.infradead.org List-Id: linux-arm-kernel.lists.infradead.org On 2/24/2015 8:30 AM, Marc Zyngier wrote: > Patch 2f896d586610 ("arm64: use fixmap for text patching") changed > the way we patch the kernel text, using a fixmap when the kernel or > modules are flagged as read only. > > Unfortunately, a flaw in the logic makes it fall over when patching > modules without CONFIG_DEBUG_SET_MODULE_RONX enabled: > > [...] > [ 32.032636] Call trace: > [ 32.032716] [] __copy_to_user+0x2c/0x60 > [ 32.032837] [] __aarch64_insn_write+0x94/0xf8 > [ 32.033027] [] aarch64_insn_patch_text_nosync+0x18/0x58 > [ 32.033200] [] ftrace_modify_code+0x58/0x84 > [ 32.033363] [] ftrace_make_nop+0x3c/0x58 > [ 32.033532] [] ftrace_process_locs+0x3d0/0x5c8 > [ 32.033709] [] ftrace_module_init+0x28/0x34 > [ 32.033882] [] load_module+0xbb8/0xfc4 > [ 32.034044] [] SyS_finit_module+0x94/0xc4 > [...] > > This is triggered by the use of virt_to_page() on a module address, > which ends to pointing to Nowhereland if you're lucky, or corrupt > your precious data if not. > > This patch fixes the logic by mimicking what is done on arm: > - If we're patching a module and CONFIG_DEBUG_SET_MODULE_RONX is set, > use vmalloc_to_page(). > - If we're patching the kernel and CONFIG_DEBUG_RODATA is set, > use virt_to_page(). > - Otherwise, use the provided address, as we can write to it directly. > > Tested on 4.0-rc1 as a KVM guest. > > Reported-by: Richard W.M. Jones > Cc: Kees Cook > Cc: Mark Rutland > Cc: Laura Abbott > Cc: Catalin Marinas > Cc: Will Deacon > Signed-off-by: Marc Zyngier > --- > arch/arm64/kernel/insn.c | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > diff --git a/arch/arm64/kernel/insn.c b/arch/arm64/kernel/insn.c > index 27d4864..c8eca88 100644 > --- a/arch/arm64/kernel/insn.c > +++ b/arch/arm64/kernel/insn.c > @@ -87,8 +87,10 @@ static void __kprobes *patch_map(void *addr, int fixmap) > > if (module && IS_ENABLED(CONFIG_DEBUG_SET_MODULE_RONX)) > page = vmalloc_to_page(addr); > - else > + else if (!module && IS_ENABLED(CONFIG_DEBUG_RODATA)) > page = virt_to_page(addr); > + else > + return addr; > > BUG_ON(!page); > set_fixmap(fixmap, page_to_phys(page)); > Looks like I dropped this incorrectly between v6 and v7. Acked-by: Laura Abbott -- Qualcomm Innovation Center, Inc. Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project