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-all mailing list