Received: by 2002:ac0:a5a6:0:0:0:0:0 with SMTP id m35-v6csp345068imm; Wed, 29 Aug 2018 01:16:04 -0700 (PDT) X-Google-Smtp-Source: ANB0Vdbzv4Je8Z7WFTHFEklxf+tN4dAj3VXgmVDzT5k9Js5OyPIzCvreLvxjh7o+NnwP1Z2iKT1B X-Received: by 2002:a17:902:3041:: with SMTP id u59-v6mr4821556plb.99.1535530564080; Wed, 29 Aug 2018 01:16:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1535530564; cv=none; d=google.com; s=arc-20160816; b=cDkI5Gf9NWiXo/rQ1pLaoJtN2jO6w3M5OnEjq6y6y+u7dInNRtPNjJfg8eJh35ho0a XHo0pkMEkwV6Ptzop3Co2v94QnEEPrsEOX+qepl8wY+TtF3Pur4cxOxOw8ttYWcltDc3 xO/mpaFuWQNF0HtiM/zZ1p28gpRcXqzVA8LSaRrTcF6DThdYVN/IiFA+T1T0gLmEvYas PPGR8UeU11dziFu/JesWvHmFexOxDxZ0biILyet5fSQDhWVYkI6e4mhICCWTMr/PnmBy Oa5xkwCkpZ5Ae9f65i8HUEwX8A9n0y/nT9kjXNtAFic5wMDQhaWoSCIwtLtn6nFjF0QA 5Ufg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:arc-authentication-results; bh=SAEVY4qT07Gc0GUxkEm/WCUn7nf6zdbNON9GLjVdynE=; b=iopWbLhnx9vUNJfjcftznTVNy9KqZuTLTrV/AG5Mpa40eensDY/fhi2EAB92+brsls jWwwJJFj9DbjrOQKpFahOp2Nc3trOqjQLSijvLTM+s7GRy4lJgwFxWqHtWSdcAGM4/Hy xE9gOTjP9fv+DPNTFTFvsv5TFLDHrYStyqaK4mA/LeItbx3HtGyqVkQ8u4+2gtFfxMQo Lq2gyV7xZyEKBBks6QF1PPOy+72SzOruMllJZ7YSVTsILEIrCi6Qcs+FbKqL+Bh4Thxi OCcNgMU/t/ThBM1W1SJYCK02yw8BNxag9u4P5oVxunJHFTpdkh+bEt+t66WRDtzA6P1U kK9Q== ARC-Authentication-Results: i=1; mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=vmware.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id h8-v6si3481764pli.14.2018.08.29.01.15.49; Wed, 29 Aug 2018 01:16:04 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; spf=pass (google.com: best guess record for domain of linux-kernel-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=fail (p=NONE sp=NONE dis=NONE) header.from=vmware.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1728083AbeH2MJa (ORCPT + 99 others); Wed, 29 Aug 2018 08:09:30 -0400 Received: from ex13-edg-ou-001.vmware.com ([208.91.0.189]:43187 "EHLO EX13-EDG-OU-001.vmware.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1727948AbeH2MJI (ORCPT ); Wed, 29 Aug 2018 08:09:08 -0400 Received: from sc9-mailhost3.vmware.com (10.113.161.73) by EX13-EDG-OU-001.vmware.com (10.113.208.155) with Microsoft SMTP Server id 15.0.1156.6; Wed, 29 Aug 2018 01:13:09 -0700 Received: from sc2-haas01-esx0118.eng.vmware.com (sc2-haas01-esx0118.eng.vmware.com [10.172.44.118]) by sc9-mailhost3.vmware.com (Postfix) with ESMTP id 4212440E07; Wed, 29 Aug 2018 01:13:26 -0700 (PDT) From: Nadav Amit To: Thomas Gleixner CC: , Ingo Molnar , , Arnd Bergmann , , Nadav Amit , Masami Hiramatsu , Kees Cook , Peter Zijlstra Subject: [RFC PATCH 4/6] x86/alternatives: initializing temporary mm for patching Date: Wed, 29 Aug 2018 01:11:45 -0700 Message-ID: <20180829081147.184610-5-namit@vmware.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20180829081147.184610-1-namit@vmware.com> References: <20180829081147.184610-1-namit@vmware.com> MIME-Version: 1.0 Content-Type: text/plain Received-SPF: None (EX13-EDG-OU-001.vmware.com: namit@vmware.com does not designate permitted sender hosts) Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org 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: Masami Hiramatsu Cc: Kees Cook Cc: Peter Zijlstra Suggested-by: Andy Lutomirski Signed-off-by: Nadav Amit --- arch/x86/include/asm/pgtable.h | 4 ++++ arch/x86/include/asm/text-patching.h | 2 ++ arch/x86/mm/init_64.c | 35 ++++++++++++++++++++++++++++ include/asm-generic/pgtable.h | 4 ++++ init/main.c | 1 + 5 files changed, 46 insertions(+) diff --git a/arch/x86/include/asm/pgtable.h b/arch/x86/include/asm/pgtable.h index e4ffa565a69f..c65d2b146ff6 100644 --- a/arch/x86/include/asm/pgtable.h +++ b/arch/x86/include/asm/pgtable.h @@ -1022,6 +1022,10 @@ 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); +#define poking_init poking_init + # 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..ed4a46a89946 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,7 @@ #include #include #include +#include #include "mm_internal.h" @@ -1389,6 +1391,39 @@ 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) + goto error; + + /* + * 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; + + return; +error: + if (poking_mm) + mmput(poking_mm); + poking_mm = NULL; + pr_err("x86/mm: error setting a separate poking address space\n"); +} + #ifdef CONFIG_SPARSEMEM_VMEMMAP /* * Initialise the sparsemem vmemmap using huge-pages at the PMD level. diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h index 88ebc6102c7c..c66579d0ee67 100644 --- a/include/asm-generic/pgtable.h +++ b/include/asm-generic/pgtable.h @@ -1111,6 +1111,10 @@ static inline bool arch_has_pfn_modify_check(void) #ifndef PAGE_KERNEL_EXEC # define PAGE_KERNEL_EXEC PAGE_KERNEL + +#ifndef poking_init +static inline void poking_init(void) { } +#endif #endif #endif /* !__ASSEMBLY__ */ diff --git a/init/main.c b/init/main.c index 18f8f0140fa0..6754ff2687c8 100644 --- a/init/main.c +++ b/init/main.c @@ -725,6 +725,7 @@ asmlinkage __visible void __init start_kernel(void) taskstats_init_early(); delayacct_init(); + poking_init(); check_bugs(); acpi_subsystem_init(); -- 2.17.1