aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/avr32/kernel/kprobes.c2
-rw-r--r--arch/ia64/kernel/kprobes.c2
-rw-r--r--arch/powerpc/kernel/kprobes.c2
-rw-r--r--arch/s390/kernel/kprobes.c2
-rw-r--r--arch/sparc64/kernel/kprobes.c2
-rw-r--r--arch/x86/kernel/kprobes_32.c7
-rw-r--r--arch/x86/kernel/kprobes_64.c7
-rw-r--r--arch/x86/kernel/process_64.c2
-rw-r--r--include/asm-avr32/kprobes.h2
-rw-r--r--include/asm-ia64/kprobes.h1
-rw-r--r--include/asm-powerpc/kprobes.h1
-rw-r--r--include/asm-s390/kprobes.h1
-rw-r--r--include/asm-sparc64/kprobes.h2
-rw-r--r--include/asm-x86/kprobes_32.h2
-rw-r--r--include/asm-x86/kprobes_64.h1
-rw-r--r--include/linux/kprobes.h6
-rw-r--r--kernel/kprobes.c23
17 files changed, 64 insertions, 1 deletions
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index 4942ee662e0b..20b1c9d8f945 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -22,6 +22,8 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe);
22static unsigned long kprobe_status; 22static unsigned long kprobe_status;
23static struct pt_regs jprobe_saved_regs; 23static struct pt_regs jprobe_saved_regs;
24 24
25struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
26
25int __kprobes arch_prepare_kprobe(struct kprobe *p) 27int __kprobes arch_prepare_kprobe(struct kprobe *p)
26{ 28{
27 int ret = 0; 29 int ret = 0;
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 5dc98b5abcfb..5fd65d8302c8 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -40,6 +40,8 @@ extern void jprobe_inst_return(void);
40DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 40DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
41DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 41DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
42 42
43struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
44
43enum instruction_type {A, I, M, F, B, L, X, u}; 45enum instruction_type {A, I, M, F, B, L, X, u};
44static enum instruction_type bundle_encoding[32][3] = { 46static enum instruction_type bundle_encoding[32][3] = {
45 { M, I, I }, /* 00 */ 47 { M, I, I }, /* 00 */
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 440f5a87271f..5338e4855712 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -38,6 +38,8 @@
38DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 38DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
39DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 39DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
40 40
41struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
42
41int __kprobes arch_prepare_kprobe(struct kprobe *p) 43int __kprobes arch_prepare_kprobe(struct kprobe *p)
42{ 44{
43 int ret = 0; 45 int ret = 0;
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index e40373d9fbce..c5549a206284 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -33,6 +33,8 @@
33DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 33DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
34DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 34DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
35 35
36struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
37
36int __kprobes arch_prepare_kprobe(struct kprobe *p) 38int __kprobes arch_prepare_kprobe(struct kprobe *p)
37{ 39{
38 /* Make sure the probe isn't going on a difficult instruction */ 40 /* Make sure the probe isn't going on a difficult instruction */
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index c93a15b785fa..d94f901d321e 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -42,6 +42,8 @@
42DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 42DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
43DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 43DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
44 44
45struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
46
45int __kprobes arch_prepare_kprobe(struct kprobe *p) 47int __kprobes arch_prepare_kprobe(struct kprobe *p)
46{ 48{
47 p->ainsn.insn[0] = *p->addr; 49 p->ainsn.insn[0] = *p->addr;
diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c
index 06b86e5617f6..90f778c04b3f 100644
--- a/arch/x86/kernel/kprobes_32.c
+++ b/arch/x86/kernel/kprobes_32.c
@@ -41,6 +41,13 @@ void jprobe_return_end(void);
41DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 41DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
42DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 42DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
43 43
44struct kretprobe_blackpoint kretprobe_blacklist[] = {
45 {"__switch_to", }, /* This function switches only current task, but
46 doesn't switch kernel stack.*/
47 {NULL, NULL} /* Terminator */
48};
49const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
50
44/* insert a jmp code */ 51/* insert a jmp code */
45static __always_inline void set_jmp_op(void *from, void *to) 52static __always_inline void set_jmp_op(void *from, void *to)
46{ 53{
diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c
index 7c16506d681f..681b801c5e26 100644
--- a/arch/x86/kernel/kprobes_64.c
+++ b/arch/x86/kernel/kprobes_64.c
@@ -48,6 +48,13 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p);
48DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 48DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
49DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 49DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
50 50
51struct kretprobe_blackpoint kretprobe_blacklist[] = {
52 {"__switch_to", }, /* This function switches only current task, but
53 doesn't switch kernel stack.*/
54 {NULL, NULL} /* Terminator */
55};
56const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
57
51/* 58/*
52 * returns non-zero if opcode modifies the interrupt flag. 59 * returns non-zero if opcode modifies the interrupt flag.
53 */ 60 */
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 7352d4b377e6..6309b275cb9c 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -581,7 +581,7 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
581 * 581 *
582 * Kprobes not supported here. Set the probe on schedule instead. 582 * Kprobes not supported here. Set the probe on schedule instead.
583 */ 583 */
584__kprobes struct task_struct * 584struct task_struct *
585__switch_to(struct task_struct *prev_p, struct task_struct *next_p) 585__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
586{ 586{
587 struct thread_struct *prev = &prev_p->thread, 587 struct thread_struct *prev = &prev_p->thread,
diff --git a/include/asm-avr32/kprobes.h b/include/asm-avr32/kprobes.h
index 0f3e636e6e4d..996cb656474e 100644
--- a/include/asm-avr32/kprobes.h
+++ b/include/asm-avr32/kprobes.h
@@ -17,6 +17,8 @@ typedef u16 kprobe_opcode_t;
17#define BREAKPOINT_INSTRUCTION 0xd673 /* breakpoint */ 17#define BREAKPOINT_INSTRUCTION 0xd673 /* breakpoint */
18#define MAX_INSN_SIZE 2 18#define MAX_INSN_SIZE 2
19 19
20#define kretprobe_blacklist_size 0
21
20#define arch_remove_kprobe(p) do { } while (0) 22#define arch_remove_kprobe(p) do { } while (0)
21 23
22/* Architecture specific copy of original instruction */ 24/* Architecture specific copy of original instruction */
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h
index 6c79edf24d73..a93ce9ef07ff 100644
--- a/include/asm-ia64/kprobes.h
+++ b/include/asm-ia64/kprobes.h
@@ -83,6 +83,7 @@ struct kprobe_ctlblk {
83}; 83};
84 84
85#define ARCH_SUPPORTS_KRETPROBES 85#define ARCH_SUPPORTS_KRETPROBES
86#define kretprobe_blacklist_size 0
86 87
87#define SLOT0_OPCODE_SHIFT (37) 88#define SLOT0_OPCODE_SHIFT (37)
88#define SLOT1_p1_OPCODE_SHIFT (37 - (64-46)) 89#define SLOT1_p1_OPCODE_SHIFT (37 - (64-46))
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index c16973d5de62..afabad230dbb 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -82,6 +82,7 @@ typedef unsigned int kprobe_opcode_t;
82 82
83#define ARCH_SUPPORTS_KRETPROBES 83#define ARCH_SUPPORTS_KRETPROBES
84#define flush_insn_slot(p) do { } while (0) 84#define flush_insn_slot(p) do { } while (0)
85#define kretprobe_blacklist_size 0
85 86
86void kretprobe_trampoline(void); 87void kretprobe_trampoline(void);
87extern void arch_remove_kprobe(struct kprobe *p); 88extern void arch_remove_kprobe(struct kprobe *p);
diff --git a/include/asm-s390/kprobes.h b/include/asm-s390/kprobes.h
index 8bc67cc9ffd2..948db3d0d05c 100644
--- a/include/asm-s390/kprobes.h
+++ b/include/asm-s390/kprobes.h
@@ -47,6 +47,7 @@ typedef u16 kprobe_opcode_t;
47 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) 47 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
48 48
49#define ARCH_SUPPORTS_KRETPROBES 49#define ARCH_SUPPORTS_KRETPROBES
50#define kretprobe_blacklist_size 0
50 51
51#define KPROBE_SWAP_INST 0x10 52#define KPROBE_SWAP_INST 0x10
52 53
diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h
index a04145b77f96..5020eaf67c29 100644
--- a/include/asm-sparc64/kprobes.h
+++ b/include/asm-sparc64/kprobes.h
@@ -10,6 +10,8 @@ typedef u32 kprobe_opcode_t;
10#define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */ 10#define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */
11#define MAX_INSN_SIZE 2 11#define MAX_INSN_SIZE 2
12 12
13#define kretprobe_blacklist_size 0
14
13#define arch_remove_kprobe(p) do {} while (0) 15#define arch_remove_kprobe(p) do {} while (0)
14 16
15#define flush_insn_slot(p) \ 17#define flush_insn_slot(p) \
diff --git a/include/asm-x86/kprobes_32.h b/include/asm-x86/kprobes_32.h
index f2489d07ce88..b772d5b38685 100644
--- a/include/asm-x86/kprobes_32.h
+++ b/include/asm-x86/kprobes_32.h
@@ -45,6 +45,8 @@ typedef u8 kprobe_opcode_t;
45#define ARCH_SUPPORTS_KRETPROBES 45#define ARCH_SUPPORTS_KRETPROBES
46#define flush_insn_slot(p) do { } while (0) 46#define flush_insn_slot(p) do { } while (0)
47 47
48extern const int kretprobe_blacklist_size;
49
48void arch_remove_kprobe(struct kprobe *p); 50void arch_remove_kprobe(struct kprobe *p);
49void kretprobe_trampoline(void); 51void kretprobe_trampoline(void);
50 52
diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h
index 3f495e5308b1..53f4d8507354 100644
--- a/include/asm-x86/kprobes_64.h
+++ b/include/asm-x86/kprobes_64.h
@@ -42,6 +42,7 @@ typedef u8 kprobe_opcode_t;
42 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) 42 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
43 43
44#define ARCH_SUPPORTS_KRETPROBES 44#define ARCH_SUPPORTS_KRETPROBES
45extern const int kretprobe_blacklist_size;
45 46
46void kretprobe_trampoline(void); 47void kretprobe_trampoline(void);
47extern void arch_remove_kprobe(struct kprobe *p); 48extern void arch_remove_kprobe(struct kprobe *p);
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 51464d12a4e5..81891581e89b 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -166,6 +166,12 @@ struct kretprobe_instance {
166 struct task_struct *task; 166 struct task_struct *task;
167}; 167};
168 168
169struct kretprobe_blackpoint {
170 const char *name;
171 void *addr;
172};
173extern struct kretprobe_blackpoint kretprobe_blacklist[];
174
169static inline void kretprobe_assert(struct kretprobe_instance *ri, 175static inline void kretprobe_assert(struct kretprobe_instance *ri,
170 unsigned long orig_ret_address, unsigned long trampoline_address) 176 unsigned long orig_ret_address, unsigned long trampoline_address)
171{ 177{
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index f9798ff7899f..e3a5d817ac9b 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -716,6 +716,18 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
716 int ret = 0; 716 int ret = 0;
717 struct kretprobe_instance *inst; 717 struct kretprobe_instance *inst;
718 int i; 718 int i;
719 void *addr = rp->kp.addr;
720
721 if (kretprobe_blacklist_size) {
722 if (addr == NULL)
723 kprobe_lookup_name(rp->kp.symbol_name, addr);
724 addr += rp->kp.offset;
725
726 for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
727 if (kretprobe_blacklist[i].addr == addr)
728 return -EINVAL;
729 }
730 }
719 731
720 rp->kp.pre_handler = pre_handler_kretprobe; 732 rp->kp.pre_handler = pre_handler_kretprobe;
721 rp->kp.post_handler = NULL; 733 rp->kp.post_handler = NULL;
@@ -794,6 +806,17 @@ static int __init init_kprobes(void)
794 INIT_HLIST_HEAD(&kretprobe_inst_table[i]); 806 INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
795 } 807 }
796 808
809 if (kretprobe_blacklist_size) {
810 /* lookup the function address from its name */
811 for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
812 kprobe_lookup_name(kretprobe_blacklist[i].name,
813 kretprobe_blacklist[i].addr);
814 if (!kretprobe_blacklist[i].addr)
815 printk("kretprobe: lookup failed: %s\n",
816 kretprobe_blacklist[i].name);
817 }
818 }
819
797 /* By default, kprobes are enabled */ 820 /* By default, kprobes are enabled */
798 kprobe_enabled = true; 821 kprobe_enabled = true;
799 822