Fix for use after free in the LinuxKPI.

Background:
The same VM object might be shared by multiple processes and the
mm_struct is usually freed when a process exits.

Grab a reference on the mm_struct while the vmap is in the
linux_vma_head list in case the first process which inserted a VM
object has exited.

Tested by:		kwm @
MFC after:		1 week
Sponsored by:		Mellanox Technologies
This commit is contained in:
hselasky 2017-05-05 14:09:44 +00:00
parent e00bc60be4
commit ea53fefda4

View File

@ -485,6 +485,16 @@ linux_cdev_handle_insert(void *handle, struct vm_area_struct *vmap)
return (NULL);
}
}
/*
* The same VM object might be shared by multiple processes
* and the mm_struct is usually freed when a process exits.
*
* The atomic reference below makes sure the mm_struct is
* available as long as the vmap is in the linux_vma_head.
*/
if (atomic_inc_not_zero(&vmap->vm_mm->mm_users) == 0)
panic("linuxkpi: mm_users is zero\n");
TAILQ_INSERT_TAIL(&linux_vma_head, vmap, vm_entry);
rw_wunlock(&linux_vma_lock);
return (vmap);
@ -499,6 +509,9 @@ linux_cdev_handle_remove(struct vm_area_struct *vmap)
rw_wlock(&linux_vma_lock);
TAILQ_REMOVE(&linux_vma_head, vmap, vm_entry);
rw_wunlock(&linux_vma_lock);
/* Drop reference on mm_struct */
mmput(vmap->vm_mm);
kfree(vmap);
}