Patch from Hugh Dickins Hugh's patch fixes vm_area_struct slab corruption due to mremap's move_vma mistaking how do_munmap splits vmas in one case. Neither of us are very happy with it - it is fragile, and obscure. Hugh will revisit this later, but for now it should fix up the potential memory corruption. mm/mmap.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff -puN mm/mmap.c~vm_area-use-after-free-fix mm/mmap.c --- 25/mm/mmap.c~vm_area-use-after-free-fix 2003-03-07 12:01:03.000000000 -0800 +++ 25-akpm/mm/mmap.c 2003-03-07 12:01:03.000000000 -0800 @@ -1259,20 +1259,24 @@ int do_munmap(struct mm_struct *mm, unsi /* * If we need to split any vma, do it now to save pain later. + * + * Note: mremap's move_vma VM_ACCOUNT handling assumes a partially + * unmapped vm_area_struct will remain in use: so lower split_vma + * places tmp vma above, and higher split_vma places tmp vma below. */ if (start > mpnt->vm_start) { if (split_vma(mm, mpnt, start, 0)) return -ENOMEM; prev = mpnt; - mpnt = mpnt->vm_next; } /* Does it split the last one? */ last = find_vma(mm, end); if (last && end > last->vm_start) { - if (split_vma(mm, last, end, 0)) + if (split_vma(mm, last, end, 1)) return -ENOMEM; } + mpnt = prev? prev->vm_next: mm->mmap; /* * Remove the vma's, and unmap the actual pages _