]>
Commit | Line | Data |
---|---|---|
c4288e2b SL |
1 | From e4cb269c974c1fea2b95cfde5d0860c261a041d5 Mon Sep 17 00:00:00 2001 |
2 | From: Nadav Amit <namit@vmware.com> | |
3 | Date: Thu, 25 Apr 2019 17:11:30 -0700 | |
4 | Subject: x86/kprobes: Set instruction page as executable | |
5 | ||
6 | [ Upstream commit 7298e24f904224fa79eb8fd7e0fbd78950ccf2db ] | |
7 | ||
8 | Set the page as executable after allocation. This patch is a | |
9 | preparatory patch for a following patch that makes module allocated | |
10 | pages non-executable. | |
11 | ||
12 | While at it, do some small cleanup of what appears to be unnecessary | |
13 | masking. | |
14 | ||
15 | Signed-off-by: Nadav Amit <namit@vmware.com> | |
16 | Signed-off-by: Rick Edgecombe <rick.p.edgecombe@intel.com> | |
17 | Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org> | |
18 | Cc: <akpm@linux-foundation.org> | |
19 | Cc: <ard.biesheuvel@linaro.org> | |
20 | Cc: <deneen.t.dock@intel.com> | |
21 | Cc: <kernel-hardening@lists.openwall.com> | |
22 | Cc: <kristen@linux.intel.com> | |
23 | Cc: <linux_dti@icloud.com> | |
24 | Cc: <will.deacon@arm.com> | |
25 | Cc: Andy Lutomirski <luto@kernel.org> | |
26 | Cc: Borislav Petkov <bp@alien8.de> | |
27 | Cc: Dave Hansen <dave.hansen@linux.intel.com> | |
28 | Cc: H. Peter Anvin <hpa@zytor.com> | |
29 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
30 | Cc: Rik van Riel <riel@surriel.com> | |
31 | Cc: Thomas Gleixner <tglx@linutronix.de> | |
32 | Link: https://lkml.kernel.org/r/20190426001143.4983-11-namit@vmware.com | |
33 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
34 | Signed-off-by: Sasha Levin <sashal@kernel.org> | |
35 | --- | |
36 | arch/x86/kernel/kprobes/core.c | 24 ++++++++++++++++++++---- | |
37 | 1 file changed, 20 insertions(+), 4 deletions(-) | |
38 | ||
39 | diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c | |
40 | index 544bc2dfe408..e83a057564d1 100644 | |
41 | --- a/arch/x86/kernel/kprobes/core.c | |
42 | +++ b/arch/x86/kernel/kprobes/core.c | |
43 | @@ -431,8 +431,20 @@ void *alloc_insn_page(void) | |
44 | void *page; | |
45 | ||
46 | page = module_alloc(PAGE_SIZE); | |
47 | - if (page) | |
48 | - set_memory_ro((unsigned long)page & PAGE_MASK, 1); | |
49 | + if (!page) | |
50 | + return NULL; | |
51 | + | |
52 | + /* | |
53 | + * First make the page read-only, and only then make it executable to | |
54 | + * prevent it from being W+X in between. | |
55 | + */ | |
56 | + set_memory_ro((unsigned long)page, 1); | |
57 | + | |
58 | + /* | |
59 | + * TODO: Once additional kernel code protection mechanisms are set, ensure | |
60 | + * that the page was not maliciously altered and it is still zeroed. | |
61 | + */ | |
62 | + set_memory_x((unsigned long)page, 1); | |
63 | ||
64 | return page; | |
65 | } | |
66 | @@ -440,8 +452,12 @@ void *alloc_insn_page(void) | |
67 | /* Recover page to RW mode before releasing it */ | |
68 | void free_insn_page(void *page) | |
69 | { | |
70 | - set_memory_nx((unsigned long)page & PAGE_MASK, 1); | |
71 | - set_memory_rw((unsigned long)page & PAGE_MASK, 1); | |
72 | + /* | |
73 | + * First make the page non-executable, and only then make it writable to | |
74 | + * prevent it from being W+X in between. | |
75 | + */ | |
76 | + set_memory_nx((unsigned long)page, 1); | |
77 | + set_memory_rw((unsigned long)page, 1); | |
78 | module_memfree(page); | |
79 | } | |
80 | ||
81 | -- | |
82 | 2.20.1 | |
83 |