[PATCH 0/2] MR11547: server: Assign a shared map address to high-entropy ASLR executables.
Only DLLs were given an address from the shared image address ranges, so executables were left to be mapped at their preferred ImageBase. Windows relocates executables that opt into ASLR like any other image, and places the ones with IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA high in the address space. Assign such executables an address from a separate range at 0x7ff600000000, leaving the ranges used for DLLs unchanged. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/11547
From: xeralin <Mail deines WineHQ-GitLab-Kontos> Only DLLs were given an address from the shared image address ranges, so executables were left to be mapped at their preferred ImageBase. Windows relocates executables that opt into ASLR like any other image, and places the ones with IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA high in the address space. Assign such executables an address from a separate range at 0x7ff600000000, leaving the ranges used for DLLs unchanged. --- server/mapping.c | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/server/mapping.c b/server/mapping.c index eb49ae37237..c5915df5638 100644 --- a/server/mapping.c +++ b/server/mapping.c @@ -183,6 +183,11 @@ static const size_t page_mask = 0xfff; static const size_t granularity_mask = 0xffff; static struct addr_range ranges32; static struct addr_range ranges64; +static struct addr_range ranges_high; + +/* range used for images with high-entropy ASLR, matching the addresses used on Windows */ +static const client_ptr_t high_entropy_base = 0x7ff600000000; +static const mem_size_t high_entropy_size = 0x200000000; struct session_block { @@ -221,11 +226,19 @@ static inline mem_size_t round_size( mem_size_t size, mem_size_t mask ) return (size + mask) & ~mask; } +static struct addr_range *get_addr_range( client_ptr_t base ) +{ + if (!(base >> 32)) return &ranges32; + if (base >= high_entropy_base && base < high_entropy_base + high_entropy_size) return &ranges_high; + return &ranges64; +} + void init_memory(void) { host_page_mask = sysconf( _SC_PAGESIZE ) - 1; free_map_addr( 0x60000000, 0x1c000000 ); free_map_addr( 0x600000000000, 0x100000000000 ); + free_map_addr( high_entropy_base, high_entropy_size ); } static void ranges_dump( struct object *obj, int verbose ) @@ -1264,10 +1277,15 @@ static client_ptr_t assign_map_address( struct mapping *mapping ) { unsigned int i; client_ptr_t ret; - struct addr_range *range = (mapping->image.base >> 32) ? &ranges64 : &ranges32; + struct addr_range *range; mem_size_t size = round_size( mapping->size, granularity_mask ); - if (!(mapping->image.image_charact & IMAGE_FILE_DLL)) return 0; + if (mapping->image.image_charact & IMAGE_FILE_DLL) + range = (mapping->image.base >> 32) ? &ranges64 : &ranges32; + else if (is_machine_64bit( mapping->image.machine ) && + (mapping->image.dll_charact & IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA)) + range = &ranges_high; + else return 0; if ((ret = get_fd_map_address( mapping->fd ))) return ret; @@ -1289,7 +1307,7 @@ void free_map_addr( client_ptr_t base, mem_size_t size ) { unsigned int i; client_ptr_t end = base + size; - struct addr_range *range = (base >> 32) ? &ranges64 : &ranges32; + struct addr_range *range = get_addr_range( base ); for (i = 0; i < range->count; i++) { -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11547
From: xeralin <Mail deines WineHQ-GitLab-Kontos> The server now assigns an address for executables that opt into high-entropy ASLR, so ask for it when mapping them, the same way it is already done for DLLs. --- dlls/ntdll/unix/virtual.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index db820a89525..669782ed006 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -3425,7 +3425,8 @@ static NTSTATUS virtual_map_image( HANDLE mapping, void **addr_ptr, SIZE_T *size } if (!pe_mapping->image.map_addr && - (pe_mapping->image.image_charact & IMAGE_FILE_DLL) && + ((pe_mapping->image.image_charact & IMAGE_FILE_DLL) || + (pe_mapping->image.dll_charact & IMAGE_DLLCHARACTERISTICS_HIGH_ENTROPY_VA)) && (pe_mapping->image.image_flags & IMAGE_FLAGS_ImageDynamicallyRelocated)) { SERVER_START_REQ( get_image_map_address ) -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/11547
participants (2)
-
Xera (@xeralin2) -
xeralin