Skip to content

Commit 90ec5e8

Browse files
rnavacmel
authored andcommitted
kretprobes: Ensure probe location is at function entry
kretprobes can be registered by specifying an absolute address or by specifying offset to a symbol. However, we need to ensure this falls at function entry so as to be able to determine the return address. Validate the same during kretprobe registration. By default, there should not be any offset from a function entry, as determined through a kallsyms_lookup(). Introduce arch_function_offset_within_entry() as a way for architectures to override this. Signed-off-by: Naveen N. Rao <[email protected]> Acked-by: Masami Hiramatsu <[email protected]> Cc: Ananth N Mavinakayanahalli <[email protected]> Cc: Michael Ellerman <[email protected]> Cc: Steven Rostedt <[email protected]> Cc: [email protected] Link: http://lkml.kernel.org/r/f1583bc4839a3862cfc2acefcc56f9c8837fa2ba.1487770934.git.naveen.n.rao@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent 5833596 commit 90ec5e8

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

include/linux/kprobes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,7 @@ extern int arch_init_kprobes(void);
267267
extern void show_registers(struct pt_regs *regs);
268268
extern void kprobes_inc_nmissed_count(struct kprobe *p);
269269
extern bool arch_within_kprobe_blacklist(unsigned long addr);
270+
extern bool arch_function_offset_within_entry(unsigned long offset);
270271

271272
extern bool within_kprobe_blacklist(unsigned long addr);
272273

kernel/kprobes.c

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1875,12 +1875,25 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
18751875
}
18761876
NOKPROBE_SYMBOL(pre_handler_kretprobe);
18771877

1878+
bool __weak arch_function_offset_within_entry(unsigned long offset)
1879+
{
1880+
return !offset;
1881+
}
1882+
18781883
int register_kretprobe(struct kretprobe *rp)
18791884
{
18801885
int ret = 0;
18811886
struct kretprobe_instance *inst;
18821887
int i;
18831888
void *addr;
1889+
unsigned long offset;
1890+
1891+
addr = kprobe_addr(&rp->kp);
1892+
if (!kallsyms_lookup_size_offset((unsigned long)addr, NULL, &offset))
1893+
return -EINVAL;
1894+
1895+
if (!arch_function_offset_within_entry(offset))
1896+
return -EINVAL;
18841897

18851898
if (kretprobe_blacklist_size) {
18861899
addr = kprobe_addr(&rp->kp);

0 commit comments

Comments
 (0)