Re: [PATCH][kprobes] support kretprobe-blacklist take2

2007-08-22 Thread Ananth N Mavinakayanahalli
On Tue, Aug 21, 2007 at 05:01:19PM -0400, Masami Hiramatsu wrote:
> Hi Andrew,
> 
> I updated my patch and removed #ifdefs from it.
> Thank you,
> 
> Masami Hiramatsu
> Hitachi Computer Products (America), Inc.
> 
> 
> This patch introduces architecture dependent kretprobe
> blacklists to prohibit users from inserting return
> probes on the function in which kprobes can be inserted
> but kretprobes can not.
> This patch also removes "__kprobes" mark from "__switch_to" on x86_64
> and registers "__switch_to" to the blacklist on x86-64, because that mark
> is to prohibit user from inserting only kretprobe.
> 
> 
> Signed-off-by: Masami Hiramatsu <[EMAIL PROTECTED]>

Acked-by: Ananth N Mavinakayanahalli <[EMAIL PROTECTED]>

> 
> ---
>  arch/avr32/kernel/kprobes.c   |2 ++
>  arch/i386/kernel/kprobes.c|7 +++
>  arch/ia64/kernel/kprobes.c|2 ++
>  arch/powerpc/kernel/kprobes.c |2 ++
>  arch/s390/kernel/kprobes.c|2 ++
>  arch/sparc64/kernel/kprobes.c |2 ++
>  arch/x86_64/kernel/kprobes.c  |7 +++
>  arch/x86_64/kernel/process.c  |2 +-
>  include/asm-avr32/kprobes.h   |2 ++
>  include/asm-i386/kprobes.h|2 ++
>  include/asm-ia64/kprobes.h|1 +
>  include/asm-powerpc/kprobes.h |1 +
>  include/asm-s390/kprobes.h|1 +
>  include/asm-sparc64/kprobes.h |2 ++
>  include/asm-x86_64/kprobes.h  |1 +
>  include/linux/kprobes.h   |6 ++
>  kernel/kprobes.c  |   23 +++
>  17 files changed, 64 insertions(+), 1 deletion(-)
> 
> Index: 2.6.23-rc2-mm2/arch/i386/kernel/kprobes.c
> ===
> --- 2.6.23-rc2-mm2.orig/arch/i386/kernel/kprobes.c
> +++ 2.6.23-rc2-mm2/arch/i386/kernel/kprobes.c
> @@ -42,6 +42,13 @@ void jprobe_return_end(void);
>  DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
>  DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
> 
> +struct kretprobe_blackpoint kretprobe_blacklist[] = {
> + {"__switch_to", }, /* This function switches only current task, but
> +  doesn't switch kernel stack.*/
> + {NULL, NULL}/* Terminator */
> +};
> +const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
> +
>  /* insert a jmp code */
>  static __always_inline void set_jmp_op(void *from, void *to)
>  {
> Index: 2.6.23-rc2-mm2/kernel/kprobes.c
> ===
> --- 2.6.23-rc2-mm2.orig/kernel/kprobes.c
> +++ 2.6.23-rc2-mm2/kernel/kprobes.c
> @@ -716,6 +716,18 @@ int __kprobes register_kretprobe(struct
>   int ret = 0;
>   struct kretprobe_instance *inst;
>   int i;
> + void *addr = rp->kp.addr;
> +
> + if (kretprobe_blacklist_size) {
> + if (addr == NULL)
> + kprobe_lookup_name(rp->kp.symbol_name, addr);
> + addr += rp->kp.offset;
> +
> + for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
> + if (kretprobe_blacklist[i].addr == addr)
> + return -EINVAL;
> + }
> + }
> 
>   rp->kp.pre_handler = pre_handler_kretprobe;
>   rp->kp.post_handler = NULL;
> @@ -794,6 +806,17 @@ static int __init init_kprobes(void)
>   INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
>   }
> 
> + if (kretprobe_blacklist_size) {
> + /* lookup the function address from its name */
> + for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
> + kprobe_lookup_name(kretprobe_blacklist[i].name,
> +kretprobe_blacklist[i].addr);
> + if (!kretprobe_blacklist[i].addr)
> + printk("kretprobe: lookup failed: %s\n",
> +kretprobe_blacklist[i].name);
> + }
> + }
> +
>   /* By default, kprobes are enabled */
>   kprobe_enabled = true;
> 
> Index: 2.6.23-rc2-mm2/arch/x86_64/kernel/kprobes.c
> ===
> --- 2.6.23-rc2-mm2.orig/arch/x86_64/kernel/kprobes.c
> +++ 2.6.23-rc2-mm2/arch/x86_64/kernel/kprobes.c
> @@ -49,6 +49,13 @@ static void __kprobes arch_copy_kprobe(s
>  DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
>  DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
> 
> +struct kretprobe_blackpoint kretprobe_blacklist[] = {
> + {"__switch_to", }, /* This function switches only current task, but
> +   doesn't switch kernel stack.*/
> + {NULL, NULL}/* Terminator */
> +};
> +const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
> +
>  /*
>   * returns non-zero if opcode modifies the interrupt flag.
>   */
> Index: 2.6.23-rc2-mm2/include/linux/kprobes.h
> ===
> --- 2.6.23-rc2-mm2.orig/include/linux/kprobes.h
> +++ 2.6.23-rc2-mm2/include/linux/kprobes

[PATCH][kprobes] support kretprobe-blacklist take2

2007-08-21 Thread Masami Hiramatsu
Hi Andrew,

I updated my patch and removed #ifdefs from it.
Thank you,

Masami Hiramatsu
Hitachi Computer Products (America), Inc.


This patch introduces architecture dependent kretprobe
blacklists to prohibit users from inserting return
probes on the function in which kprobes can be inserted
but kretprobes can not.
This patch also removes "__kprobes" mark from "__switch_to" on x86_64
and registers "__switch_to" to the blacklist on x86-64, because that mark
is to prohibit user from inserting only kretprobe.


Signed-off-by: Masami Hiramatsu <[EMAIL PROTECTED]>

---
 arch/avr32/kernel/kprobes.c   |2 ++
 arch/i386/kernel/kprobes.c|7 +++
 arch/ia64/kernel/kprobes.c|2 ++
 arch/powerpc/kernel/kprobes.c |2 ++
 arch/s390/kernel/kprobes.c|2 ++
 arch/sparc64/kernel/kprobes.c |2 ++
 arch/x86_64/kernel/kprobes.c  |7 +++
 arch/x86_64/kernel/process.c  |2 +-
 include/asm-avr32/kprobes.h   |2 ++
 include/asm-i386/kprobes.h|2 ++
 include/asm-ia64/kprobes.h|1 +
 include/asm-powerpc/kprobes.h |1 +
 include/asm-s390/kprobes.h|1 +
 include/asm-sparc64/kprobes.h |2 ++
 include/asm-x86_64/kprobes.h  |1 +
 include/linux/kprobes.h   |6 ++
 kernel/kprobes.c  |   23 +++
 17 files changed, 64 insertions(+), 1 deletion(-)

Index: 2.6.23-rc2-mm2/arch/i386/kernel/kprobes.c
===
--- 2.6.23-rc2-mm2.orig/arch/i386/kernel/kprobes.c
+++ 2.6.23-rc2-mm2/arch/i386/kernel/kprobes.c
@@ -42,6 +42,13 @@ void jprobe_return_end(void);
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);

