From 840b7e60cad04649cce4679588164d193025c697 Mon Sep 17 00:00:00 2001
From: alex <alex>
Date: Sun, 18 Jul 2004 08:36:01 +0000
Subject: [PATCH] - teached to catch double-free messy

---
 .../slab-use-after-free-debug-2.4.24.patch    | 132 ++++++++++--------
 1 file changed, 75 insertions(+), 57 deletions(-)

diff --git a/lustre/kernel_patches/patches/slab-use-after-free-debug-2.4.24.patch b/lustre/kernel_patches/patches/slab-use-after-free-debug-2.4.24.patch
index cb03c8572f..9627033ca7 100644
--- a/lustre/kernel_patches/patches/slab-use-after-free-debug-2.4.24.patch
+++ b/lustre/kernel_patches/patches/slab-use-after-free-debug-2.4.24.patch
@@ -1,8 +1,8 @@
 %patch
 Index: linux-2.4.24/mm/slab.c
 ===================================================================
---- linux-2.4.24.orig/mm/slab.c	2004-07-14 18:14:27.000000000 +0400
-+++ linux-2.4.24/mm/slab.c	2004-07-16 15:54:07.000000000 +0400
+--- linux-2.4.24.orig/mm/slab.c	2004-07-16 09:33:00.000000000 -0400
++++ linux-2.4.24/mm/slab.c	2004-07-17 08:02:02.000000000 -0400
 @@ -97,6 +97,8 @@
  #define	FORCED_DEBUG	0
  #endif
@@ -88,7 +88,7 @@ Index: linux-2.4.24/mm/slab.c
  	local_irq_save(flags);
  	CHECK_PAGE(virt_to_page(objp));
  	c = GET_PAGE_CACHE(virt_to_page(objp));
-@@ -2076,3 +2110,471 @@
+@@ -2076,3 +2110,478 @@
  #endif
  }
  #endif
@@ -112,7 +112,7 @@ Index: linux-2.4.24/mm/slab.c
 +	atomic_t uaf_failed;
 +};
 +
-+static int uaf_max = 32768;
++static int uaf_max = 8192;
 +static void *uaf_bitmap = NULL;
 +static spinlock_t uaf_lock;
 +static int uaf_last_found = 0;
@@ -349,7 +349,8 @@ Index: linux-2.4.24/mm/slab.c
 +	unsigned long flags;
 +	int i, j;
 +
-+	uaf_printk("UAF: to free 0x%p/%d\n", addr, size);
++	if (cachep->flags & SLAB_USE_UAF)
++		uaf_printk("UAF: to free 0x%p/%d\n", addr, size);
 +
 +	size = (size + (PAGE_SIZE - 1)) / PAGE_SIZE;
 +	if (size > MAX_UAF_OBJ_SIZE)
@@ -363,6 +364,32 @@ Index: linux-2.4.24/mm/slab.c
 +		(unsigned) addr >= (unsigned) uaf_area->addr + uaf_area->size)
 +		return 0;
 +
