linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 0/1] x86/kprobes: Prohibit probing of .entry_trampoline code
@ 2018-03-09  3:18 Francis Deslauriers
  2018-03-09  3:18 ` [PATCH 1/1] " Francis Deslauriers
  2018-03-09 15:15 ` [PATCH 0/1] x86/kprobes: Prohibit probing of " Masami Hiramatsu
  0 siblings, 2 replies; 5+ messages in thread
From: Francis Deslauriers @ 2018-03-09  3:18 UTC (permalink / raw)
  To: mhiramat
  Cc: tglx, mingo, peterz, mathieu.desnoyers, linux-kernel,
	Francis Deslauriers

Hi all,

While fuzzing the Perf kprobe interface, I found that adding a probe on
the 'entry_SYSCALL_64_trampoline' symbol will crash my 4.16-rc4
kernel(661e50bc853209e41a5c14a290ca4decc43cbfd1) on a x86_64 Qemu VM.

How to reproduce:
	echo 'p:event1 entry_SYSCALL_64_trampoline' > ./kprobe_events
	echo 1 >  events/kprobes/enable
Crash log:[1]

My understanding is that the userspace CR3 register has not yet been
replaced by the kernel's CR3, when the kprobe is triggered. This means
that the kernel addresses can not be translated, thus making the
handling of the kprobe impossible.

This can be fixed by blacklisting the .entry_trampoline section. See
patch[1/1].

Here is the config I am using[2].

Thanks,

Francis Deslauriers
EfficiOS inc.

1:http://paste.ubuntu.com/p/djnpZCzQKv/
2:http://paste.ubuntu.com/p/3jrFYt6XQB/

Francis Deslauriers (1):
  x86/kprobes: Prohibit probing of .entry_trampoline code

 arch/x86/include/asm/sections.h |  1 +
 arch/x86/kernel/kprobes/core.c  | 10 +++++++++-
 arch/x86/kernel/vmlinux.lds.S   |  2 ++
 3 files changed, 12 insertions(+), 1 deletion(-)

-- 
2.7.4

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [PATCH 1/1] x86/kprobes: Prohibit probing of .entry_trampoline code
  2018-03-09  3:18 [PATCH 0/1] x86/kprobes: Prohibit probing of .entry_trampoline code Francis Deslauriers
@ 2018-03-09  3:18 ` Francis Deslauriers
  2018-03-09 15:17   ` Masami Hiramatsu
  2018-03-10  7:07   ` [tip:x86/pti] x86/kprobes: Fix kernel crash when probing " tip-bot for Francis Deslauriers
  2018-03-09 15:15 ` [PATCH 0/1] x86/kprobes: Prohibit probing of " Masami Hiramatsu
  1 sibling, 2 replies; 5+ messages in thread
From: Francis Deslauriers @ 2018-03-09  3:18 UTC (permalink / raw)
  To: mhiramat
  Cc: tglx, mingo, peterz, mathieu.desnoyers, linux-kernel,
	Francis Deslauriers

.entry_trampoline is a code area that is used to ensure page table
isolation between userspace and kernelspace.

At the beginning of the execution of the trampoline, we load the
kernel's CR3 register. This has the effect of enabling the translation
of the kernel virtual addresses to physical addresses. Before this
happens most kernel addresses can not be translated because the running
process' CR3 is still used.

If a kprobe is placed on the trampoline code before that change of the
CR3 register happens the kernel crashes because int3 handling pages are
not accessible.

To fix this, add the .entry_trampoline section to the kprobe blacklist
to prohibit the probing of code before all the kernel pages are
accessible.

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
---
 arch/x86/include/asm/sections.h |  1 +
 arch/x86/kernel/kprobes/core.c  | 10 +++++++++-
 arch/x86/kernel/vmlinux.lds.S   |  2 ++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h
index d6baf23..5c019d2 100644
--- a/arch/x86/include/asm/sections.h
+++ b/arch/x86/include/asm/sections.h
@@ -10,6 +10,7 @@ extern struct exception_table_entry __stop___ex_table[];
 
 #if defined(CONFIG_X86_64)
 extern char __end_rodata_hpage_align[];
