From: Nadav Amit <namit@vmware.com> To: Thomas Gleixner <tglx@linutronix.de> Cc: <linux-kernel@vger.kernel.org>, Ingo Molnar <mingo@redhat.com>, <x86@kernel.org>, Arnd Bergmann <arnd@arndb.de>, <linux-arch@vger.kernel.org>, Dave Hansen <dave.hansen@linux.intel.com>, Nadav Amit <nadav.amit@gmail.com>, Nadav Amit <namit@vmware.com>, Kees Cook <keescook@chromium.org>, Peter Zijlstra <peterz@infradead.org>, Dave Hansen <dave.hansen@intel.com> Subject: [PATCH v2 4/6] x86/alternatives: initializing temporary mm for patching Date: Sun, 2 Sep 2018 10:32:22 -0700 [thread overview] Message-ID: <20180902173224.30606-5-namit@vmware.com> (raw) In-Reply-To: <20180902173224.30606-1-namit@vmware.com> To prevent improper use of the PTEs that are used for text patching, we want to use a temporary mm struct. We initailize it by copying the init mm. The address that will be used for patching is taken from the lower area that is usually used for the task memory. Doing so prevents the need to frequently synchronize the temporary-mm (e.g., when BPF programs are installed), since different PGDs are used for the task memory. Finally, we randomize the address of the PTEs to harden against exploits that use these PTEs. Cc: Kees Cook <keescook@chromium.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Dave Hansen <dave.hansen@intel.com> Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org> Tested-by: Masami Hiramatsu <mhiramat@kernel.org> Suggested-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Nadav Amit <namit@vmware.com> --- arch/x86/include/asm/pgtable.h | 3 +++ arch/x86/include/asm/text-patching.h | 2 ++ arch/x86/mm/init_64.c | 29 ++++++++++++++++++++++++++++ init/main.c | 3 +++ 4 files changed, 37 insertions(+) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index e4ffa565a69f..3de9a1fb7a9a 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -1022,6 +1022,9 @@ static inline void __meminit init_trampoline_default(void) /* Default trampoline pgd value */ trampoline_pgd_entry = init_top_pgt[pgd_index(__PAGE_OFFSET)]; } + +void __init poking_init(void); + # ifdef CONFIG_RANDOMIZE_MEMORY void __meminit init_trampoline(void); # else diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h index e85ff65c43c3..ffe7902cc326 100644 --- a/arch/x86/include/asm/text-patching.h +++ b/arch/x86/include/asm/text-patching.h @@ -38,5 +38,7 @@ extern void *text_poke(void *addr, const void *opcode, size_t len); extern int poke_int3_handler(struct pt_regs *regs); extern void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler); extern int after_bootmem; +extern __ro_after_init struct mm_struct *poking_mm; +extern __ro_after_init unsigned long poking_addr; #endif /* _ASM_X86_TEXT_PATCHING_H */ diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index dd519f372169..db33a724a054 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -54,6 +54,7 @@ #include <asm/init.h> #include <asm/uv/uv.h> #include <asm/setup.h> +#include <asm/text-patching.h> #include "mm_internal.h" @@ -1389,6 +1390,34 @@ unsigned long memory_block_size_bytes(void) return memory_block_size_probed; } +/* + * Initialize an mm_struct to be used during poking and a pointer to be used + * during patching. If anything fails during initialization, poking will be done + * using the fixmap, which is unsafe, so warn the user about it. + */ +void __init poking_init(void) +{ + unsigned long poking_addr; + + poking_mm = copy_init_mm(); + if (!poking_mm) { + pr_err("x86/mm: error setting a separate poking address space"); + return; + } + + /* + * Randomize the poking address, but make sure that the following page + * will be mapped at the same PMD. We need 2 pages, so find space for 3, + * and adjust the address if the PMD ends after the first one. + */ + poking_addr = TASK_UNMAPPED_BASE + + (kaslr_get_random_long("Poking") & PAGE_MASK) % + (TASK_SIZE - TASK_UNMAPPED_BASE - 3 * PAGE_SIZE); + + if (((poking_addr + PAGE_SIZE) & ~PMD_MASK) == 0) + poking_addr += PAGE_SIZE; +} + #ifdef CONFIG_SPARSEMEM_VMEMMAP /* * Initialise the sparsemem vmemmap using huge-pages at the PMD level. diff --git a/init/main.c b/init/main.c index 18f8f0140fa0..8c6dd8d88fca 100644 --- a/init/main.c +++ b/init/main.c @@ -496,6 +496,8 @@ void __init __weak thread_stack_cache_init(void) void __init __weak mem_encrypt_init(void) { } +void __init __weak poking_init(void) { } + bool initcall_debug; core_param(initcall_debug, initcall_debug, bool, 0644); @@ -725,6 +727,7 @@ asmlinkage __visible void __init start_kernel(void) taskstats_init_early(); delayacct_init(); + poking_init(); check_bugs(); acpi_subsystem_init(); -- 2.17.1
WARNING: multiple messages have this Message-ID (diff)
From: Nadav Amit <namit@vmware.com> To: Thomas Gleixner <tglx@linutronix.de> Cc: linux-kernel@vger.kernel.org, Ingo Molnar <mingo@redhat.com>, x86@kernel.org, Arnd Bergmann <arnd@arndb.de>, linux-arch@vger.kernel.org, Dave Hansen <dave.hansen@linux.intel.com>, Nadav Amit <nadav.amit@gmail.com>, Nadav Amit <namit@vmware.com>, Kees Cook <keescook@chromium.org>, Peter Zijlstra <peterz@infradead.org>, Dave Hansen <dave.hansen@intel.com> Subject: [PATCH v2 4/6] x86/alternatives: initializing temporary mm for patching Date: Sun, 2 Sep 2018 10:32:22 -0700 [thread overview] Message-ID: <20180902173224.30606-5-namit@vmware.com> (raw) In-Reply-To: <20180902173224.30606-1-namit@vmware.com> To prevent improper use of the PTEs that are used for text patching, we want to use a temporary mm struct. We initailize it by copying the init mm. The address that will be used for patching is taken from the lower area that is usually used for the task memory. Doing so prevents the need to frequently synchronize the temporary-mm (e.g., when BPF programs are installed), since different PGDs are used for the task memory. Finally, we randomize the address of the PTEs to harden against exploits that use these PTEs. Cc: Kees Cook <keescook@chromium.org> Cc: Peter Zijlstra <peterz@infradead.org> Cc: Dave Hansen <dave.hansen@intel.com> Reviewed-by: Masami Hiramatsu <mhiramat@kernel.org> Tested-by: Masami Hiramatsu <mhiramat@kernel.org> Suggested-by: Andy Lutomirski <luto@kernel.org> Signed-off-by: Nadav Amit <namit@vmware.com> --- arch/x86/include/asm/pgtable.h | 3 +++ arch/x86/include/asm/text-patching.h | 2 ++ arch/x86/mm/init_64.c | 29 ++++++++++++++++++++++++++++ init/main.c | 3 +++ 4 files changed, 37 insertions(+) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index e4ffa565a69f..3de9a1fb7a9a 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -1022,6 +1022,9 @@ static inline void __meminit init_trampoline_default(void) /* Default trampoline pgd value */ trampoline_pgd_entry = init_top_pgt[pgd_index(__PAGE_OFFSET)]; } + +void __init poking_init(void); + # ifdef CONFIG_RANDOMIZE_MEMORY void __meminit init_trampoline(void); # else diff --git a/arch/x86/include/asm/text-patching.h b/arch/x86/include/asm/text-patching.h index e85ff65c43c3..ffe7902cc326 100644 --- a/arch/x86/include/asm/text-patching.h +++ b/arch/x86/include/asm/text-patching.h @@ -38,5 +38,7 @@ extern void *text_poke(void *addr, const void *opcode, size_t len); extern int poke_int3_handler(struct pt_regs *regs); extern void *text_poke_bp(void *addr, const void *opcode, size_t len, void *handler); extern int after_bootmem; +extern __ro_after_init struct mm_struct *poking_mm; +extern __ro_after_init unsigned long poking_addr; #endif /* _ASM_X86_TEXT_PATCHING_H */ diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index dd519f372169..db33a724a054 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -54,6 +54,7 @@ #include <asm/init.h> #include <asm/uv/uv.h> #include <asm/setup.h> +#include <asm/text-patching.h> #include "mm_internal.h" @@ -1389,6 +1390,34 @@ unsigned long memory_block_size_bytes(void) return memory_block_size_probed; } +/* + * Initialize an mm_struct to be used during poking and a pointer to be used + * during patching. If anything fails during initialization, poking will be done + * using the fixmap, which is unsafe, so warn the user about it. + */ +void __init poking_init(void) +{ + unsigned long poking_addr; + + poking_mm = copy_init_mm(); + if (!poking_mm) { + pr_err("x86/mm: error setting a separate poking address space"); + return; + } + + /* + * Randomize the poking address, but make sure that the following page + * will be mapped at the same PMD. We need 2 pages, so find space for 3, + * and adjust the address if the PMD ends after the first one. + */ + poking_addr = TASK_UNMAPPED_BASE + + (kaslr_get_random_long("Poking") & PAGE_MASK) % + (TASK_SIZE - TASK_UNMAPPED_BASE - 3 * PAGE_SIZE); + + if (((poking_addr + PAGE_SIZE) & ~PMD_MASK) == 0) + poking_addr += PAGE_SIZE; +} + #ifdef CONFIG_SPARSEMEM_VMEMMAP /* * Initialise the sparsemem vmemmap using huge-pages at the PMD level. diff --git a/init/main.c b/init/main.c index 18f8f0140fa0..8c6dd8d88fca 100644 --- a/init/main.c +++ b/init/main.c @@ -496,6 +496,8 @@ void __init __weak thread_stack_cache_init(void) void __init __weak mem_encrypt_init(void) { } +void __init __weak poking_init(void) { } + bool initcall_debug; core_param(initcall_debug, initcall_debug, bool, 0644); @@ -725,6 +727,7 @@ asmlinkage __visible void __init start_kernel(void) taskstats_init_early(); delayacct_init(); + poking_init(); check_bugs(); acpi_subsystem_init(); -- 2.17.1
next prev parent reply other threads:[~2018-09-02 17:33 UTC|newest] Thread overview: 38+ messages / expand[flat|nested] mbox.gz Atom feed top 2018-09-02 17:32 [PATCH v2 0/6] x86/alternatives: text_poke() fixes Nadav Amit 2018-09-02 17:32 ` Nadav Amit 2018-09-02 17:32 ` [PATCH v2 1/6] Fix "x86/alternatives: Lockdep-enforce text_mutex in text_poke*()" Nadav Amit 2018-09-02 17:32 ` Nadav Amit 2018-09-06 19:40 ` Peter Zijlstra 2018-09-06 19:42 ` Nadav Amit 2018-09-06 19:53 ` Peter Zijlstra 2018-09-06 19:58 ` Nadav Amit 2018-09-06 20:25 ` Peter Zijlstra 2018-09-06 20:57 ` Nadav Amit 2018-09-06 21:41 ` Peter Zijlstra 2018-09-02 17:32 ` [PATCH v2 2/6] x86/mm: temporary mm struct Nadav Amit 2018-09-02 17:32 ` Nadav Amit 2018-09-02 17:32 ` [PATCH v2 3/6] fork: provide a function for copying init_mm Nadav Amit 2018-09-02 17:32 ` Nadav Amit 2018-09-02 17:32 ` Nadav Amit [this message] 2018-09-02 17:32 ` [PATCH v2 4/6] x86/alternatives: initializing temporary mm for patching Nadav Amit 2018-09-06 9:01 ` Peter Zijlstra 2018-09-07 20:52 ` Nadav Amit 2018-09-02 17:32 ` [PATCH v2 5/6] x86/alternatives: use temporary mm for text poking Nadav Amit 2018-09-02 17:32 ` Nadav Amit 2018-09-02 17:32 ` [PATCH v2 6/6] x86/alternatives: remove text_poke() return value Nadav Amit 2018-09-02 17:32 ` Nadav Amit 2018-09-05 18:56 ` [PATCH v2 0/6] x86/alternatives: text_poke() fixes Peter Zijlstra 2018-09-05 19:02 ` Nadav Amit 2018-09-05 19:10 ` Nadav Amit 2018-09-06 8:13 ` Peter Zijlstra 2018-09-06 8:42 ` Peter Zijlstra 2018-09-06 9:18 ` Peter Zijlstra 2018-09-06 10:16 ` Peter Zijlstra 2018-09-06 17:01 ` Nadav Amit 2018-09-06 17:17 ` Peter Zijlstra 2018-09-06 17:58 ` Nadav Amit 2018-09-06 18:09 ` Andy Lutomirski 2018-09-06 18:31 ` Peter Zijlstra 2018-09-06 18:38 ` Nadav Amit 2018-09-06 19:19 ` Peter Zijlstra 2018-09-06 17:23 ` Peter Zijlstra
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=20180902173224.30606-5-namit@vmware.com \ --to=namit@vmware.com \ --cc=arnd@arndb.de \ --cc=dave.hansen@intel.com \ --cc=dave.hansen@linux.intel.com \ --cc=keescook@chromium.org \ --cc=linux-arch@vger.kernel.org \ --cc=linux-kernel@vger.kernel.org \ --cc=mingo@redhat.com \ --cc=nadav.amit@gmail.com \ --cc=peterz@infradead.org \ --cc=tglx@linutronix.de \ --cc=x86@kernel.org \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: linkBe sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.