++	uaf_printk("UAF: to free 0x%p/%d\n", addr, size);
++
++	/* calculate placement in bitmap */
++	i = (unsigned) addr - (unsigned) uaf_area->addr;
++	UAF_ASSERT(i >= 0);
++	i = i / PAGE_SIZE;
++
++	/* check against double-free */
++	spin_lock_irqsave(&uaf_lock, flags);
++	for (j = 0; j < size; j++) {
++		/* now check is correspondend bit set */
++		unsigned long address;
++		UAF_ASSERT(i+j >= 0 && i+j < uaf_max);
++		BUG_ON(!test_bit(i+j, uaf_bitmap));
++
++		address = ((unsigned long) addr) + (PAGE_SIZE * j);
++		pages[j] = vmalloc_to_page((void *) address);
++		BUG_ON(pages[j] == NULL);
++
++		/* now free space in UAF */
++		clear_bit(i+j, uaf_bitmap);
++		uaf_used--;
++	}
++	spin_unlock_irqrestore(&uaf_lock, flags);
++
++	/* check poison bytes */
 +	if (cachep->objsize < PAGE_SIZE) {
 +		unsigned char *a = (void *) addr;
 +		for (i = 0; i < PAGE_SIZE - cachep->objsize; i++)
@@ -380,35 +407,11 @@ Index: linux-2.4.24/mm/slab.c
 +	UAF_ASSERT(i >= 0);
 +	i = i / PAGE_SIZE;
 +
-+	/* collect all the pages */
-+	uaf_printk("free/unmap %d pages: ", size);
-+	/* NOTE: we need not page_table_lock here. bits in bitmap
-+	 * protect those pte's from to be reused */
-+	for (j = 0; j < size; j++) {
-+		unsigned long address;
-+		address = ((unsigned long) addr) + (PAGE_SIZE * j);
-+		pages[j] = vmalloc_to_page((void *) address);
-+		uaf_printk("0x%lx->0x%p ", address, pages[j]);
-+	}
-+	uaf_printk("\n");
-+
 +	uaf_unmap((unsigned long) addr, PAGE_SIZE * size);
 +	/* free all the pages */
 +	for (j = 0; j < size; j++)
 +		__free_page(pages[j]);
 +
-+	spin_lock_irqsave(&uaf_lock, flags);
-+	for (j = 0; j < size; j++) {
-+		/* now check is correspondend bit set */
-+		UAF_ASSERT(i+j >= 0 && i+j < uaf_max);
-+		UAF_ASSERT(test_bit(i+j, uaf_bitmap));
-+		
-+		/* now free space in UAF */
-+		clear_bit(i+j, uaf_bitmap);
-+		uaf_used--;
-+	}
-+	spin_unlock_irqrestore(&uaf_lock, flags);
-+
 +	atomic_dec(&uaf_stats[size].uaf_allocated);
 +	
 +	uaf_printk("UAF: freed %d/%d at 0x%p\n", i, size, addr);
@@ -468,8 +471,12 @@ Index: linux-2.4.24/mm/slab.c
 +
 +	if (!n)
 +		seq_printf(m, "size(pgs) allocated failed allocations. "
-+				"%d reserved, %d in use, %d last\n",
-+				uaf_max, uaf_used, uaf_last_found);
++				"%d reserved, %d in use, %d last\n"
++				"start 0x%p, size %lu, bitmap 0x%p\n"
++				"VMALLOC_START 0x%x, VMALLOC_END 0x%x\n",
++				uaf_max, uaf_used, uaf_last_found,
++				uaf_area->addr, uaf_area->size,
++				uaf_bitmap, VMALLOC_START, VMALLOC_END);
 +	else if (n > MAX_UAF_OBJ_SIZE)
 +		return NULL;
 +
@@ -562,8 +569,8 @@ Index: linux-2.4.24/mm/slab.c
 +
 Index: linux-2.4.24/mm/vmalloc.c
 ===================================================================
---- linux-2.4.24.orig/mm/vmalloc.c	2004-06-24 09:03:26.000000000 +0400
-+++ linux-2.4.24/mm/vmalloc.c	2004-07-16 15:54:07.000000000 +0400
+--- linux-2.4.24.orig/mm/vmalloc.c	2004-07-16 09:24:01.000000000 -0400
++++ linux-2.4.24/mm/vmalloc.c	2004-07-16 13:55:05.000000000 -0400
 @@ -53,7 +53,7 @@
  	} while (address < end);
  }
@@ -584,8 +591,8 @@ Index: linux-2.4.24/mm/vmalloc.c
  					pgprot_t prot,
 Index: linux-2.4.24/mm/page_alloc.c
 ===================================================================
---- linux-2.4.24.orig/mm/page_alloc.c	2004-07-14 18:14:27.000000000 +0400
-+++ linux-2.4.24/mm/page_alloc.c	2004-07-16 16:11:49.000000000 +0400
+--- linux-2.4.24.orig/mm/page_alloc.c	2004-07-16 09:33:00.000000000 -0400
++++ linux-2.4.24/mm/page_alloc.c	2004-07-16 13:55:05.000000000 -0400
 @@ -91,6 +91,12 @@
  	zone_t *zone;
  
