[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
PATCH - bug in vfree
Linus,
I posted this bug on the kernel mailing list last year, but it never got
fixed, probably as I didn't include a patch. I attach a patch this time
against kernel 2.2.1. The bug is rare, but can lead to kernel virtual
memory corruption.
Quick description:- vfree forgets to subtract the extra cushion page
from the size of each virtual memory area stored in vmlist when it calls
vmfree_area_pages. This means that only the vmalloc-requested size is
allocated by vmalloc_area_pages, but the requested size PLUS the cushion
page is freed by vmfree_area_pages.
More deeply:- Close inspection of get_vm_area reveals that
(intentionally?) it does NOT insist there be a cushion page behind a VMA
that is placed in front of a previously-allocated VMA, it ONLY
guarantees that a cushion page lies in front of newly-allocated VMAs.
Thus two VMAs could be immediately adjacent without a cushion page, and
coupled with the vfree bug means that vfree-ing the first VMA also frees
the first page of the second VMA, with dire consequences.
I have described this as clearly as I can, I hope it makes sense. Alan,
this same bug also exists in 2.0.36.
Neil.
--- linux/mm/vmalloc.c~ Sun Jan 24 19:21:06 1999
+++ linux/mm/vmalloc.c Sat Feb 20 20:17:11 1999
@@ -187,7 +187,7 @@
for (p = &vmlist ; (tmp = *p) ; p = &tmp->next) {
if (tmp->addr == addr) {
*p = tmp->next;
- vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size);
+ vmfree_area_pages(VMALLOC_VMADDR(tmp->addr), tmp->size - PAGE_SIZE);
kfree(tmp);
return;
}