summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrea Arcangeli <andrea@novell.com>2005-03-07 17:38:45 -0800
committerLinus Torvalds <torvalds@ppc970.osdl.org>2005-03-07 17:38:45 -0800
commit54fe2b5bfa8887f57cfff32c81d124b56d9de3ac (patch)
tree1ed035b71df560d209a796bd7d42a9b101681ee6
parentb525cd4479e68f1d642b58c1e8c5ea22f4889b11 (diff)
[PATCH] fix iounmap and a pageattr memleak (x86 and x86-64)
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> Signed-off-by: Linus Torvalds <torvalds@osdl.org>
-rw-r--r--mm/vmalloc.c15
1 files changed, 11 insertions, 4 deletions
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 43b264efe6b7..1b585ad47fa5 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -256,20 +256,22 @@ struct vm_struct *__get_vm_area(unsigned long size, unsigned long flags,
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;
}