@@ -601,8 +608,8 @@ Index: linux-2.4.24/mm/page_alloc.c
  	 * a reference to a page in order to pin it for io. -ben
 Index: linux-2.4.24/init/main.c
 ===================================================================
---- linux-2.4.24.orig/init/main.c	2004-06-24 09:06:32.000000000 +0400
-+++ linux-2.4.24/init/main.c	2004-07-16 15:54:07.000000000 +0400
+--- linux-2.4.24.orig/init/main.c	2004-07-16 09:24:01.000000000 -0400
++++ linux-2.4.24/init/main.c	2004-07-16 13:55:05.000000000 -0400
 @@ -437,6 +437,9 @@
  #if defined(CONFIG_SYSVIPC)
  	ipc_init();
@@ -615,8 +622,8 @@ Index: linux-2.4.24/init/main.c
  
 Index: linux-2.4.24/fs/proc/proc_misc.c
 ===================================================================
---- linux-2.4.24.orig/fs/proc/proc_misc.c	2004-06-24 09:06:31.000000000 +0400
-+++ linux-2.4.24/fs/proc/proc_misc.c	2004-07-16 15:54:07.000000000 +0400
+--- linux-2.4.24.orig/fs/proc/proc_misc.c	2004-07-16 09:23:51.000000000 -0400
++++ linux-2.4.24/fs/proc/proc_misc.c	2004-07-16 13:55:05.000000000 -0400
 @@ -303,6 +303,22 @@
  	release:	seq_release,
  };
@@ -652,8 +659,8 @@ Index: linux-2.4.24/fs/proc/proc_misc.c
  #endif
 Index: linux-2.4.24/include/linux/slab.h
 ===================================================================
---- linux-2.4.24.orig/include/linux/slab.h	2004-07-16 10:25:19.000000000 +0400
-+++ linux-2.4.24/include/linux/slab.h	2004-07-16 15:54:13.000000000 +0400
+--- linux-2.4.24.orig/include/linux/slab.h	2004-07-16 09:33:00.000000000 -0400
++++ linux-2.4.24/include/linux/slab.h	2004-07-17 05:26:51.000000000 -0400
 @@ -40,6 +40,7 @@
  #define	SLAB_HWCACHE_ALIGN	0x00002000UL	/* align objs on a h/w cache lines */
  #define SLAB_CACHE_DMA		0x00004000UL	/* use GFP_DMA memory */
@@ -664,8 +671,8 @@ Index: linux-2.4.24/include/linux/slab.h
  #define	SLAB_CTOR_CONSTRUCTOR	0x001UL		/* if not set, then deconstructor */
 Index: linux-2.4.24/include/asm-i386/io.h
 ===================================================================
---- linux-2.4.24.orig/include/asm-i386/io.h	2004-07-16 10:25:19.000000000 +0400
-+++ linux-2.4.24/include/asm-i386/io.h	2004-07-16 15:54:13.000000000 +0400
+--- linux-2.4.24.orig/include/asm-i386/io.h	2004-07-16 09:23:54.000000000 -0400
++++ linux-2.4.24/include/asm-i386/io.h	2004-07-17 05:27:02.000000000 -0400
 @@ -75,6 +75,16 @@
   
  static inline unsigned long virt_to_phys(volatile void * address)
@@ -685,9 +692,9 @@ Index: linux-2.4.24/include/asm-i386/io.h
  
 Index: linux-2.4.24/include/asm-i386/page.h
 ===================================================================
---- linux-2.4.24.orig/include/asm-i386/page.h	2004-07-14 18:14:27.000000000 +0400
-+++ linux-2.4.24/include/asm-i386/page.h	2004-07-16 15:54:07.000000000 +0400
-@@ -131,9 +131,49 @@
+--- linux-2.4.24.orig/include/asm-i386/page.h	2004-07-16 09:33:00.000000000 -0400
++++ linux-2.4.24/include/asm-i386/page.h	2004-07-17 05:26:19.000000000 -0400
+@@ -131,9 +131,60 @@
  #define VMALLOC_RESERVE		((unsigned long)__VMALLOC_RESERVE)
  #define __MAXMEM		(-__PAGE_OFFSET-__VMALLOC_RESERVE)
  #define MAXMEM			((unsigned long)(-PAGE_OFFSET-VMALLOC_RESERVE))
