x86/kprobes: Convert to insn_decode()
Simplify code, improve decoding error checking. Signed-off-by: Borislav Petkov <bp@suse.de> Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Link: https://lkml.kernel.org/r/20210304174237.31945-12-bp@alien8.de
This commit is contained in:
parent
1580f488ea
commit
77e768ec13
|
@ -265,6 +265,8 @@ static int can_probe(unsigned long paddr)
|
||||||
/* Decode instructions */
|
/* Decode instructions */
|
||||||
addr = paddr - offset;
|
addr = paddr - offset;
|
||||||
while (addr < paddr) {
|
while (addr < paddr) {
|
||||||
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Check if the instruction has been modified by another
|
* Check if the instruction has been modified by another
|
||||||
* kprobe, in which case we replace the breakpoint by the
|
* kprobe, in which case we replace the breakpoint by the
|
||||||
|
@ -276,8 +278,10 @@ static int can_probe(unsigned long paddr)
|
||||||
__addr = recover_probed_instruction(buf, addr);
|
__addr = recover_probed_instruction(buf, addr);
|
||||||
if (!__addr)
|
if (!__addr)
|
||||||
return 0;
|
return 0;
|
||||||
kernel_insn_init(&insn, (void *)__addr, MAX_INSN_SIZE);
|
|
||||||
insn_get_length(&insn);
|
ret = insn_decode(&insn, (void *)__addr, MAX_INSN_SIZE, INSN_MODE_KERN);
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Another debugging subsystem might insert this breakpoint.
|
* Another debugging subsystem might insert this breakpoint.
|
||||||
|
@ -301,8 +305,8 @@ static int can_probe(unsigned long paddr)
|
||||||
int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn)
|
int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn)
|
||||||
{
|
{
|
||||||
kprobe_opcode_t buf[MAX_INSN_SIZE];
|
kprobe_opcode_t buf[MAX_INSN_SIZE];
|
||||||
unsigned long recovered_insn =
|
unsigned long recovered_insn = recover_probed_instruction(buf, (unsigned long)src);
|
||||||
recover_probed_instruction(buf, (unsigned long)src);
|
int ret;
|
||||||
|
|
||||||
if (!recovered_insn || !insn)
|
if (!recovered_insn || !insn)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -312,8 +316,9 @@ int __copy_instruction(u8 *dest, u8 *src, u8 *real, struct insn *insn)
|
||||||
MAX_INSN_SIZE))
|
MAX_INSN_SIZE))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
kernel_insn_init(insn, dest, MAX_INSN_SIZE);
|
ret = insn_decode(insn, dest, MAX_INSN_SIZE, INSN_MODE_KERN);
|
||||||
insn_get_length(insn);
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* We can not probe force emulate prefixed instruction */
|
/* We can not probe force emulate prefixed instruction */
|
||||||
if (insn_has_emulate_prefix(insn))
|
if (insn_has_emulate_prefix(insn))
|
||||||
|
|
|
@ -312,6 +312,8 @@ static int can_optimize(unsigned long paddr)
|
||||||
addr = paddr - offset;
|
addr = paddr - offset;
|
||||||
while (addr < paddr - offset + size) { /* Decode until function end */
|
while (addr < paddr - offset + size) { /* Decode until function end */
|
||||||
unsigned long recovered_insn;
|
unsigned long recovered_insn;
|
||||||
|
int ret;
|
||||||
|
|
||||||
if (search_exception_tables(addr))
|
if (search_exception_tables(addr))
|
||||||
/*
|
/*
|
||||||
* Since some fixup code will jumps into this function,
|
* Since some fixup code will jumps into this function,
|
||||||
|
@ -321,8 +323,11 @@ static int can_optimize(unsigned long paddr)
|
||||||
recovered_insn = recover_probed_instruction(buf, addr);
|
recovered_insn = recover_probed_instruction(buf, addr);
|
||||||
if (!recovered_insn)
|
if (!recovered_insn)
|
||||||
return 0;
|
return 0;
|
||||||
kernel_insn_init(&insn, (void *)recovered_insn, MAX_INSN_SIZE);
|
|
||||||
insn_get_length(&insn);
|
ret = insn_decode(&insn, (void *)recovered_insn, MAX_INSN_SIZE, INSN_MODE_KERN);
|
||||||
|
if (ret < 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In the case of detecting unknown breakpoint, this could be
|
* In the case of detecting unknown breakpoint, this could be
|
||||||
* a padding INT3 between functions. Let's check that all the
|
* a padding INT3 between functions. Let's check that all the
|
||||||
|
|
Loading…
Reference in New Issue