Hi all,
I'm trying to play with kernel probes (kprobe, jprobe & kretprobe) but it does not seem to work on a pax-enabled kernel.
The "problem" (probably a feature, right) seems to come from "CONFIG_GRKERNSEC_HIDESYM", is there a way to make it compatible ?
If not, shouldn't this option disable CONFIG_KPROBES ?
More details:
Without CONFIG_GRKERNSEC_HIDESYM:
'''
# insmod /lib/modules/3.9.9-hardened/kernel/samples/kprobes/kretprobe_example.ko
# insmod /lib/modules/3.9.9-hardened/kernel/samples/kprobes/kprobe_example.ko
# insmod /lib/modules/3.9.9-hardened/kernel/samples/kprobes/jprobe_example.ko
# dmesg -c
[ 990.206134] Planted return probe at do_fork: ffffffff81042e90
[ 993.036279] do_fork returned 1811 and took 459352 ns to execute
[ 993.042004] Planted kprobe at ffffffff81042e90
[ 996.234982] pre_handler: p->addr = 0xffffffff81042e90, ip = ffffffff81042e91, flags = 0x246
[ 996.234995] post_handler: p->addr = 0xffffffff81042e90, flags = 0x246
[ 996.235658] do_fork returned 1812 and took 662402 ns to execute
[ 996.240575] pre_handler: p->addr = 0xffffffff81042e90, ip = ffffffff81042e91, flags = 0x246
[ 996.240587] post_handler: p->addr = 0xffffffff81042e90, flags = 0x246
[ 996.240836] do_fork returned 1813 and took 249500 ns to execute
[ 996.242885] Planted jprobe at ffffffff81042e90, handler addr ffffffffa0010000
[ 998.365686] pre_handler: p->addr = 0xffffffff81042e90, ip = ffffffff81042e91, flags = 0x246
[ 998.365700] jprobe: clone_flags = 0x1200011, stack_size = 0x0, regs = 0x (nil)
[ 998.365707] post_handler: p->addr = 0xffffffff81042e90, flags = 0x246
[ 998.365966] do_fork returned 1814 and took 265981 ns to execute
'''
With CONFIG_GRKERNSEC_HIDESYM:
'''
# insmod /lib/modules/3.9.9-hardened/kernel/samples/kprobes/jprobe_example.ko
insmod: ERROR: could not insert module /lib/modules/3.9.9-hardened/kernel/samples/kprobes/jprobe_example.ko: Operation not permitted
# insmod /lib/modules/3.9.9-hardened/kernel/samples/kprobes/kprobe_example.ko
insmod: ERROR: could not insert module /lib/modules/3.9.9-hardened/kernel/samples/kprobes/kprobe_example.ko: Unknown symbol in module
# insmod /lib/modules/3.9.9-hardened/kernel/samples/kprobes/kretprobe_example.ko
insmod: ERROR: could not insert module /lib/modules/3.9.9-hardened/kernel/samples/kprobes/kretprobe_example.ko: Operation not permitted
# dmesg -c
[ 370.049241] register_jprobes: kallsyms_lookup_size_offset: 0, offset 0
[ 370.049249] register_jprobe failed, returned -22
[ 372.598819] kprobe_addr: !kprobe_lookup_name(p->symbol_name, addr)
[ 372.598827] register_kprobe: IS_ERR(kprobe_addr(p))
[ 372.598831] register_kprobe failed, returned -2
[ 375.879601] kprobe_addr: !kprobe_lookup_name(p->symbol_name, addr)
[ 375.879610] register_kretprobe failed, returned -2
'''
Those error message (lookup) come from my following small patch:
'''
--- kernel/kprobes.c.orig 2013-08-15 11:36:44.814699323 +0200
+++ kernel/kprobes.c 2013-08-15 12:02:17.553935292 +0200
@@ -1368,8 +1368,10 @@
if (p->symbol_name) {
kprobe_lookup_name(p->symbol_name, addr);
- if (!addr)
+ if (!addr) {
+ printk(KERN_ERR "kprobe_addr: !kprobe_lookup_name(p->symbol_name, addr)\n");
return ERR_PTR(-ENOENT);
+ }
}
addr = (kprobe_opcode_t *)(((char *)addr) + p->offset);
@@ -1485,8 +1487,10 @@
/* Adjust probe address from symbol */
addr = kprobe_addr(p);
- if (IS_ERR(addr))
+ if (IS_ERR(addr)) {
+ printk(KERN_ERR "register_kprobe: IS_ERR(kprobe_addr(p))\n");
return PTR_ERR(addr);
+ }
p->addr = addr;
ret = check_kprobe_rereg(p);
@@ -1720,13 +1724,16 @@
addr = arch_deref_entry_point(jp->entry);
/* Verify probepoint is a function entry point */
- if (kallsyms_lookup_size_offset(addr, NULL, &offset) &&
+ offset = 0;
+ if ((ret = kallsyms_lookup_size_offset(addr, NULL, &offset)) &&
offset == 0) {
jp->kp.pre_handler = setjmp_pre_handler;
jp->kp.break_handler = longjmp_break_handler;
ret = register_kprobe(&jp->kp);
- } else
+ } else {
+ printk(KERN_ERR "register_jprobes: kallsyms_lookup_size_offset: %i, offset %lu\n", ret, offset);
ret = -EINVAL;
+ }
if (ret < 0) {
if (i > 0)
'''