Kprobes: Verify probepoint in register_jprobe()
PATCH 1/1 Kprobes: Verify probepoint in register_jprobe()
This patch, built against version 2.6.12, checks if probepoint address is a function entry point using an offset value, obtained from kallsyms_lookup(). If offset is zero, we register jprobe, otherwise we return -EINVAL.
kernel/kprobes.c renamed from kernel/kprobes.c.orig +10 -1
@@ -33,6 +33,7 @@#include <linux/hash.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/kallsyms.h> #include <asm/cacheflush.h> #include <asm/errno.h> #include <asm/kdebug.h>
@@ -245,7 +246,15 @@ static struct notifier_block kprobe_exceint register_jprobe (struct jprobe *jp) { -/* Todo: Verify probepoint is a function entry point */ +unsigned long size, offset; +char *modname, namebuf[KSYM_NAME_LEN +1 ]; + +kallsyms_lookup ((unsigned long )jp->kp.addr, &size, + &offset, &modname, namebuf); + +if (unlikely (offset)) +return -EINVAL ; + jp->kp.pre_handler = setjmp_pre_handler; jp->kp.break_handler = longjmp_break_handler;
Regards,
Signature · 1 line
Luca
Quoted 5 lines · Luca Falavigna
This patch, built against version 2.6.12, checks if probepoint address is a function entry point using an offset value, obtained from
kallsyms_lookup(). If offset is zero, we register jprobe, otherwise we return-EINVAL.
a) kallsyms holds symbols other than just function names.
b) This won't work with CONFIG_KALLSYMS=n
Quoted 28 lines
kernel/kprobes.c renamed from kernel/kprobes.c.orig +10
-1@@ -33,6 +33,7 @@#include <linux/hash.h> #include <linux/init.h> #include <linux/module.h> +#include <linux/kallsyms.h> #include <asm/cacheflush.h> #include <asm/errno.h> #include <asm/kdebug.h> @@ -245,7 +246,15 @@ static struct notifier_block kprobe_exceint register_jprobe (struct jprobe *jp) { -/* Todo: Verify probepoint is a function entry point */ +unsigned long size, offset; +char *modname, namebuf[KSYM_NAME_LEN +1 ]; + +kallsyms_lookup ((unsigned long )jp->kp.addr, &size, + &offset, &modname, namebuf); + +if (unlikely (offset)) +return -EINVAL ; + jp->kp.pre_handler = setjmp_pre_handler; jp->kp.break_handler = longjmp_break_handler;
kernel/kprobes.c static struct notifier_block kprobe_exce · line 256
Quoted 12 lines · Luca Falavigna
[...]
intregister_jprobe(struct jprobe *jp)
{kernel/kprobes.c renamed from kernel/kprobes.c.orig +8
-1-/* Todo: Verify probepoint is a function entry point */ +unsigned long size, offset; +char *modname, namebuf[KSYM_NAME_LEN +1 ]; + +kallsyms_lookup ((unsigned long )jp->kp.addr, &size, + &offset, &modname, namebuf); + +if (unlikely (offset)) +return -EINVAL ;
Hmmm, kallsyms_lookup might return NULL if either the address is not found or CONFIG_KALLSYMS is not set, and in this case "offset" is not initialized at all before this test.
We should either fail in this case, or accept the address as valid without confirmation. I don't have sufficient knowledge about kprobes to advise either way, but a test should be made nevertheless (or we could just initialize "offset" to 0, if we want to accept the address without confirmation).
Signature · 5 lines
Paulo Marques - www.grupopie.com It is a mistake to think you can solve any major problems just with potatoes. Douglas Adams