Skip to content

Commit c07a8f8

Browse files
frdesoIngo Molnar
authored andcommitted
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 <[email protected]> Reviewed-by: Thomas Gleixner <[email protected]> Cc: Andy Lutomirski <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Brian Gerst <[email protected]> Cc: Denys Vlasenko <[email protected]> Cc: H. Peter Anvin <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Linus Torvalds <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: [email protected] Cc: [email protected] Link: http://lkml.kernel.org/r/1520565492-4637-2-git-send-email-francis.deslauriers@efficios.com Signed-off-by: Ingo Molnar <[email protected]>
1 parent c5b679f commit c07a8f8

File tree

3 files changed

+12
-1
lines changed

3 files changed

+12
-1
lines changed

arch/x86/include/asm/sections.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ extern struct exception_table_entry __stop___ex_table[];
1010

1111
#if defined(CONFIG_X86_64)
1212
extern char __end_rodata_hpage_align[];
13+
extern char __entry_trampoline_start[], __entry_trampoline_end[];
1314
#endif
1415

1516
#endif /* _ASM_X86_SECTIONS_H */

arch/x86/kernel/kprobes/core.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1168,10 +1168,18 @@ NOKPROBE_SYMBOL(longjmp_break_handler);
11681168

11691169
bool arch_within_kprobe_blacklist(unsigned long addr)
11701170
{
1171+
bool is_in_entry_trampoline_section = false;
1172+
1173+
#ifdef CONFIG_X86_64
1174+
is_in_entry_trampoline_section =
1175+
(addr >= (unsigned long)__entry_trampoline_start &&
1176+
addr < (unsigned long)__entry_trampoline_end);
1177+
#endif
11711178
return (addr >= (unsigned long)__kprobes_text_start &&
11721179
addr < (unsigned long)__kprobes_text_end) ||
11731180
(addr >= (unsigned long)__entry_text_start &&
1174-
addr < (unsigned long)__entry_text_end);
1181+
addr < (unsigned long)__entry_text_end) ||
1182+
is_in_entry_trampoline_section;
11751183
}
11761184

11771185
int __init arch_init_kprobes(void)

arch/x86/kernel/vmlinux.lds.S

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,9 +118,11 @@ SECTIONS
118118

119119
#ifdef CONFIG_X86_64
120120
. = ALIGN(PAGE_SIZE);
121+
VMLINUX_SYMBOL(__entry_trampoline_start) = .;
121122
_entry_trampoline = .;
122123
*(.entry_trampoline)
123124
. = ALIGN(PAGE_SIZE);
125+
VMLINUX_SYMBOL(__entry_trampoline_end) = .;
124126
ASSERT(. - _entry_trampoline == PAGE_SIZE, "entry trampoline is too big");
125127
#endif
126128

0 commit comments

Comments
 (0)