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_set_area_memory_type(area_id id, phys_addr_t physicalBase,
|
||||
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);
|
||||
bool vm_test_map_modification(struct vm_page *page);
|
||||
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;
|
||||
addr_t delta = 0;
|
||||
uint32 addressSpec = B_RANDOMIZED_BASE_ADDRESS;
|
||||
area_id* mappedAreas = NULL;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
// 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;
|
||||
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;
|
||||
area_id id;
|
||||
|
||||
mappedAreas[i] = -1;
|
||||
|
||||
if (programHeaders[i].p_type == PT_DYNAMIC) {
|
||||
image->dynamic_section = programHeaders[i].p_vaddr;
|
||||
continue;
|
||||
@@ -1950,6 +1960,7 @@ elf_load_user_image(const char *path, Team *team, int flags, addr_t *entry)
|
||||
status = B_NOT_AN_EXECUTABLE;
|
||||
goto error2;
|
||||
}
|
||||
mappedAreas[i] = id;
|
||||
|
||||
imageInfo.data = regionAddress;
|
||||
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,
|
||||
addressSpec, segmentSize,
|
||||
B_READ_AREA | B_EXECUTE_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP,
|
||||
false, fd, ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
||||
B_READ_AREA | B_WRITE_AREA, REGION_PRIVATE_MAP, false, fd,
|
||||
ROUNDDOWN(programHeaders[i].p_offset, B_PAGE_SIZE));
|
||||
if (id < B_OK) {
|
||||
dprintf("error mapping file text: %s!\n", strerror(id));
|
||||
status = B_NOT_AN_EXECUTABLE;
|
||||
goto error2;
|
||||
}
|
||||
|
||||
mappedAreas[i] = id;
|
||||
|
||||
imageInfo.text = regionAddress;
|
||||
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)
|
||||
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
|
||||
imageInfo.type = B_LIBRARY_IMAGE;
|
||||
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;
|
||||
|
||||
error2:
|
||||
free(mappedAreas);
|
||||
|
||||
image->elf_header = NULL;
|
||||
delete_elf_image(image);
|
||||
|
||||
|
||||
@@ -274,6 +274,7 @@ static status_t map_backing_store(VMAddressSpace* addressSpace,
|
||||
int protection, int mapping, uint32 flags,
|
||||
const virtual_address_restrictions* addressRestrictions, bool kernel,
|
||||
VMArea** _area, void** _virtualAddress);
|
||||
static void fix_protection(uint32* protection);
|
||||
|
||||
|
||||
// #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,
|
||||
bool kernel)
|
||||
{
|
||||
fix_protection(&newProtection);
|
||||
|
||||
TRACE(("vm_set_area_protection(team = %#" B_PRIx32 ", area = %#" B_PRIx32
|
||||
", 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
|
||||
set_area_protection(area_id area, uint32 newProtection)
|
||||
{
|
||||
fix_protection(&newProtection);
|
||||
|
||||
return vm_set_area_protection(VMAddressSpace::KernelID(), area,
|
||||
newProtection, true);
|
||||
}
|
||||
@@ -6037,8 +6038,6 @@ _user_set_area_protection(area_id area, uint32 newProtection)
|
||||
if ((newProtection & ~B_USER_PROTECTION) != 0)
|
||||
return B_BAD_VALUE;
|
||||
|
||||
fix_protection(&newProtection);
|
||||
|
||||
return vm_set_area_protection(VMAddressSpace::CurrentID(), area,
|
||||
newProtection, false);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user