+extern char __entry_trampoline_start[], __entry_trampoline_end[];
 #endif
 
 #endif	/* _ASM_X86_SECTIONS_H */
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index bd36f3c..0715f82 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -1168,10 +1168,18 @@ NOKPROBE_SYMBOL(longjmp_break_handler);
 
 bool arch_within_kprobe_blacklist(unsigned long addr)
 {
+	bool is_in_entry_trampoline_section = false;
+
+#ifdef CONFIG_X86_64
+	is_in_entry_trampoline_section =
+		(addr >= (unsigned long)__entry_trampoline_start &&
+		 addr < (unsigned long)__entry_trampoline_end);
+#endif
 	return  (addr >= (unsigned long)__kprobes_text_start &&
 		 addr < (unsigned long)__kprobes_text_end) ||
 		(addr >= (unsigned long)__entry_text_start &&
-		 addr < (unsigned long)__entry_text_end);
+		 addr < (unsigned long)__entry_text_end) ||
+		is_in_entry_trampoline_section;
 }
 
 int __init arch_init_kprobes(void)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 9b138a0..b854ebf 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -118,9 +118,11 @@ SECTIONS
 
 #ifdef CONFIG_X86_64
 		. = ALIGN(PAGE_SIZE);
+		VMLINUX_SYMBOL(__entry_trampoline_start) = .;
 		_entry_trampoline = .;
 		*(.entry_trampoline)
 		. = ALIGN(PAGE_SIZE);
+		VMLINUX_SYMBOL(__entry_trampoline_end) = .;
 		ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big");
 #endif
 
-- 
2.7.4

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH 0/1] x86/kprobes: Prohibit probing of .entry_trampoline code
  2018-03-09  3:18 [PATCH 0/1] x86/kprobes: Prohibit probing of .entry_trampoline code Francis Deslauriers
  2018-03-09  3:18 ` [PATCH 1/1] " Francis Deslauriers
@ 2018-03-09 15:15 ` Masami Hiramatsu
  1 sibling, 0 replies; 5+ messages in thread
From: Masami Hiramatsu @ 2018-03-09 15:15 UTC (permalink / raw)
  To: Francis Deslauriers; +Cc: tglx, mingo, peterz, mathieu.desnoyers, linux-kernel

On Thu,  8 Mar 2018 22:18:11 -0500
Francis Deslauriers <francis.deslauriers@efficios.com> wrote:

> Hi all,
> 
> While fuzzing the Perf kprobe interface, I found that adding a probe on
> the 'entry_SYSCALL_64_trampoline' symbol will crash my 4.16-rc4
> kernel(661e50bc853209e41a5c14a290ca4decc43cbfd1) on a x86_64 Qemu VM.
> 
> How to reproduce:
> 	echo 'p:event1 entry_SYSCALL_64_trampoline' > ./kprobe_events
> 	echo 1 >  events/kprobes/enable
> Crash log:[1]
> 
> My understanding is that the userspace CR3 register has not yet been
> replaced by the kernel's CR3, when the kprobe is triggered. This means
> that the kernel addresses can not be translated, thus making the
> handling of the kprobe impossible.

Thanks for reporting!
And yes, all entry code must be nokprobe.

