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
edad331b44
commit
e97c4bdc7f
@ -981,8 +981,10 @@ exec_map_first_page(struct image_params *imgp)
|
|||||||
if (ma[0]->valid != VM_PAGE_BITS_ALL) {
|
if (ma[0]->valid != VM_PAGE_BITS_ALL) {
|
||||||
vm_page_xbusy(ma[0]);
|
vm_page_xbusy(ma[0]);
|
||||||
if (!vm_pager_has_page(object, 0, NULL, &after)) {
|
if (!vm_pager_has_page(object, 0, NULL, &after)) {
|
||||||
vm_page_unwire_noq(ma[0]);
|
if (vm_page_unwire_noq(ma[0]))
|
||||||
vm_page_free(ma[0]);
|
vm_page_free(ma[0]);
|
||||||
|
else
|
||||||
|
vm_page_xunbusy(ma[0]);
|
||||||
VM_OBJECT_WUNLOCK(object);
|
VM_OBJECT_WUNLOCK(object);
|
||||||
return (EIO);
|
return (EIO);
|
||||||
}
|
}
|
||||||
@ -1006,9 +1008,16 @@ exec_map_first_page(struct image_params *imgp)
|
|||||||
initial_pagein = i;
|
initial_pagein = i;
|
||||||
rv = vm_pager_get_pages(object, ma, initial_pagein, NULL, NULL);
|
rv = vm_pager_get_pages(object, ma, initial_pagein, NULL, NULL);
|
||||||
if (rv != VM_PAGER_OK) {
|
if (rv != VM_PAGER_OK) {
|
||||||
vm_page_unwire_noq(ma[0]);
|
if (vm_page_unwire_noq(ma[0]))
|
||||||
for (i = 0; i < initial_pagein; i++)
|
vm_page_free(ma[0]);
|
||||||
vm_page_free(ma[i]);
|
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);
|
VM_OBJECT_WUNLOCK(object);
|
||||||
return (EIO);
|
return (EIO);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user