Skip to contentSkip to conversation

uprobes: x86: Reject probing MOV SS

PATCH In review Masami Hiramatsu 4 participants 9 messages May 9, 2018 – May 13, 2018

Subsystems (2)
lore
Share & tools
lore

Masami Hiramatsu

author maintainer
#0 lore raw

cover uprobes: x86: Reject probing MOV SS

Hi,

I found the CVE-2018-1087 and CVE-2018-8897 should be related to kprobes and uprobes too, since both are using #DB for single stepping.

I decided to just reject probes on MOV SS and POP SS because those are not recommended to use (Intel SDM recommend to use LSS instead), thus it might be rare case.

Oleg, could you review the uprobes patch?

Thank you,

---

Masami Hiramatsu (2):
kprobes: x86: Prohibit probing on exception masking instructions
uprobes: x86: Prohibit probing on MOV SS instruction

 arch/x86/include/asm/insn.h    |   18 ++++++++++++++++++
 arch/x86/kernel/kprobes/core.c |    4 ++++
 arch/x86/kernel/uprobes.c      |    4 ++++
 3 files changed, 26 insertions(+)

--
Masami Hiramatsu (Linaro) <[email protected]>

author maintainer
#1 lore raw

PATCH 1/2 kprobes: x86: Prohibit probing on exception masking instructions

Since MOV SS and POP SS instructions will delay the exceptions until the next instruction is executed, we should not do single-stepping on it by kprobes.

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 we use it 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.

---
 arch/x86/include/asm/insn.h    |   18 ++++++++++++++++++
 arch/x86/kernel/kprobes/core.c |    4 ++++
 2 files changed, 22 insertions(+)