> 
> This can be fixed by blacklisting the .entry_trampoline section. See
> patch[1/1].
> 
> Here is the config I am using[2].
> 
> Thanks,
> 
> Francis Deslauriers
> EfficiOS inc.
> 
> 1:http://paste.ubuntu.com/p/djnpZCzQKv/
> 2:http://paste.ubuntu.com/p/3jrFYt6XQB/
> 
> Francis Deslauriers (1):
>   x86/kprobes: Prohibit probing of .entry_trampoline code
> 
>  arch/x86/include/asm/sections.h |  1 +
>  arch/x86/kernel/kprobes/core.c  | 10 +++++++++-
>  arch/x86/kernel/vmlinux.lds.S   |  2 ++
>  3 files changed, 12 insertions(+), 1 deletion(-)
> 
> -- 
> 2.7.4
> 


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH 1/1] x86/kprobes: Prohibit probing of .entry_trampoline code
  2018-03-09  3:18 ` [PATCH 1/1] " Francis Deslauriers
@ 2018-03-09 15:17   ` Masami Hiramatsu
  2018-03-10  7:07   ` [tip:x86/pti] x86/kprobes: Fix kernel crash when probing " tip-bot for Francis Deslauriers
  1 sibling, 0 replies; 5+ messages in thread
From: Masami Hiramatsu @ 2018-03-09 15:17 UTC (permalink / raw)
  To: Francis Deslauriers; +Cc: tglx, mingo, peterz, mathieu.desnoyers, linux-kernel

On Thu,  8 Mar 2018 22:18:12 -0500
Francis Deslauriers <francis.deslauriers@efficios.com> wrote:

> .entry_trampoline is a code area that is used to ensure page table
> isolation between userspace and kernelspace.
> 
> At the beginning of the execution of the trampoline, we load the
> kernel's CR3 register. This has the effect of enabling the translation
> of the kernel virtual addresses to physical addresses. Before this
> happens most kernel addresses can not be translated because the running
> process' CR3 is still used.
> 
> If a kprobe is placed on the trampoline code before that change of the
> CR3 register happens the kernel crashes because int3 handling pages are
> not accessible.
> 
> To fix this, add the .entry_trampoline section to the kprobe blacklist
> to prohibit the probing of code before all the kernel pages are
> accessible.

OK, looks good to me.

Acked-by: Masami Hiramatsu <mhiramat@kernel.org>

Ingo, could you pick it as an urgent fix?

Thanks!

> 
> Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
> ---
>  arch/x86/include/asm/sections.h |  1 +
>  arch/x86/kernel/kprobes/core.c  | 10 +++++++++-
>  arch/x86/kernel/vmlinux.lds.S   |  2 ++
>  3 files changed, 12 insertions(+), 1 deletion(-)
> 
> diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h
> index d6baf23..5c019d2 100644
> --- a/arch/x86/include/asm/sections.h
> +++ b/arch/x86/include/asm/sections.h
> @@ -10,6 +10,7 @@ extern struct exception_table_entry __stop___ex_table[];
>  
>  #if defined(CONFIG_X86_64)
>  extern char __end_rodata_hpage_align[];
> +extern char __entry_trampoline_start[], __entry_trampoline_end[];
>  #endif
>  
>  #endif	/* _ASM_X86_SECTIONS_H */
> diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
> index bd36f3c..0715f82 100644
> --- a/arch/x86/kernel/kprobes/core.c
> +++ b/arch/x86/kernel/kprobes/core.c
> @@ -1168,10 +1168,18 @@ NOKPROBE_SYMBOL(longjmp_break_handler);
>  
>  bool arch_within_kprobe_blacklist(unsigned long addr)
>  {
> +	bool is_in_entry_trampoline_section = false;
> +
> +#ifdef CONFIG_X86_64
> +	is_in_entry_trampoline_section =
> +		(addr >= (unsigned long)__entry_trampoline_start &&
> +		 addr < (unsigned long)__entry_trampoline_end);
> +#endif
>  	return  (addr >= (unsigned long)__kprobes_text_start &&
>  		 addr < (unsigned long)__kprobes_text_end) ||
>  		(addr >= (unsigned long)__entry_text_start &&
> -		 addr < (unsigned long)__entry_text_end);
> +		 addr < (unsigned long)__entry_text_end) ||
> +		is_in_entry_trampoline_section;
>  }
>  
>  int __init arch_init_kprobes(void)
> diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
> index 9b138a0..b854ebf 100644
> --- a/arch/x86/kernel/vmlinux.lds.S
> +++ b/arch/x86/kernel/vmlinux.lds.S
> @@ -118,9 +118,11 @@ SECTIONS
>  
>  #ifdef CONFIG_X86_64
>  		. = ALIGN(PAGE_SIZE);
> +		VMLINUX_SYMBOL(__entry_trampoline_start) = .;
>  		_entry_trampoline = .;
>  		*(.entry_trampoline)
>  		. = ALIGN(PAGE_SIZE);
> +		VMLINUX_SYMBOL(__entry_trampoline_end) = .;
>  		ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big");
>  #endif
>  
> -- 
> 2.7.4
> 


-- 
Masami Hiramatsu <mhiramat@kernel.org>

^ permalink raw reply	[flat|nested] 5+ messages in thread

* [tip:x86/pti] x86/kprobes: Fix kernel crash when probing .entry_trampoline code
  2018-03-09  3:18 ` [PATCH 1/1] " Francis Deslauriers
  2018-03-09 15:17   ` Masami Hiramatsu
@ 2018-03-10  7:07   ` tip-bot for Francis Deslauriers
  1 sibling, 0 replies; 5+ messages in thread
From: tip-bot for Francis Deslauriers @ 2018-03-10  7:07 UTC (permalink / raw)
  To: linux-tip-commits
  Cc: dvlasenk, hpa, linux-kernel, torvalds, peterz, jpoimboe, bp,
	mingo, brgerst, luto, francis.deslauriers, tglx

Commit-ID:  c07a8f8b08ba683ea24f3ac9159f37ae94daf47f
Gitweb:     https://git.kernel.org/tip/c07a8f8b08ba683ea24f3ac9159f37ae94daf47f
Author:     Francis Deslauriers <francis.deslauriers@efficios.com>
AuthorDate: Thu, 8 Mar 2018 22:18:12 -0500
Committer:  Ingo Molnar <mingo@kernel.org>
CommitDate: Fri, 9 Mar 2018 09:58:36 +0100

