When resizing an area that has individual page protections (set via mprotect),
we have to enlarge/shrink the array that holds them and assign a protection value for the additional pages as necessary. Otherwise we'll access invalid memory when looking up page protections for enlarged areas and get random protection values. Experienced with QEMU that sets page protections via mprotect on heap memory. When the heap was later enlarged, write access to the additional memory would result in permission denied errors and crashes. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@42330 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
4b722b91db
commit
3fb17998a7
@ -4765,6 +4765,33 @@ vm_resize_area(area_id areaID, size_t newSize, bool kernel)
|
||||
if (status == B_OK && newSize < oldSize)
|
||||
status = cache->Resize(cache->virtual_base + newSize, priority);
|
||||
|
||||
if (status == B_OK) {
|
||||
// Shrink or grow individual page protections if in use.
|
||||
if (area->page_protections != NULL) {
|
||||
uint32 bytes = (newSize / B_PAGE_SIZE + 1) / 2;
|
||||
uint8* newProtections
|
||||
= (uint8*)realloc(area->page_protections, bytes);
|
||||
if (newProtections == NULL)
|
||||
status = B_NO_MEMORY;
|
||||
else {
|
||||
area->page_protections = newProtections;
|
||||
|
||||
if (oldSize < newSize) {
|
||||
// init the additional page protections to that of the area
|
||||
uint32 offset = (oldSize / B_PAGE_SIZE + 1) / 2;
|
||||
uint32 areaProtection = area->protection
|
||||
& (B_READ_AREA | B_WRITE_AREA | B_EXECUTE_AREA);
|
||||
memset(area->page_protections + offset,
|
||||
areaProtection | (areaProtection << 4), bytes - offset);
|
||||
if ((oldSize / B_PAGE_SIZE) % 2 != 0) {
|
||||
uint8& entry = area->page_protections[offset - 1];
|
||||
entry = (entry & 0x0f) | (areaProtection << 4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (status != B_OK) {
|
||||
// Something failed -- resize the areas back to their original size.
|
||||
// This can fail, too, in which case we're seriously screwed.
|
||||
|
Loading…
x
Reference in New Issue
Block a user