Correct a rare use-after-free error in pmap_copy(). This error was
introduced in amd64 revision 1.540 and i386 revision 1.547. However, it had no harmful effects until after a recent change, r189698, on amd64. (In other words, the error is harmless in RELENG_7.) The error is triggered by the failure to allocate a pv entry for the one and only mapping in a page table page. I am addressing the error by changing pmap_copy() to abort if either pv entry allocation or page table page allocation fails. This is appropriate because the creation of mappings by pmap_copy() is optional. They are a (possible) optimization, and not a requirement. Correct a nearby whitespace error in the i386 pmap_copy(). Crash reported by: jeff@ MFC after: 6 weeks
This commit is contained in:
parent
82da6bfdea
commit
2553ba9c64
@ -3556,7 +3556,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
|
||||
dstmpte->wire_count++;
|
||||
else if ((dstmpte = pmap_allocpte(dst_pmap,
|
||||
addr, M_NOWAIT)) == NULL)
|
||||
break;
|
||||
goto out;
|
||||
dst_pte = (pt_entry_t *)
|
||||
PHYS_TO_DMAP(VM_PAGE_TO_PHYS(dstmpte));
|
||||
dst_pte = &dst_pte[pmap_pte_index(addr)];
|
||||
@ -3579,6 +3579,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
|
||||
addr);
|
||||
pmap_free_zero_pages(free);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
if (dstmpte->wire_count >= srcmpte->wire_count)
|
||||
break;
|
||||
@ -3587,6 +3588,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
|
||||
src_pte++;
|
||||
}
|
||||
}
|
||||
out:
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(src_pmap);
|
||||
PMAP_UNLOCK(dst_pmap);
|
||||
|
@ -3638,7 +3638,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
|
||||
dstmpte = pmap_allocpte(dst_pmap, addr,
|
||||
M_NOWAIT);
|
||||
if (dstmpte == NULL)
|
||||
break;
|
||||
goto out;
|
||||
dst_pte = pmap_pte_quick(dst_pmap, addr);
|
||||
if (*dst_pte == 0 &&
|
||||
pmap_try_insert_pv_entry(dst_pmap, addr,
|
||||
@ -3653,12 +3653,13 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
|
||||
dst_pmap->pm_stats.resident_count++;
|
||||
} else {
|
||||
free = NULL;
|
||||
if (pmap_unwire_pte_hold( dst_pmap,
|
||||
if (pmap_unwire_pte_hold(dst_pmap,
|
||||
dstmpte, &free)) {
|
||||
pmap_invalidate_page(dst_pmap,
|
||||
addr);
|
||||
pmap_free_zero_pages(free);
|
||||
}
|
||||
goto out;
|
||||
}
|
||||
if (dstmpte->wire_count >= srcmpte->wire_count)
|
||||
break;
|
||||
@ -3667,6 +3668,7 @@ pmap_copy(pmap_t dst_pmap, pmap_t src_pmap, vm_offset_t dst_addr, vm_size_t len,
|
||||
src_pte++;
|
||||
}
|
||||
}
|
||||
out:
|
||||
sched_unpin();
|
||||
vm_page_unlock_queues();
|
||||
PMAP_UNLOCK(src_pmap);
|
||||
|
Loading…
Reference in New Issue
Block a user