elf: restore correct region protection after relocation
This commit is contained in:
@@ -121,6 +121,8 @@ status_t vm_delete_area(team_id teamID, area_id areaID, bool kernel);
|
|||||||
status_t vm_create_vnode_cache(struct vnode *vnode, struct VMCache **_cache);
|
status_t vm_create_vnode_cache(struct vnode *vnode, struct VMCache **_cache);
|
||||||
status_t vm_set_area_memory_type(area_id id, phys_addr_t physicalBase,
|
status_t vm_set_area_memory_type(area_id id, phys_addr_t physicalBase,
|
||||||
uint32 type);
|
uint32 type);
|
||||||
|
status_t vm_set_area_protection(team_id team, area_id areaID,
|
||||||
|
uint32 newProtection, bool kernel);
|
||||||
status_t vm_get_page_mapping(team_id team, addr_t vaddr, phys_addr_t *paddr);
|
status_t vm_get_page_mapping(team_id team, addr_t vaddr, phys_addr_t *paddr);
|
||||||
bool vm_test_map_modification(struct vm_page *page);
|
bool vm_test_map_modification(struct vm_page *page);
|
||||||
void vm_clear_map_flags(struct vm_page *page, uint32 flags);
|
void vm_clear_map_flags(struct vm_page *page, uint32 flags);
|
||||||
|
|||||||
@@ -1827,6 +1827,7 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
int i;
|
int i;
|
||||||
addr_t delta = 0;
|
addr_t delta = 0;
|
||||||
uint32 addressSpec = B_RANDOMIZED_BASE_ADDRESS;
|
uint32 addressSpec = B_RANDOMIZED_BASE_ADDRESS;
|
||||||
|
area_id* mappedAreas = NULL;
|
||||||
|
|
||||||
TRACE(("elf_load: entry path '%s', team %p\n", path, team));
|
TRACE(("elf_load: entry path '%s', team %p\n", path, team));
|
||||||
|
|
||||||
@@ -1906,7 +1907,14 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
strcpy(baseName, leaf);
|
strcpy(baseName, leaf);
|
||||||
}
|
}
|
||||||
|
|
||||||
// map the program's segments into memory
|
// map the program's segments into memory, initially with rw access
|
||||||
|
// correct area protection will be set after relocation
|
||||||
|
|
||||||
|
mappedAreas = (area_id*)malloc(sizeof(area_id) * elfHeader.e_phnum);
|
||||||
|
if (mappedAreas == NULL) {
|
||||||
|
status = B_NO_MEMORY;
|
||||||
|
goto error2;
|
||||||
|
}
|
||||||
|
|
||||||
image_info imageInfo;
|
image_info imageInfo;
|
||||||
memset(&imageInfo, 0, sizeof(image_info));
|
memset(&imageInfo, 0, sizeof(image_info));
|
||||||
@@ -1917,6 +1925,8 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
char *originalRegionAddress;
|
char *originalRegionAddress;
|
||||||
area_id id;
|
area_id id;
|
||||||
|
|
||||||
|
mappedAreas[i] = -1;
|
||||||
|
|
||||||
if (programHeaders[i].p_type == PT_DYNAMIC) {
|
if (programHeaders[i].p_type == PT_DYNAMIC) {
|
||||||
image->dynamic_section = programHeaders[i].p_vaddr;
|
image->dynamic_section = programHeaders[i].p_vaddr;
|
||||||
continue;
|
continue;
|
||||||
@@ -1950,6 +1960,7 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
status = B_NOT_AN_EXECUTABLE;
|
status = B_NOT_AN_EXECUTABLE;
|
||||||
goto error2;
|
goto error2;
|
||||||
}
|
}
|
||||||
|
mappedAreas[i] = id;
|
||||||
|
|
||||||
imageInfo.data = regionAddress;
|
imageInfo.data = regionAddress;
|
||||||
imageInfo.data_size = memUpperBound;
|
imageInfo.data_size = memUpperBound;
|
||||||
@@ -1998,14 +2009,16 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
|
|
||||||
id = vm_map_file(team->id, regionName, (void **)®ionAddress,
|
id = vm_map_file(team->id, regionName, (void **)®ionAddress,
|
||||||
addressSpec, segmentSize,
|
addressSpec, segmentSize,
|
||||||
B_READ_AREA | B_EXECUTE_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP,
|
B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false, fd,
|
||||||
false, fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
||||||
if (id < B_OK) {
|
if (id < B_OK) {
|
||||||
dprintf("error mapping file text: %s!\n", strerror(id));
|
dprintf("error mapping file text: %s!\n", strerror(id));
|
||||||
status = B_NOT_AN_EXECUTABLE;
|
status = B_NOT_AN_EXECUTABLE;
|
||||||
goto error2;
|
goto error2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mappedAreas[i] = id;
|
||||||
|
|
||||||
imageInfo.text = regionAddress;
|
imageInfo.text = regionAddress;
|
||||||
imageInfo.text_size = segmentSize;
|
imageInfo.text_size = segmentSize;
|
||||||
|
|
||||||
@@ -2033,6 +2046,26 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
if (status != B_OK)
|
if (status != B_OK)
|
||||||
goto error2;
|
goto error2;
|
||||||
|
|
||||||
|
// set correct area protection
|
||||||
|
for (i = 0; i < elfHeader.e_phnum; i++) {
|
||||||
|
if (mappedAreas[i] == -1)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
uint32 protection = 0;
|
||||||
|
|
||||||
|
if (programHeaders[i].p_flags & PF_EXECUTE)
|
||||||
|
protection |= B_EXECUTE_AREA;
|
||||||
|
if (programHeaders[i].p_flags & PF_WRITE)
|
||||||
|
protection |= B_WRITE_AREA;
|
||||||
|
if (programHeaders[i].p_flags & PF_READ)
|
||||||
|
protection |= B_READ_AREA;
|
||||||
|
|
||||||
|
status = vm_set_area_protection(team->id, mappedAreas[i], protection,
|
||||||
|
true);
|
||||||
|
if (status != B_OK)
|
||||||
|
goto error2;
|
||||||
|
}
|
||||||
|
|
||||||
// register the loaded image
|
// register the loaded image
|
||||||
imageInfo.type = B_LIBRARY_IMAGE;
|
imageInfo.type = B_LIBRARY_IMAGE;
|
||||||
imageInfo.device = st.st_dev;
|
imageInfo.device = st.st_dev;
|
||||||
@@ -2056,6 +2089,8 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
|||||||
status = B_OK;
|
status = B_OK;
|
||||||
|
|
||||||
error2:
|
error2:
|
||||||
|
free(mappedAreas);
|
||||||
|
|
||||||
image->elf_header = NULL;
|
image->elf_header = NULL;
|
||||||
delete_elf_image(image);
|
delete_elf_image(image);
|
||||||
|
|
||||||
|
|||||||
@@ -274,6 +274,7 @@ static status_t map_backing_store(VMAddressSpace* addressSpace,
|
|||||||
int protection, int mapping, uint32 flags,
|
int protection, int mapping, uint32 flags,
|
||||||
const virtual_address_restrictions* addressRestrictions, bool kernel,
|
const virtual_address_restrictions* addressRestrictions, bool kernel,
|
||||||
VMArea** _area, void** _virtualAddress);
|
VMArea** _area, void** _virtualAddress);
|
||||||
|
static void fix_protection(uint32* protection);
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
// #pragma mark -
|
||||||
@@ -2527,10 +2528,12 @@ vm_copy_area(team_id team, const char* name, void** _address,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
status_t
|
||||||
vm_set_area_protection(team_id team, area_id areaID, uint32 newProtection,
|
vm_set_area_protection(team_id team, area_id areaID, uint32 newProtection,
|
||||||
bool kernel)
|
bool kernel)
|
||||||
{
|
{
|
||||||
|
fix_protection(&newProtection);
|
||||||
|
|
||||||
TRACE(("vm_set_area_protection(team = %#" B_PRIx32 ", area = %#" B_PRIx32
|
TRACE(("vm_set_area_protection(team = %#" B_PRIx32 ", area = %#" B_PRIx32
|
||||||
", protection = %#" B_PRIx32 ")\n", team, areaID, newProtection));
|
", protection = %#" B_PRIx32 ")\n", team, areaID, newProtection));
|
||||||
|
|
||||||
@@ -5808,8 +5811,6 @@ _get_next_area_info(team_id team, ssize_t* cookie, area_info* info, size_t size)
|
|||||||
status_t
|
status_t
|
||||||
set_area_protection(area_id area, uint32 newProtection)
|
set_area_protection(area_id area, uint32 newProtection)
|
||||||
{
|
{
|
||||||
fix_protection(&newProtection);
|
|
||||||
|
|
||||||
return vm_set_area_protection(VMAddressSpace::KernelID(), area,
|
return vm_set_area_protection(VMAddressSpace::KernelID(), area,
|
||||||
newProtection, true);
|
newProtection, true);
|
||||||
}
|
}
|
||||||
@@ -6037,8 +6038,6 @@ _user_set_area_protection(area_id area, uint32 newProtection)
|
|||||||
if ((newProtection & ~B_USER_PROTECTION) != 0)
|
if ((newProtection & ~B_USER_PROTECTION) != 0)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
fix_protection(&newProtection);
|
|
||||||
|
|
||||||
return vm_set_area_protection(VMAddressSpace::CurrentID(), area,
|
return vm_set_area_protection(VMAddressSpace::CurrentID(), area,
|
||||||
newProtection, false);
|
newProtection, false);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user