diff options
-rw-r--r-- | include/linux/uprobes.h | 9 | ||||
-rw-r--r-- | kernel/events/uprobes.c | 18 |
2 files changed, 20 insertions, 7 deletions
diff --git a/include/linux/uprobes.h b/include/linux/uprobes.h index 83742b91ff73..c2df6934fdc6 100644 --- a/include/linux/uprobes.h +++ b/include/linux/uprobes.h | |||
@@ -35,8 +35,17 @@ struct inode; | |||
35 | # include <asm/uprobes.h> | 35 | # include <asm/uprobes.h> |
36 | #endif | 36 | #endif |
37 | 37 | ||
38 | enum uprobe_filter_ctx { | ||
39 | UPROBE_FILTER_REGISTER, | ||
40 | UPROBE_FILTER_UNREGISTER, | ||
41 | UPROBE_FILTER_MMAP, | ||
42 | }; | ||
43 | |||
38 | struct uprobe_consumer { | 44 | struct uprobe_consumer { |
39 | int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs); | 45 | int (*handler)(struct uprobe_consumer *self, struct pt_regs *regs); |
46 | bool (*filter)(struct uprobe_consumer *self, | ||
47 | enum uprobe_filter_ctx ctx, | ||
48 | struct mm_struct *mm); | ||
40 | 49 | ||
41 | struct uprobe_consumer *next; | 50 | struct uprobe_consumer *next; |
42 | }; | 51 | }; |
diff --git a/kernel/events/uprobes.c b/kernel/events/uprobes.c index 33912086d54e..c2737be3c4b8 100644 --- a/kernel/events/uprobes.c +++ b/kernel/events/uprobes.c | |||
@@ -579,19 +579,21 @@ static int prepare_uprobe(struct uprobe *uprobe, struct file *file, | |||
579 | return ret; | 579 | return ret; |
580 | } | 580 | } |
581 | 581 | ||
582 | static inline bool consumer_filter(struct uprobe_consumer *uc) | 582 | static inline bool consumer_filter(struct uprobe_consumer *uc, |
583 | enum uprobe_filter_ctx ctx, struct mm_struct *mm) | ||
583 | { | 584 | { |
584 | return true; /* TODO: !uc->filter || uc->filter(...) */ | 585 | return !uc->filter || uc->filter(uc, ctx, mm); |
585 | } | 586 | } |
586 | 587 | ||
587 | static bool filter_chain(struct uprobe *uprobe) | 588 | static bool filter_chain(struct uprobe *uprobe, |
589 | enum uprobe_filter_ctx ctx, struct mm_struct *mm) | ||
588 | { | 590 | { |
589 | struct uprobe_consumer *uc; | 591 | struct uprobe_consumer *uc; |
590 | bool ret = false; | 592 | bool ret = false; |
591 | 593 | ||
592 | down_read(&uprobe->consumer_rwsem); | 594 | down_read(&uprobe->consumer_rwsem); |
593 | for (uc = uprobe->consumers; uc; uc = uc->next) { | 595 | for (uc = uprobe->consumers; uc; uc = uc->next) { |
594 | ret = consumer_filter(uc); | 596 | ret = consumer_filter(uc, ctx, mm); |
595 | if (ret) | 597 | if (ret) |
596 | break; | 598 | break; |
597 | } | 599 | } |
@@ -772,10 +774,12 @@ static int register_for_each_vma(struct uprobe *uprobe, bool is_register) | |||
772 | 774 | ||
773 | if (is_register) { | 775 | if (is_register) { |
774 | /* consult only the "caller", new consumer. */ | 776 | /* consult only the "caller", new consumer. */ |
775 | if (consumer_filter(uprobe->consumers)) | 777 | if (consumer_filter(uprobe->consumers, |
778 | UPROBE_FILTER_REGISTER, mm)) | ||
776 | err = install_breakpoint(uprobe, mm, vma, info->vaddr); | 779 | err = install_breakpoint(uprobe, mm, vma, info->vaddr); |
777 | } else if (test_bit(MMF_HAS_UPROBES, &mm->flags)) { | 780 | } else if (test_bit(MMF_HAS_UPROBES, &mm->flags)) { |
778 | if (!filter_chain(uprobe)) | 781 | if (!filter_chain(uprobe, |
782 | UPROBE_FILTER_UNREGISTER, mm)) | ||
779 | err |= remove_breakpoint(uprobe, mm, info->vaddr); | 783 | err |= remove_breakpoint(uprobe, mm, info->vaddr); |
780 | } | 784 | } |
781 | 785 | ||
@@ -968,7 +972,7 @@ int uprobe_mmap(struct vm_area_struct *vma) | |||
968 | */ | 972 | */ |
969 | list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { | 973 | list_for_each_entry_safe(uprobe, u, &tmp_list, pending_list) { |
970 | if (!fatal_signal_pending(current) && | 974 | if (!fatal_signal_pending(current) && |
971 | filter_chain(uprobe)) { | 975 | filter_chain(uprobe, UPROBE_FILTER_MMAP, vma->vm_mm)) { |
972 | unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset); | 976 | unsigned long vaddr = offset_to_vaddr(vma, uprobe->offset); |
973 | install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); | 977 | install_breakpoint(uprobe, vma->vm_mm, vma, vaddr); |
974 | } | 978 | } |