
From: Andrea Arcangeli <andrea@novell.com>

Reject zero page vm-area request, align size properly and hide the guard page
from the callers like ioremap - this avoids a kernel crash due one more page
being passed to change_page_attr

Signed-off-by: Andrea Arcangeli <andrea@novell.com>
Signed-off-by: Andrew Morton <akpm@osdl.org>
---

 25-akpm/mm/vmalloc.c |   15 +++++++++++----
 1 files changed, 11 insertions(+), 4 deletions(-)

diff -puN mm/vmalloc.c~fix-iounmap-and-a-pageattr-memleak-x86-and-x86-64 mm/vmalloc.c
--- 25/mm/vmalloc.c~fix-iounmap-and-a-pageattr-memleak-x86-and-x86-64	2005-03-07 20:41:30.000000000 -0800
+++ 25-akpm/mm/vmalloc.c	2005-03-07 20:41:30.000000000 -0800
@@ -256,20 +256,22 @@ struct vm_struct *__get_vm_area(unsigned
 		align = 1ul << bit;
 	}
 	addr = ALIGN(start, align);
+	size = PAGE_ALIGN(size);
 
 	area = kmalloc(sizeof(*area), GFP_KERNEL);
 	if (unlikely(!area))
 		return NULL;
 
-	/*
-	 * We always allocate a guard page.
-	 */
-	size += PAGE_SIZE;
 	if (unlikely(!size)) {
 		kfree (area);
 		return NULL;
 	}
 
+	/*
+	 * We always allocate a guard page.
+	 */
+	size += PAGE_SIZE;
+
 	write_lock(&vmlist_lock);
 	for (p = &vmlist; (tmp = *p) != NULL ;p = &tmp->next) {
 		if ((unsigned long)tmp->addr < addr) {
@@ -349,6 +351,11 @@ found:
 	unmap_vm_area(tmp);
 	*p = tmp->next;
 	write_unlock(&vmlist_lock);
+
+	/*
+	 * Remove the guard page.
+	 */
+	tmp->size -= PAGE_SIZE;
 	return tmp;
 }
 
_
