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
This commit is contained in:
parent
9afb12bab4
commit
55248d32f2
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user