Patch from Petr Vandrovec <vandrove@vc.cvut.cz>

Modifies check_poison function to not only verify that last byte is
POISON_END, but also that all preceeding bytes are either POISON_BEFORE or
POISON_AFTER bytes.  



 mm/slab.c |   43 +++++++++++++++++++++++++++++++++++++++++--
 1 files changed, 41 insertions(+), 2 deletions(-)

diff -puN mm/slab.c~use-after-free-check mm/slab.c
--- 25/mm/slab.c~use-after-free-check	2003-03-02 18:14:44.000000000 -0800
+++ 25-akpm/mm/slab.c	2003-03-02 18:14:44.000000000 -0800
@@ -768,6 +768,21 @@ static void poison_obj(kmem_cache_t *cac
 	*(unsigned char *)(addr+size-1) = POISON_END;
 }
 
+static void *fprob(unsigned char* addr, unsigned int size)
+{
+	unsigned char *end;
+	
+	end = addr + size - 1;
+
+	for (; addr < end; addr++) {
+		if (*addr != POISON_BEFORE && *addr != POISON_AFTER)
+			return addr;
+	}
+	if (*addr != POISON_END)
+		return addr;
+	return NULL;
+}
+
 static void check_poison_obj(kmem_cache_t *cachep, void *addr)
 {
 	int size = cachep->objsize;
@@ -776,9 +791,33 @@ static void check_poison_obj(kmem_cache_
 		addr += BYTES_PER_WORD;
 		size -= 2*BYTES_PER_WORD;
 	}
-	end = memchr(addr, POISON_END, size);
-	if (end != (addr+size-1))
+	end = fprob(addr, size);
+	if (end) {
+		int s;
+		printk(KERN_ERR "Slab corruption: start=%p, expend=%p, "
+				"problemat=%p\n", addr, addr+size-1, end);
+		printk(KERN_ERR "Data: ");
+		for (s = 0; s < size; s++) {
+			if (((char*)addr)[s] == POISON_BEFORE)
+				printk(".");
+			else if (((char*)addr)[s] == POISON_AFTER)
+				printk("*");
+			else
+				printk("%02X ", ((unsigned char*)addr)[s]);
+		}
+		printk("\n");
+		printk(KERN_ERR "Next: ");
+		for (; s < size + 32; s++) {
+			if (((char*)addr)[s] == POISON_BEFORE)
+				printk(".");
+			else if (((char*)addr)[s] == POISON_AFTER)
+				printk("*");
+			else
+				printk("%02X ", ((unsigned char*)addr)[s]);
+		}
+		printk("\n");
 		slab_error(cachep, "object was modified after freeing");
+	}
 }
 #endif
 

_