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); } _______________________________________________ svn-src-head@freebsd.org mailing list https://lists.freebsd.org/mailman/listinfo/svn-src-head To unsubscribe, send any mail to "svn-src-head-unsubscr...@freebsd.org"