arch/x86/include/asm/insn.h +18 -0
index b3e32b010ab1..c2c01f84df75 100644
@@ -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 */
arch/x86/kernel/kprobes/core.c +4 -0
index 0715f827607c..6f4d42377fe5 100644
@@ -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)) {
#2 lore raw

[tip:x86/urgent] kprobes/x86: Prohibit probing on exception masking instructions

kprobes/x86: Prohibit probing on exception masking instructions
Commit-ID:  ee6a7354a3629f9b65bc18dbe393503e9440d6f5
Gitweb:     https://git.kernel.org/tip/ee6a7354a3629f9b65bc18dbe393503e9440d6f5
Author:     Masami Hiramatsu <[email protected]>
AuthorDate: Wed, 9 May 2018 21:58:15 +0900
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 13 May 2018 19:52:55 +0200

kprobes/x86: Prohibit probing on exception masking instructions

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.

Cc Ricardo Neri <[email protected]>
Cc Francis Deslauriers <[email protected]>
Cc Oleg Nesterov <[email protected]>
Cc Alexei Starovoitov <[email protected]>
Cc Steven Rostedt <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc "H . Peter Anvin" <[email protected]>
Cc Yonghong Song <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc "David S . Miller" <[email protected]>
---
 arch/x86/include/asm/insn.h    | 18 ++++++++++++++++++
 arch/x86/kernel/kprobes/core.c |  4 ++++
 2 files changed, 22 insertions(+)
arch/x86/include/asm/insn.h +18 -0
index b3e32b010ab1..c2c01f84df75 100644
@@ -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 */
arch/x86/kernel/kprobes/core.c +4 -0
index 0715f827607c..6f4d42377fe5 100644
@@ -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)) {
author maintainer
#3 lore raw

PATCH 2/2 uprobes: x86: Prohibit probing on MOV SS instruction

In reply to Masami Hiramatsu

Since MOV SS and POP SS instructions will delay the exceptions until the next instruction is executed, we should not do single-stepping on it by uprobes.

uprobe already rejects probing on POP SS (0x1f), but allows probing on MOV SS (0x8e and reg == 2).
This checks the target instruction and if it is MOV SS or POP SS, returns -ENOTSUPP to reject probing.

---
 arch/x86/kernel/uprobes.c |    4 ++++
 1 file changed, 4 insertions(+)
arch/x86/kernel/uprobes.c +4 -0
index 85c7ef23d99f..c84bb5396958 100644
@@ -299,6 +299,10 @@ static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool
 	if (is_prefix_bad(insn))
 		return -ENOTSUPP;
 
+	/* We should not singlestep on the exception masking instructions */
+	if (insn_masking_exception(insn))
+		return -ENOTSUPP;
+
 	if (x86_64)
 		good_insns = good_insns_64;
 	else
maintainer Acked-by on v1 2/2
#4 lore raw

Re: [PATCH 2/2] uprobes: x86: Prohibit probing on MOV SS instruction

Quoted 4 lines · Masami Hiramatsu

Since MOV SS and POP SS instructions will delay the exceptions until the next instruction is executed, we should not do single-stepping on it by uprobes.

...

arch/x86/kernel/uprobes.c static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool · line 304

Quoted 9 lines
arch/x86/kernel/uprobes.c +3 -0
@@ -299,6 +299,10 @@ static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool
 	if (is_prefix_bad(insn))
 		return -ENOTSUPP;
 
+	/* We should not singlestep on the exception masking instructions */
+	if (insn_masking_exception(insn))
+		return -ENOTSUPP;
#5 lore raw

[tip:x86/urgent] uprobes/x86: Prohibit probing on MOV SS instruction

In reply to Masami Hiramatsu
uprobes/x86: Prohibit probing on MOV SS instruction
Commit-ID:  13ebe18c94f5b0665c01ae7fad2717ae959f4212
Gitweb:     https://git.kernel.org/tip/13ebe18c94f5b0665c01ae7fad2717ae959f4212
Author:     Masami Hiramatsu <[email protected]>
AuthorDate: Wed, 9 May 2018 21:58:45 +0900
Committer:  Thomas Gleixner <[email protected]>
CommitDate: Sun, 13 May 2018 19:52:56 +0200

uprobes/x86: Prohibit probing on MOV SS instruction

Since MOV SS and POP SS instructions will delay the exceptions until the next instruction is executed, single-stepping on it by uprobes must be prohibited.

uprobe already rejects probing on POP SS (0x1f), but allows probing on MOV SS (0x8e and reg == 2). This checks the target instruction and if it is MOV SS or POP SS, returns -ENOTSUPP to reject probing.

Cc Ricardo Neri <[email protected]>
Cc Francis Deslauriers <[email protected]>
Cc Alexei Starovoitov <[email protected]>
Cc Steven Rostedt <[email protected]>
Cc Andy Lutomirski <[email protected]>
Cc "H . Peter Anvin" <[email protected]>
Cc Yonghong Song <[email protected]>
Cc Borislav Petkov <[email protected]>
Cc Linus Torvalds <[email protected]>
Cc "David S . Miller" <[email protected]>
---
 arch/x86/kernel/uprobes.c | 4 ++++
 1 file changed, 4 insertions(+)
arch/x86/kernel/uprobes.c +4 -0
index 85c7ef23d99f..c84bb5396958 100644
@@ -299,6 +299,10 @@ static int uprobe_init_insn(struct arch_uprobe *auprobe, struct insn *insn, bool
 	if (is_prefix_bad(insn))
 		return -ENOTSUPP;
 
+	/* We should not singlestep on the exception masking instructions */
+	if (insn_masking_exception(insn))
+		return -ENOTSUPP;
+
 	if (x86_64)
 		good_insns = good_insns_64;
 	else
author maintainer
#6 lore raw

cover uprobes: kprobes: x86: Reject probing MOV SS/POP SS

In reply to Masami Hiramatsu

Oops, I missed adding kprobes: and POP SS on subject...

Quoted 29 lines · On Wed, 9 May 2018 21:57:44 +0900 Masami Hiramatsu <[email protected]> wrote:

Hi,

I found the CVE-2018-1087 and CVE-2018-8897 should be related to kprobes and uprobes too, since both are using #DB for single stepping.

I decided to just reject probes on MOV SS and POP SS because those are not recommended to use (Intel SDM recommend to use LSS instead), thus it might be rare case.

Oleg, could you review the uprobes patch?

Thank you,

---

Masami Hiramatsu (2):
kprobes: x86: Prohibit probing on exception masking instructions
uprobes: x86: Prohibit probing on MOV SS instruction

 arch/x86/include/asm/insn.h    |   18 ++++++++++++++++++
 arch/x86/kernel/kprobes/core.c |    4 ++++
 arch/x86/kernel/uprobes.c      |    4 ++++
 3 files changed, 26 insertions(+)

--
Masami Hiramatsu (Linaro) <[email protected]>

Signature · 1 line
Masami Hiramatsu <[email protected]>
#7 lore raw
In reply to Masami Hiramatsu
Quoted 5 lines · Masami Hiramatsu

Hi,

I found the CVE-2018-1087 and CVE-2018-8897 should be related to kprobes and uprobes too, since both are using #DB for single stepping.

Seems okay to me. I doubt we have a security problem, but I can easily imagine that the probes wouldn't work right.

author maintainer
#8 lore raw
Quoted 11 lines · On Wed, 09 May 2018 14:36:27 +0000 Andy Lutomirski <[email protected]> wrote:
Quoted 5 lines · Masami Hiramatsu

Hi,

I found the CVE-2018-1087 and CVE-2018-8897 should be related to kprobes and uprobes too, since both are using #DB for single stepping.

Seems okay to me. I doubt we have a security problem, but I can easily imagine that the probes wouldn't work right.

Sorry for confusion, yes, that will not be a security issue, since kprobes and uprobes can be used only by root user.

Thank you,

Signature · 1 line
Masami Hiramatsu <[email protected]>