svn commit: r352748 - head/sys/kern

Mark Johnston markj at FreeBSD.org
Thu Sep 26 15:35:36 UTC 2019


Author: markj
Date: Thu Sep 26 15:35:35 2019
New Revision: 352748
URL: https://svnweb.freebsd.org/changeset/base/352748

Log:
  Fix handling of invalid pages in exec_map_first_page().
  
  exec_map_first_page() would unconditionally free an unbacked, invalid
  page from the executable image.  However, it is possible that the page
  is wired, in which case it is incorrect to free the page, so check for
  additional wirings first.
  
  Reported by:	syzkaller
  Tested by:	pho
  Reviewed by:	kib
  MFC after:	1 week
  Sponsored by:	The FreeBSD Foundation
  Differential Revision:	https://reviews.freebsd.org/D21767

Modified:
  head/sys/kern/kern_exec.c

Modified: head/sys/kern/kern_exec.c
==============================================================================
--- head/sys/kern/kern_exec.c	Thu Sep 26 15:32:28 2019	(r352747)
+++ head/sys/kern/kern_exec.c	Thu Sep 26 15:35:35 2019	(r352748)
@@ -981,8 +981,10 @@ exec_map_first_page(struct image_params *imgp)
 	if (ma[0]->valid != VM_PAGE_BITS_ALL) {
 		vm_page_xbusy(ma[0]);
 		if (!vm_pager_has_page(object, 0, NULL, &after)) {
-			vm_page_unwire_noq(ma[0]);
-			vm_page_free(ma[0]);
+			if (vm_page_unwire_noq(ma[0]))
+				vm_page_free(ma[0]);
+			else
+				vm_page_xunbusy(ma[0]);
 			VM_OBJECT_WUNLOCK(object);
 			return (EIO);
 		}
@@ -1006,9 +1008,16 @@ exec_map_first_page(struct image_params *imgp)
 		initial_pagein = i;
 		rv = vm_pager_get_pages(object, ma, initial_pagein, NULL, NULL);
 		if (rv != VM_PAGER_OK) {
-			vm_page_unwire_noq(ma[0]);
-			for (i = 0; i < initial_pagein; i++)
-				vm_page_free(ma[i]);
+			if (vm_page_unwire_noq(ma[0]))
+				vm_page_free(ma[0]);
+			else
+				vm_page_xunbusy(ma[0]);
+			for (i = 1; i < initial_pagein; i++) {
+				if (!vm_page_wired(ma[i]))
+					vm_page_free(ma[i]);
+				else
+					vm_page_xunbusy(ma[i]);
+			}
 			VM_OBJECT_WUNLOCK(object);
 			return (EIO);
 		}


More information about the svn-src-all mailing list