This is the mail archive of the systemtap@sourceware.org mailing list for the systemtap project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH] To refuse users from probing preempt_schedule()


Hi 

This patch disallows user from probing preempt_schedule(). As
preempt_schedule() already attributed to __sched section, I have used
the "blacklist" approach.
kprobe blacklist approach is somewhat different from kretprobe blacklist,
because in kprobe user can probe any instruction inside the function and
hence we need verify the user specified address with start and end of the
 blacklisted function.

I have collected address and size of the blacklisted function during
init_kprobes() and verify the range of address(start-end of blacklisted
function)with the user specified address during kprobes registration time.

please let me know your comments.


---
 include/linux/kprobes.h |    7 +++++++
 kernel/kprobes.c        |   34 ++++++++++++++++++++++++++++++++++
 2 files changed, 41 insertions(+)

Index: linux-2.6.25-rc2/include/linux/kprobes.h
===================================================================
--- linux-2.6.25-rc2.orig/include/linux/kprobes.h
+++ linux-2.6.25-rc2/include/linux/kprobes.h
@@ -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,
Index: linux-2.6.25-rc2/kernel/kprobes.c
===================================================================
--- linux-2.6.25-rc2.orig/kernel/kprobes.c
+++ linux-2.6.25-rc2/kernel/kprobes.c
@@ -89,6 +89,11 @@ struct kprobe_insn_page {
 	int ngarbage;
 };
 
+struct kprobe_blackpoint kprobe_blacklist[] = {
+        {"preempt_schedule",},
+        {NULL}    /* Terminator */
+};
+
 enum kprobe_slot_state {
 	SLOT_CLEAN = 0,
 	SLOT_DIRTY = 1,
@@ -492,9 +497,20 @@ static int __kprobes register_aggr_kprob
 
 static int __kprobes in_kprobes_functions(unsigned long addr)
 {
+	int i;
+
 	if (addr >= (unsigned long)__kprobes_text_start &&
 	    addr < (unsigned long)__kprobes_text_end)
 		return -EINVAL;
+
+	for (i = 0; kprobe_blacklist[i].name != NULL; i++) {
+		if (kprobe_blacklist[i].start_addr) {
+			if (addr >= kprobe_blacklist[i].start_addr &&
+			    addr < (kprobe_blacklist[i].start_addr +
+			                  kprobe_blacklist[i].range))
+				return -EINVAL;
+		}
+	}
 	return 0;
 }
 
@@ -805,6 +821,10 @@ void __kprobes unregister_kretprobe(stru
 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;
 
 	/* FIXME allocate the probe table, currently defined statically */
 	/* initialize all list heads */
@@ -813,6 +833,20 @@ static int __init init_kprobes(void)
 		INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
 	}
 
+	for (i = 0; kprobe_blacklist[i].name != NULL; i++) {
+		kprobe_lookup_name(kprobe_blacklist[i].name, addr);
+		if (!addr)
+			continue;
+
+		kprobe_blacklist[i].start_addr = (unsigned long)addr;
+		symbol_name = kallsyms_lookup(kprobe_blacklist[i].start_addr,
+				&size, &offset, &modname, namebuf);
+		if (!symbol_name)
+			kprobe_blacklist[i].range = 0;
+		else
+			kprobe_blacklist[i].range = size;
+	}
+
 	if (kretprobe_blacklist_size) {
 		/* lookup the function address from its name */
 		for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]