summaryrefslogtreecommitdiffstats
path: root/kernel/kprobes.c
diff options
context:
space:
mode:
authorNaveen N. Rao <naveen.n.rao@linux.vnet.ibm.com>2017-02-22 08:53:37 -0500
committerArnaldo Carvalho de Melo <acme@redhat.com>2017-03-03 17:07:17 -0500
commit90ec5e89e393c76e19afc845d8f88a5dc8315919 (patch)
tree95fe1e1d60938f6a3102ce9bbff8ed99cdb072b4 /kernel/kprobes.c
parent583359646fde8526ea9456618cc24dc359b34094 (diff)
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 <naveen.n.rao@linux.vnet.ibm.com> Acked-by: Masami Hiramatsu <mhiramat@kernel.org> Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com> Cc: Michael Ellerman <mpe@ellerman.id.au> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: linuxppc-dev@lists.ozlabs.org Link: http://lkml.kernel.org/r/f1583bc4839a3862cfc2acefcc56f9c8837fa2ba.1487770934.git.naveen.n.rao@linux.vnet.ibm.com Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Diffstat (limited to 'kernel/kprobes.c')
-rw-r--r--kernel/kprobes.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 699c5bc51a92..448759d4a263 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -1875,12 +1875,25 @@ static int pre_handler_kretprobe(struct kprobe *p, struct pt_regs *regs)
1875} 1875}
1876NOKPROBE_SYMBOL(pre_handler_kretprobe); 1876NOKPROBE_SYMBOL(pre_handler_kretprobe);
1877 1877
1878bool __weak arch_function_offset_within_entry(unsigned long offset)
1879{
1880 return !offset;
1881}
1882
1878int register_kretprobe(struct kretprobe *rp) 1883int register_kretprobe(struct kretprobe *rp)
1879{ 1884{
1880 int ret = 0; 1885 int ret = 0;
1881 struct kretprobe_instance *inst; 1886 struct kretprobe_instance *inst;
1882 int i; 1887 int i;
1883 void *addr; 1888 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;
1884 1897
1885 if (kretprobe_blacklist_size) { 1898 if (kretprobe_blacklist_size) {
1886 addr = kprobe_addr(&rp->kp); 1899 addr = kprobe_addr(&rp->kp);