Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 94107
b: refs/heads/master
c: 3d8d996
h: refs/heads/master
i:
  94105: 311ac57
  94103: 026541a
v: v3
  • Loading branch information
Srinivasa Ds authored and Linus Torvalds committed Apr 28, 2008
1 parent 617a593 commit 1e5e666
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 1 deletion.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0341a4d0fdd2a0a3d9e2bb3a9afef9f8292c8502
refs/heads/master: 3d8d996e0ca5b4093203d3f050b0f70b5c949ae8
7 changes: 7 additions & 0 deletions trunk/include/linux/kprobes.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,13 @@ struct kretprobe_blackpoint {
const char *name;
void *addr;
};

struct kprobe_blackpoint {
const char *name;
unsigned long start_addr;
unsigned long range;
};

extern struct kretprobe_blackpoint kretprobe_blacklist[];

static inline void kretprobe_assert(struct kretprobe_instance *ri,
Expand Down
52 changes: 52 additions & 0 deletions trunk/kernel/kprobes.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,18 @@ DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */
static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;

/*
* Normally, functions that we'd want to prohibit kprobes in, are marked
* __kprobes. But, there are cases where such functions already belong to
* a different section (__sched for preempt_schedule)
*
* For such cases, we now have a blacklist
*/
struct kprobe_blackpoint kprobe_blacklist[] = {
{"preempt_schedule",},
{NULL} /* Terminator */
};

#ifdef __ARCH_WANT_KPROBES_INSN_SLOT
/*
* kprobe->ainsn.insn points to the copy of the instruction to be
Expand Down Expand Up @@ -492,9 +504,22 @@ static int __kprobes register_aggr_kprobe(struct kprobe *old_p,

static int __kprobes in_kprobes_functions(unsigned long addr)
{
struct kprobe_blackpoint *kb;

if (addr >= (unsigned long)__kprobes_text_start &&
addr < (unsigned long)__kprobes_text_end)
return -EINVAL;
/*
* If there exists a kprobe_blacklist, verify and
* fail any probe registration in the prohibited area
*/
for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
if (kb->start_addr) {
if (addr >= kb->start_addr &&
addr < (kb->start_addr + kb->range))
return -EINVAL;
}
}
return 0;
}

Expand Down Expand Up @@ -811,6 +836,11 @@ void __kprobes unregister_kretprobe(struct kretprobe *rp)
static int __init init_kprobes(void)
{
int i, err = 0;
unsigned long offset = 0, size = 0;
char *modname, namebuf[128];
const char *symbol_name;
void *addr;
struct kprobe_blackpoint *kb;

/* FIXME allocate the probe table, currently defined statically */
/* initialize all list heads */
Expand All @@ -819,6 +849,28 @@ static int __init init_kprobes(void)
INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
}

/*
* Lookup and populate the kprobe_blacklist.
*
* Unlike the kretprobe blacklist, we'll need to determine
* the range of addresses that belong to the said functions,
* since a kprobe need not necessarily be at the beginning
* of a function.
*/
for (kb = kprobe_blacklist; kb->name != NULL; kb++) {
kprobe_lookup_name(kb->name, addr);
if (!addr)
continue;

kb->start_addr = (unsigned long)addr;
symbol_name = kallsyms_lookup(kb->start_addr,
&size, &offset, &modname, namebuf);
if (!symbol_name)
kb->range = 0;
else
kb->range = size;
}

if (kretprobe_blacklist_size) {
/* lookup the function address from its name */
for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
Expand Down

0 comments on commit 1e5e666

Please sign in to comment.