@@ -721,12 +728,23 @@ Index: linux-2.4.24/include/asm-i386/page.h
 +				}						\
 +				((void *)((unsigned long)(x) + PAGE_OFFSET));	\
 +			})
-+
++#ifndef PKMAP_BASE
++#define PKMAP_BASE (0xfe000000UL)
++#endif
 +#define virt_to_page(ka) ({							\
 +				struct page *_p;				\
-+				if ((unsigned long)(ka) >= VMALLOC_START) {	\
++				if ((unsigned)(ka) >= VMALLOC_START &&		\
++						(unsigned)(ka) < VMALLOC_END) {	\
 +					_p = vmalloc_to_page((void *)(ka));	\
-+					BUG_ON(!_p);				\
++					if (!_p) {				\
++						printk(KERN_ALERT		\
++							"wrong address 0x%x, "	\
++							"VMALLOC_START 0x%x\n",	\
++							(unsigned) (ka),	\
++						(unsigned)VMALLOC_START);	\
++					_p = mem_map+(__pa(ka) >> PAGE_SHIFT);	\
++						dump_stack();			\
++					}					\
 +				} else 						\
 +					_p = mem_map+(__pa(ka) >> PAGE_SHIFT);	\
 +				(_p);						\
@@ -739,8 +757,8 @@ Index: linux-2.4.24/include/asm-i386/page.h
  #define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | VM_EXEC | \
 Index: linux-2.4.24/arch/i386/config.in
 ===================================================================
---- linux-2.4.24.orig/arch/i386/config.in	2004-07-16 15:54:07.000000000 +0400
-+++ linux-2.4.24/arch/i386/config.in	2004-07-16 15:54:07.000000000 +0400
+--- linux-2.4.24.orig/arch/i386/config.in	2004-07-16 09:33:02.000000000 -0400
++++ linux-2.4.24/arch/i386/config.in	2004-07-16 13:55:05.000000000 -0400
 @@ -509,6 +509,9 @@
     bool '  Check for stack overflows' CONFIG_DEBUG_STACKOVERFLOW
     bool '  Debug high memory support' CONFIG_DEBUG_HIGHMEM
@@ -753,9 +771,9 @@ Index: linux-2.4.24/arch/i386/config.in
     bool '  Spinlock debugging' CONFIG_DEBUG_SPINLOCK
 Index: linux-2.4.24/kernel/ksyms.c
 ===================================================================
---- linux-2.4.24.orig/kernel/ksyms.c	2004-07-13 11:07:55.000000000 +0400
-+++ linux-2.4.24/kernel/ksyms.c	2004-07-16 20:59:09.000000000 +0400
-@@ -117,6 +117,8 @@
+--- linux-2.4.24.orig/kernel/ksyms.c	2004-07-16 09:36:49.000000000 -0400
++++ linux-2.4.24/kernel/ksyms.c	2004-07-16 13:55:05.000000000 -0400
+@@ -123,6 +123,8 @@
  EXPORT_SYMBOL(kfree);
  EXPORT_SYMBOL(vfree);
  EXPORT_SYMBOL(__vmalloc);
@@ -769,12 +787,12 @@ Index: linux-2.4.24/kernel/ksyms.c
  arch/i386/config.in     |    3 
  fs/proc/proc_misc.c     |   19 +
  include/asm-i386/io.h   |   10 
- include/asm-i386/page.h |   40 +++
+ include/asm-i386/page.h |   51 ++++
  include/linux/slab.h    |    1 
  init/main.c             |    3 
  kernel/ksyms.c          |    2 
  mm/page_alloc.c         |    6 
- mm/slab.c               |  506 +++++++++++++++++++++++++++++++++++++++++++++++-
+ mm/slab.c               |  513 +++++++++++++++++++++++++++++++++++++++++++++++-
  mm/vmalloc.c            |    4 
- 10 files changed, 590 insertions(+), 4 deletions(-)
+ 10 files changed, 608 insertions(+), 4 deletions(-)
 
-- 
GitLab