Unmap pages mapped during a failed fill_vmr() If we get part of the way through filling the VMR with the parent's contents, but then run out of memory, we were leaving the old, successful PTE mappings behind. The VMR would be freed and never added to the proc's list, so we wouldn't unmap it during __proc_free(). However, our assert would catch that the process still has mapped pages that weren't a part of any VMR. I'm not 100% that this is what happened with syzkaller, but it's a likely scenario, especially since other bugs it found recently are due to running low/out of memory. Reported-by: syzbot+28ec6ca66d7b660fbf4d@syzkaller.appspotmail.com Signed-off-by: Barret Rhoden <brho@cs.berkeley.edu>
diff --git a/kern/src/mm.c b/kern/src/mm.c index b5249ed..648745a 100644 --- a/kern/src/mm.c +++ b/kern/src/mm.c
@@ -573,6 +573,15 @@ foc_decref(vmr->__vm_foc); } } + if (ret < 0) { + /* Need to undo any mappings we left behind. We don't know + * where we died, but we can just blast the entire region */ + spin_lock(&new_p->pte_lock); + env_user_mem_walk(new_p, (void*)vmr->vm_base, + vmr->vm_end - vmr->vm_base, + __vmr_free_pgs, NULL); + spin_unlock(&new_p->pte_lock); + } return ret; }