kprobes: Support __kprobes and NOKPROBE_SYMBOL in modules
Subsystems (2)
Masami Hiramatsu
maintainercover kprobes: Support __kprobes and NOKPROBE_SYMBOL in modules
Hi,
Here is a series for adding support of __kprobes attribute and NOKPROBE_SYMBOL() macro in modules. With this series, kprobes user can add its handlers and sub-functions to kprobe blacklist so that other kprobes don't probe it.
Note that user should not use both __kprobes and NOKPROBE_SYMBOL() to same function. In that case, the function will appear twice on the blacklist, and that is a waste of memory.
Thomas, it is easy to add ".noinstr.text" support to this series. as same as __kprobes (.kprobes.text) support in [2/4], we can add mod->noinstr_text_start and mod->noinstr_text_size and register it in add_module_kprobe_blacklist().
Thank you,
---
Masami Hiramatsu (4):
kprobes: Lock kprobe_mutex while showing kprobe_blacklist
kprobes: Support __kprobes blacklist in modules
kprobes: Support NOKPROBE_SYMBOL() in modules samples/kprobes: Add __kprobes and NOKPROBE_SYMBOL() for handlers.
include/linux/module.h | 6 +++ kernel/kprobes.c | 67 ++++++++++++++++++++++++++++++++++- kernel/module.c | 7 ++++ samples/kprobes/kprobe_example.c | 6 ++- samples/kprobes/kretprobe_example.c | 2 + 5 files changed, 85 insertions(+), 3 deletions(-)
--
Masami Hiramatsu (Linaro) <[email protected]>
Masami Hiramatsu
maintainerPATCH 1/4 kprobes: Lock kprobe_mutex while showing kprobe_blacklist
Lock kprobe_mutex while showing kprobe_blacklist to prevent updating the kprobe_blacklist.
--- kernel/kprobes.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
kernel/kprobes.c +7 -1
@@ -2420,6 +2420,7 @@ static const struct file_operations debugfs_kprobes_operations = {/* kprobes/blacklist -- shows which functions can not be probed */ static void *kprobe_blacklist_seq_start (struct seq_file *m,loff_t *pos) { +mutex_lock (&kprobe_mutex);return seq_list_start (&kprobe_blacklist, *pos); }
@@ -2446,10 +2447,15 @@ static int kprobe_blacklist_seq_show(struct seq_file *m, void *v)return 0 ; } +static void kprobe_blacklist_seq_stop (struct seq_file *f,void *v) +{ +mutex_unlock (&kprobe_mutex); +} +static const struct seq_operations kprobe_blacklist_seq_ops = { .start = kprobe_blacklist_seq_start, .next = kprobe_blacklist_seq_next, - .stop = kprobe_seq_stop,/* Reuse void function */ + .stop = kprobe_blacklist_seq_stop, .show = kprobe_blacklist_seq_show, };
Masami Hiramatsu
maintainerPATCH 2/4 kprobes: Support __kprobes blacklist in modules
In reply to Masami HiramatsuSupport __kprobes attribute for blacklist functions in modules. The __kprobes attribute functions are stored in .kprobes.text section.
--- include/linux/module.h | 4 ++++ kernel/kprobes.c | 42 ++++++++++++++++++++++++++++++++++++++++++ kernel/module.c | 4 ++++ 3 files changed, 50 insertions(+)
include/linux/module.h +4 -0
@@ -489,6 +489,10 @@ struct module {unsigned int num_ftrace_callsites;unsigned long *ftrace_callsites;#endif +#ifdef CONFIG_KPROBES +void *kprobes_text_start; +unsigned int kprobes_text_size; +#endif #ifdef CONFIG_LIVEPATCH bool klp;/* Is this a livepatch module? */
kernel/kprobes.c +42 -0
66 lines not on this page · raw message
kernel/module.c +4 -0
@@ -3193,6 +3193,10 @@ static int find_module_sections(struct module *mod, struct load_info *info) mod->ei_funcs =section_objs (info,"_error_injection_whitelist" ,sizeof (*mod->ei_funcs), &mod->num_ei_funcs); +#endif +#ifdef CONFIG_KPROBES + mod->kprobes_text_start =section_objs (info,".kprobes.text" ,1 , + &mod->kprobes_text_size);#endif mod->extable =section_objs (info,"__ex_table" ,sizeof (*mod->extable), &mod->num_exentries);
Masami Hiramatsu
maintainerPATCH 3/4 kprobes: Support NOKPROBE_SYMBOL() in modules
In reply to Masami HiramatsuSupport NOKPROBE_SYMBOL() in modules. NOKPROBE_SYMBOL() records only symbol address in "_kprobe_blacklist" section in the module.
--- include/linux/module.h | 2 ++ kernel/kprobes.c | 17 +++++++++++++++++ kernel/module.c | 3 +++ 3 files changed, 22 insertions(+)
include/linux/module.h +2 -0
@@ -492,6 +492,8 @@ struct module {#ifdef CONFIG_KPROBES void *kprobes_text_start;unsigned int kprobes_text_size; +unsigned long *kprobe_blacklist; +unsigned int num_kprobe_blacklist;#endif #ifdef CONFIG_LIVEPATCH
kernel/kprobes.c +17 -0
@@ -2192,6 +2192,11 @@ static void kprobe_remove_area_blacklist(unsigned long start, unsigned long end) } } +static void kprobe_remove_ksym_blacklist (unsigned long entry) +{ +kprobe_remove_area_blacklist (entry, entry +1 ); +} +int __init __weak arch_populate_kprobe_blacklist (void ) {return 0 ;
@@ -2231,6 +2236,12 @@ static int __init populate_kprobe_blacklist(unsigned long *start,static void add_module_kprobe_blacklist (struct module *mod) {unsigned long start, end; +int i; + +if (mod->kprobe_blacklist) { +for (i =0 ; i < mod->num_kprobe_blacklist; i++) +kprobe_add_ksym_blacklist (mod->kprobe_blacklist[i]); + } start = (unsigned long )mod->kprobes_text_start;if (start) {
@@ -2242,6 +2253,12 @@ static void add_module_kprobe_blacklist(struct module *mod)static void remove_module_kprobe_blacklist (struct module *mod) {unsigned long start, end; +int i; + +if (mod->kprobe_blacklist) { +for (i =0 ; i < mod->num_kprobe_blacklist; i++) +kprobe_remove_ksym_blacklist (mod->kprobe_blacklist[i]); + } start = (unsigned long )mod->kprobes_text_start;if (start) {
kernel/module.c +3 -0
@@ -3197,6 +3197,9 @@ static int find_module_sections(struct module *mod, struct load_info *info)#ifdef CONFIG_KPROBES mod->kprobes_text_start =section_objs (info,".kprobes.text" ,1 , &mod->kprobes_text_size); + mod->kprobe_blacklist =section_objs (info,"_kprobe_blacklist" , +sizeof (unsigned long ), + &mod->num_kprobe_blacklist);#endif mod->extable =section_objs (info,"__ex_table" ,sizeof (*mod->extable), &mod->num_exentries);
Masami Hiramatsu
maintainerPATCH 4/4 samples/kprobes: Add __kprobes and NOKPROBE_SYMBOL() for handlers.
In reply to Masami HiramatsuAdd __kprobes and NOKPROBE_SYMBOL() for sample
kprobe handlers.
--- samples/kprobes/kprobe_example.c | 6 ++++-- samples/kprobes/kretprobe_example.c | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-)
samples/kprobes/kprobe_example.c +4 -2
@@ -25,7 +25,7 @@ static struct kprobe kp = { };/* kprobe pre_handler: called just before the probed instruction is executed */ -static int handler_pre (struct kprobe *p,struct pt_regs *regs) +static int __kprobes handler_pre (struct kprobe *p,struct pt_regs *regs) {#ifdef CONFIG_X86 pr_info("<%s> pre_handler: p->addr = 0x%p, ip = %lx, flags = 0x%lx\n",
@@ -54,7 +54,7 @@ static int handler_pre(struct kprobe *p, struct pt_regs *regs) }/* kprobe post_handler: called after the probed instruction is executed */ -static void handler_post (struct kprobe *p,struct pt_regs *regs, +static void __kprobes handler_post (struct kprobe *p,struct pt_regs *regs,unsigned long flags) {#ifdef CONFIG_X86
@@ -90,6 +90,8 @@ static int handler_fault(struct kprobe *p, struct pt_regs *regs, int trapnr)/* Return 0 because we don't handle the fault. */ return 0 ; } +/* NOKPROBE_SYMBOL() is also available */ +NOKPROBE_SYMBOL (handler_fault);static int __init kprobe_init (void ) {
samples/kprobes/kretprobe_example.c +2 -0
@@ -48,6 +48,7 @@ static int entry_handler(struct kretprobe_instance *ri, struct pt_regs *regs) data->entry_stamp =ktime_get ();return 0 ; } +NOKPROBE_SYMBOL (entry_handler);/* * Return-probe handler: Log the return value and duration. Duration may turn
@@ -67,6 +68,7 @@ static int ret_handler(struct kretprobe_instance *ri, struct pt_regs *regs) func_name, retval, (long long)delta);return 0 ; } +NOKPROBE_SYMBOL (ret_handler);static struct kretprobe my_kretprobe = { .handler = ret_handler,