Skip to content

Commit 2f706e0

Browse files
mhiramatIngo Molnar
authored andcommitted
x86/kprobes: Fix to identify indirect jmp and others using range case
Fix can_boost() to identify indirect jmp and others using range case correctly. Since the condition in switch statement is opcode & 0xf0, it can not evaluate to 0xff case. This should be under the 0xf0 case. However, there is no reason to use the conbinations of the bit-masked condition and lower bit checking. Use range case to clean up the switch statement too. Fixes: 6256e66 ("x86/kprobes: Use int3 instead of debug trap for single-step") Reported-by: Colin Ian King <[email protected]> Signed-off-by: Masami Hiramatsu <[email protected]> Signed-off-by: Ingo Molnar <[email protected]> Link: https://lore.kernel.org/r/161666692308.1120877.4675552834049546493.stgit@devnote2
1 parent 6dd3b8c commit 2f706e0

File tree

1 file changed

+20
-24
lines changed

1 file changed

+20
-24
lines changed

arch/x86/kernel/kprobes/core.c

Lines changed: 20 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -164,32 +164,28 @@ int can_boost(struct insn *insn, void *addr)
164164

165165
opcode = insn->opcode.bytes[0];
166166

167-
switch (opcode & 0xf0) {
168-
case 0x60:
169-
/* can't boost "bound" */
170-
return (opcode != 0x62);
171-
case 0x70:
172-
return 0; /* can't boost conditional jump */
173-
case 0x90:
174-
return opcode != 0x9a; /* can't boost call far */
175-
case 0xc0:
176-
/* can't boost software-interruptions */
177-
return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf;
178-
case 0xd0:
179-
/* can boost AA* and XLAT */
180-
return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7);
181-
case 0xe0:
182-
/* can boost in/out and absolute jmps */
183-
return ((opcode & 0x04) || opcode == 0xea);
184-
case 0xf0:
185-
/* clear and set flags are boostable */
186-
return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe));
187-
case 0xff:
188-
/* indirect jmp is boostable */
167+
switch (opcode) {
168+
case 0x62: /* bound */
169+
case 0x70 ... 0x7f: /* Conditional jumps */
170+
case 0x9a: /* Call far */
171+
case 0xc0 ... 0xc1: /* Grp2 */
172+
case 0xcc ... 0xce: /* software exceptions */
173+
case 0xd0 ... 0xd3: /* Grp2 */
174+
case 0xd6: /* (UD) */
175+
case 0xd8 ... 0xdf: /* ESC */
176+
case 0xe0 ... 0xe3: /* LOOP*, JCXZ */
177+
case 0xe8 ... 0xe9: /* near Call, JMP */
178+
case 0xeb: /* Short JMP */
179+
case 0xf0 ... 0xf4: /* LOCK/REP, HLT */
180+
case 0xf6 ... 0xf7: /* Grp3 */
181+
case 0xfe: /* Grp4 */
182+
/* ... are not boostable */
183+
return 0;
184+
case 0xff: /* Grp5 */
185+
/* Only indirect jmp is boostable */
189186
return X86_MODRM_REG(insn->modrm.bytes[0]) == 4;
190187
default:
191-
/* call is not boostable */
192-
return opcode != 0x9a;
188+
return 1;
193189
}
194190
}
195191

0 commit comments

Comments
 (0)