svn commit: r317828 - head/sys/compat/linuxkpi/common/src
Hans Petter Selasky
hselasky at FreeBSD.org
Fri May 5 14:09:45 UTC 2017
Author: hselasky
Date: Fri May 5 14:09:44 2017
New Revision: 317828
URL: https://svnweb.freebsd.org/changeset/base/317828
Log:
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
Modified:
head/sys/compat/linuxkpi/common/src/linux_compat.c
Modified: head/sys/compat/linuxkpi/common/src/linux_compat.c
==============================================================================
--- head/sys/compat/linuxkpi/common/src/linux_compat.c Fri May 5 13:31:25 2017 (r317827)
+++ head/sys/compat/linuxkpi/common/src/linux_compat.c Fri May 5 14:09:44 2017 (r317828)
@@ -485,6 +485,16 @@ linux_cdev_handle_insert(void *handle, s
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_
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);
}
More information about the svn-src-head
mailing list