Skip to content

Commit

Permalink
kprobes/x86: Prohibit probing on exception masking instructions
Browse files Browse the repository at this point in the history
Since MOV SS and POP SS instructions will delay the exceptions until the
next instruction is executed, single-stepping on it by kprobes must be
prohibited.

However, kprobes usually executes those instructions directly on trampoline
buffer (a.k.a. kprobe-booster), except for the kprobes which has
post_handler. Thus if kprobe user probes MOV SS with post_handler, it will
do single-stepping on the MOV SS.

This means it is safe that if it is used via ftrace or perf/bpf since those
don't use the post_handler.

Anyway, since the stack switching is a rare case, it is safer just
rejecting kprobes on such instructions.

Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Cc: Ricardo Neri <ricardo.neri-calderon@linux.intel.com>
Cc: Francis Deslauriers <francis.deslauriers@efficios.com>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Cc: Andy Lutomirski <luto@kernel.org>
Cc: "H . Peter Anvin" <hpa@zytor.com>
Cc: Yonghong Song <yhs@fb.com>
Cc: Borislav Petkov <bp@suse.de>
Cc: Linus Torvalds <torvalds@linux-foundation.org>
Cc: "David S . Miller" <davem@davemloft.net>
Link: https://lkml.kernel.org/r/152587069574.17316.3311695234863248641.stgit@devbox
  • Loading branch information
Masami Hiramatsu authored and Thomas Gleixner committed May 13, 2018
1 parent a466ef7 commit ee6a735
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 0 deletions.
18 changes: 18 additions & 0 deletions arch/x86/include/asm/insn.h
Original file line number Diff line number Diff line change
Expand Up @@ -208,4 +208,22 @@ static inline int insn_offset_immediate(struct insn *insn)
return insn_offset_displacement(insn) + insn->displacement.nbytes;
}

#define POP_SS_OPCODE 0x1f
#define MOV_SREG_OPCODE 0x8e

/*
* Intel SDM Vol.3A 6.8.3 states;
* "Any single-step trap that would be delivered following the MOV to SS
* instruction or POP to SS instruction (because EFLAGS.TF is 1) is
* suppressed."
* This function returns true if @insn is MOV SS or POP SS. On these
* instructions, single stepping is suppressed.
*/
static inline int insn_masking_exception(struct insn *insn)
{
return insn->opcode.bytes[0] == POP_SS_OPCODE ||
(insn->opcode.bytes[0] == MOV_SREG_OPCODE &&
X86_MODRM_REG(insn->modrm.bytes[0]) == 2);
}

#endif /* _ASM_X86_INSN_H */
4 changes: 4 additions & 0 deletions arch/x86/kernel/kprobes/core.c
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,10 @@ int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn)
if (insn->opcode.bytes[0] == BREAKPOINT_INSTRUCTION)
return 0;

/* We should not singlestep on the exception masking instructions */
if (insn_masking_exception(insn))
return 0;

#ifdef CONFIG_X86_64
/* Only x86_64 has RIP relative instructions */
if (insn_rip_relative(insn)) {
Expand Down

0 comments on commit ee6a735

Please sign in to comment.