x86/kprobes: Fix kernel crash when probing .entry_trampoline code

Disable the kprobe probing of the entry trampoline:

.entry_trampoline is a code area that is used to ensure page table
isolation between userspace and kernelspace.

At the beginning of the execution of the trampoline, we load the
kernel's CR3 register. This has the effect of enabling the translation
of the kernel virtual addresses to physical addresses. Before this
happens most kernel addresses can not be translated because the running
process' CR3 is still used.

If a kprobe is placed on the trampoline code before that change of the
CR3 register happens the kernel crashes because int3 handling pages are
not accessible.

To fix this, add the .entry_trampoline section to the kprobe blacklist
to prohibit the probing of code before all the kernel pages are
accessible.

Signed-off-by: Francis Deslauriers <francis.deslauriers@efficios.com>
Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Brian Gerst <brgerst@gmail.com>
Cc: Denys Vlasenko <dvlasenk@redhat.com>
Cc: H. Peter Anvin <hpa@zytor.com>
Cc: Josh Poimboeuf <jpoimboe@redhat.com>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: mathieu.desnoyers@efficios.com
Cc: mhiramat@kernel.org
Link: http://lkml.kernel.org/r/1520565492-4637-2-git-send-email-francis.deslauriers@efficios.com
Signed-off-by: Ingo Molnar <mingo@kernel.org>
---
 arch/x86/include/asm/sections.h |  1 +
 arch/x86/kernel/kprobes/core.c  | 10 +++++++++-
 arch/x86/kernel/vmlinux.lds.S   |  2 ++
 3 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/arch/x86/include/asm/sections.h b/arch/x86/include/asm/sections.h
index d6baf23782bc..5c019d23d06b 100644
--- a/arch/x86/include/asm/sections.h
+++ b/arch/x86/include/asm/sections.h
@@ -10,6 +10,7 @@ extern struct exception_table_entry __stop___ex_table[];
 
 #if defined(CONFIG_X86_64)
 extern char __end_rodata_hpage_align[];
+extern char __entry_trampoline_start[], __entry_trampoline_end[];
 #endif
 
 #endif	/* _ASM_X86_SECTIONS_H */
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index bd36f3c33cd0..0715f827607c 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -1168,10 +1168,18 @@ NOKPROBE_SYMBOL(longjmp_break_handler);
 
 bool arch_within_kprobe_blacklist(unsigned long addr)
 {
+	bool is_in_entry_trampoline_section = false;
+
+#ifdef CONFIG_X86_64
+	is_in_entry_trampoline_section =
+		(addr >= (unsigned long)__entry_trampoline_start &&
+		 addr < (unsigned long)__entry_trampoline_end);
+#endif
 	return  (addr >= (unsigned long)__kprobes_text_start &&
 		 addr < (unsigned long)__kprobes_text_end) ||
 		(addr >= (unsigned long)__entry_text_start &&
-		 addr < (unsigned long)__entry_text_end);
+		 addr < (unsigned long)__entry_text_end) ||
+		is_in_entry_trampoline_section;
 }
 
 int __init arch_init_kprobes(void)
diff --git a/arch/x86/kernel/vmlinux.lds.S b/arch/x86/kernel/vmlinux.lds.S
index 9b138a06c1a4..b854ebf5851b 100644
--- a/arch/x86/kernel/vmlinux.lds.S
+++ b/arch/x86/kernel/vmlinux.lds.S
@@ -118,9 +118,11 @@ SECTIONS
 
 #ifdef CONFIG_X86_64
 		. = ALIGN(PAGE_SIZE);
+		VMLINUX_SYMBOL(__entry_trampoline_start) = .;
 		_entry_trampoline = .;
 		*(.entry_trampoline)
 		. = ALIGN(PAGE_SIZE);
+		VMLINUX_SYMBOL(__entry_trampoline_end) = .;
 		ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big");
 #endif
 

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2018-03-10  7:07 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-03-09  3:18 [PATCH 0/1] x86/kprobes: Prohibit probing of .entry_trampoline code Francis Deslauriers
2018-03-09  3:18 ` [PATCH 1/1] " Francis Deslauriers
2018-03-09 15:17   ` Masami Hiramatsu
2018-03-10  7:07   ` [tip:x86/pti] x86/kprobes: Fix kernel crash when probing " tip-bot for Francis Deslauriers
2018-03-09 15:15 ` [PATCH 0/1] x86/kprobes: Prohibit probing of " Masami Hiramatsu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).