Commit 127419b1 authored by Andrew Morton's avatar Andrew Morton Committed by Linus Torvalds

[PATCH] Fix and harden validate_mm

From: Andi Kleen <ak@muc.de>

I was debugging some code that corrupted the vma rb lists and for that I
fixed validate_mm to not be recursive and do some more checks.

It's slower now, but that shouldn't be a problem.

Also make it non static to allow easier checks elsewhere.
parent 3745aa40
...@@ -138,17 +138,34 @@ asmlinkage unsigned long sys_brk(unsigned long brk) ...@@ -138,17 +138,34 @@ asmlinkage unsigned long sys_brk(unsigned long brk)
} }
#ifdef DEBUG_MM_RB #ifdef DEBUG_MM_RB
static int browse_rb(struct rb_node * rb_node) { static int browse_rb(struct rb_root *root) {
int i = 0; int i, j;
if (rb_node) { struct rb_node *nd, *pn = NULL;
i = 0;
unsigned long prev = 0, pend = 0;
for (nd = rb_first(root); nd; nd = rb_next(nd)) {
struct vm_area_struct *vma;
vma = rb_entry(nd, struct vm_area_struct, vm_rb);
if (vma->vm_start < prev)
printk("vm_start %lx prev %lx\n", vma->vm_start, prev), i = -1;
if (vma->vm_start < pend)
printk("vm_start %lx pend %lx\n", vma->vm_start, pend);
if (vma->vm_start > vma->vm_end)
printk("vm_end %lx < vm_start %lx\n", vma->vm_end, vma->vm_start);
i++; i++;
i += browse_rb(rb_node->rb_left); pn = nd;
i += browse_rb(rb_node->rb_right); }
j = 0;
for (nd = pn; nd; nd = rb_prev(nd)) {
j++;
} }
if (i != j)
printk("backwards %d, forwards %d\n", j, i), i = 0;
return i; return i;
} }
static void validate_mm(struct mm_struct * mm) { void validate_mm(struct mm_struct * mm) {
int bug = 0; int bug = 0;
int i = 0; int i = 0;
struct vm_area_struct * tmp = mm->mmap; struct vm_area_struct * tmp = mm->mmap;
...@@ -158,7 +175,7 @@ static void validate_mm(struct mm_struct * mm) { ...@@ -158,7 +175,7 @@ static void validate_mm(struct mm_struct * mm) {
} }
if (i != mm->map_count) if (i != mm->map_count)
printk("map_count %d vm_next %d\n", mm->map_count, i), bug = 1; printk("map_count %d vm_next %d\n", mm->map_count, i), bug = 1;
i = browse_rb(mm->mm_rb.rb_node); i = browse_rb(&mm->mm_rb);
if (i != mm->map_count) if (i != mm->map_count)
printk("map_count %d rb %d\n", mm->map_count, i), bug = 1; printk("map_count %d rb %d\n", mm->map_count, i), bug = 1;
if (bug) if (bug)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment