Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 27922b4260f65d317aabda37e42bbbff > files > 2050

kernel-2.6.18-238.el5.src.rpm

From: Jerome Marchand <jmarchan@redhat.com>
Date: Tue, 29 Jul 2008 09:18:23 +0200
Subject: [misc] null pointer dereference in register_kretprobe
Message-id: 488EC43F.9000106@redhat.com
O-Subject: [RHEL5.3 Patch] Fix null pointer dereference in register_kretprobe()
Bugzilla: 452308
RH-Acked-by: Chuck Ebbert <cebbert@redhat.com>
RH-Acked-by: Neil Horman <nhorman@redhat.com>
RH-Acked-by: Vitaly Mayatskikh <vmayatsk@redhat.com>
RH-Acked-by: Anton Arapov <aarapov@redhat.com>

Bugzilla:
https://bugzilla.redhat.com/show_bug.cgi?id=452308

Description:
register_kretprobe() does not check that rp->kp.symbol_name is not
NULL before calling kprobe_lookup_name() and thus leads to NULL
pointer dereference.

Upstream status:
commit: b2a5cd6938879b5bcfef0a73c28fea84c49519c2

Brew build:
http://brewweb.devel.redhat.com/brew/taskinfo?taskID=1406990

Test status:
Build on all archs and tested on i686.

Regards,
Jerome

diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index d744725..ac07f87 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -454,6 +454,23 @@ static int __kprobes in_kprobes_functions(unsigned long addr)
 		return -EINVAL;
 	return 0;
 }
+/*
+* If we have a symbol_name argument, look it up and add the offset field
+* to it. This way, we can specify a relative address to a symbol.
+*/
+static kprobe_opcode_t __kprobes *kprobe_addr(struct kprobe *p)
+{
+	kprobe_opcode_t *addr = p->addr;
+	if (p->symbol_name) {
+		if (addr)
+			return NULL;
+		kprobe_lookup_name(p->symbol_name, addr);
+	}
+
+	if (!addr)
+		return NULL;
+	return (kprobe_opcode_t *)(((char *)addr) + p->offset);
+}
 
 static int __kprobes __register_kprobe(struct kprobe *p,
 	unsigned long called_from)
@@ -461,21 +478,12 @@ static int __kprobes __register_kprobe(struct kprobe *p,
 	int ret = 0;
 	struct kprobe *old_p;
 	struct module *probed_mod;
+	kprobe_opcode_t *addr;
 
-	/*
-	 * If we have a symbol_name argument look it up,
-	 * and add it to the address.  That way the addr
-	 * field can either be global or relative to a symbol.
-	 */
-	if (p->symbol_name) {
-		if (p->addr)
-			return -EINVAL;
-		kprobe_lookup_name(p->symbol_name, p->addr);
-	}
-
-	if (!p->addr)
+	addr = kprobe_addr(p);
+	if (!addr)
 		return -EINVAL;
-	p->addr = (kprobe_opcode_t *)(((char *)p->addr)+ p->offset);
+	p->addr = addr;
 
 	if ((!kernel_text_address((unsigned long) p->addr)) ||
 		in_kprobes_functions((unsigned long) p->addr))
@@ -756,12 +764,12 @@ static int __kprobes __register_kretprobe(struct kretprobe *rp,
 	int ret = 0;
 	struct kretprobe_instance *inst;
 	int i;
-	void *addr = rp->kp.addr;
+	void *addr;
 
 	if (kretprobe_blacklist_size) {
-		if (addr == NULL)
-			kprobe_lookup_name(rp->kp.symbol_name, addr);
-		addr += rp->kp.offset;
+		addr = kprobe_addr(&rp->kp);
+		if (!addr)
+			return -EINVAL;
 
 		for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
 			if (kretprobe_blacklist[i].addr == addr)