+struct kretprobe_blackpoint kretprobe_blacklist[] = {
+   {"__switch_to", }, /* This function switches only current task, but
+doesn't switch kernel stack.*/
+   {NULL, NULL}/* Terminator */
+};
+const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
+
 /* insert a jmp code */
 static __always_inline void set_jmp_op(void *from, void *to)
 {
Index: 2.6.23-rc2-mm2/kernel/kprobes.c
===
--- 2.6.23-rc2-mm2.orig/kernel/kprobes.c
+++ 2.6.23-rc2-mm2/kernel/kprobes.c
@@ -716,6 +716,18 @@ int __kprobes register_kretprobe(struct
int ret = 0;
struct kretprobe_instance *inst;
int i;
+   void *addr = rp->kp.addr;
+
+   if (kretprobe_blacklist_size) {
+   if (addr == NULL)
+   kprobe_lookup_name(rp->kp.symbol_name, addr);
+   addr += rp->kp.offset;
+
+   for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
+   if (kretprobe_blacklist[i].addr == addr)
+   return -EINVAL;
+   }
+   }

rp->kp.pre_handler = pre_handler_kretprobe;
rp->kp.post_handler = NULL;
@@ -794,6 +806,17 @@ static int __init init_kprobes(void)
INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
}

+   if (kretprobe_blacklist_size) {
+   /* lookup the function address from its name */
+   for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
+   kprobe_lookup_name(kretprobe_blacklist[i].name,
+  kretprobe_blacklist[i].addr);
+   if (!kretprobe_blacklist[i].addr)
+   printk("kretprobe: lookup failed: %s\n",
+  kretprobe_blacklist[i].name);
+   }
+   }
+
/* By default, kprobes are enabled */
kprobe_enabled = true;

Index: 2.6.23-rc2-mm2/arch/x86_64/kernel/kprobes.c
===
--- 2.6.23-rc2-mm2.orig/arch/x86_64/kernel/kprobes.c
+++ 2.6.23-rc2-mm2/arch/x86_64/kernel/kprobes.c
@@ -49,6 +49,13 @@ static void __kprobes arch_copy_kprobe(s
 DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
 DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);

+struct kretprobe_blackpoint kretprobe_blacklist[] = {
+   {"__switch_to", }, /* This function switches only current task, but
+ doesn't switch kernel stack.*/
+   {NULL, NULL}/* Terminator */
+};
+const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
+
 /*
  * returns non-zero if opcode modifies the interrupt flag.
  */
Index: 2.6.23-rc2-mm2/include/linux/kprobes.h
===
--- 2.6.23-rc2-mm2.orig/include/linux/kprobes.h
+++ 2.6.23-rc2-mm2/include/linux/kprobes.h
@@ -166,6 +166,12 @@ struct kretprobe_instance {
struct task_struct *task;
 };

+struct kretprobe_blackpoint {
+   const char *name;
+   void *addr;
+};
+extern struct kretprobe_blackpoint kretprobe_blacklist[];
+
 static inline void kretprobe_assert(struct kretprobe_instance *