From 1b823e5f3e6e6e25a4816610c855b41f5ff52a44 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Tue, 9 May 2023 13:02:14 +0200 Subject: [PATCH] ntdll: Support the MEM_EXTENDED_PARAMETER_EC_CODE attribute. --- dlls/ntdll/tests/virtual.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++ dlls/ntdll/unix/virtual.c | 7 +++-- 2 files changed, 77 insertions(+), 2 deletions(-) diff --git a/dlls/ntdll/tests/virtual.c b/dlls/ntdll/tests/virtual.c index a239a75ad47..425d02473ba 100644 --- a/dlls/ntdll/tests/virtual.c +++ b/dlls/ntdll/tests/virtual.c @@ -37,6 +37,8 @@ static ULONG64 (WINAPI *pRtlGetEnabledExtendedFeatures)(ULONG64); static NTSTATUS (WINAPI *pRtlFreeUserStack)(void *); static void * (WINAPI *pRtlFindExportedRoutineByName)(HMODULE,const char*); static BOOL (WINAPI *pIsWow64Process)(HANDLE, PBOOL); +static NTSTATUS (WINAPI *pRtlGetNativeSystemInformation)(SYSTEM_INFORMATION_CLASS, PVOID, ULONG, PULONG); +static BOOLEAN (WINAPI *pRtlIsEcCode)(const void *); static NTSTATUS (WINAPI *pNtAllocateVirtualMemoryEx)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG, MEM_EXTENDED_PARAMETER *, ULONG); static NTSTATUS (WINAPI *pNtMapViewOfSectionEx)(HANDLE, HANDLE, PVOID *, const LARGE_INTEGER *, SIZE_T *, @@ -291,6 +293,7 @@ static void check_region_size_(void *p, SIZE_T s, unsigned int line) static void test_NtAllocateVirtualMemoryEx(void) { + MEM_EXTENDED_PARAMETER ext; SIZE_T size, size2; char *p, *p1, *p2; NTSTATUS status; @@ -421,6 +424,73 @@ static void test_NtAllocateVirtualMemoryEx(void) status = NtFreeVirtualMemory(NtCurrentProcess(), (void **)&p2, &size2, MEM_RELEASE); ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); } + + memset( &ext, 0, sizeof(ext) ); + ext.Type = MemExtendedParameterAttributeFlags; + ext.ULong = MEM_EXTENDED_PARAMETER_EC_CODE; + size = 0x10000; + addr1 = NULL; + status = pNtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr1, &size, MEM_RESERVE, + PAGE_EXECUTE_READWRITE, &ext, 1 ); +#ifdef __x86_64__ + if (pRtlGetNativeSystemInformation) + { + SYSTEM_CPU_INFORMATION cpu_info; + + pRtlGetNativeSystemInformation( SystemCpuInformation, &cpu_info, sizeof(cpu_info), NULL ); + if (cpu_info.ProcessorArchitecture == PROCESSOR_ARCHITECTURE_ARM64) + { + ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); + if (pRtlIsEcCode) ok( pRtlIsEcCode( addr1 ), "not EC code %p\n", addr1 ); + size = 0; + NtFreeVirtualMemory( NtCurrentProcess(), &addr1, &size, MEM_RELEASE ); + + size = 0x10000; + addr1 = NULL; + status = pNtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr1, &size, MEM_RESERVE, + PAGE_EXECUTE_READWRITE, NULL, 0 ); + ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); + if (pRtlIsEcCode) ok( !pRtlIsEcCode( addr1 ), "EC code %p\n", addr1 ); + size = 0x1000; + status = pNtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr1, &size, MEM_COMMIT, + PAGE_EXECUTE_READWRITE, &ext, 1 ); + ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); + if (pRtlIsEcCode) + { + ok( pRtlIsEcCode( addr1 ), "not EC code %p\n", addr1 ); + ok( !pRtlIsEcCode( (char *)addr1 + 0x1000 ), "EC code %p\n", (char *)addr1 + 0x1000 ); + } + size = 0x2000; + status = pNtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr1, &size, MEM_COMMIT, + PAGE_EXECUTE_READWRITE, NULL, 0 ); + ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); + if (pRtlIsEcCode) + { + ok( pRtlIsEcCode( addr1 ), "not EC code %p\n", addr1 ); + ok( !pRtlIsEcCode( (char *)addr1 + 0x1000 ), "EC code %p\n", (char *)addr1 + 0x1000 ); + } + + NtFreeVirtualMemory( NtCurrentProcess(), &addr1, &size, MEM_DECOMMIT ); + if (pRtlIsEcCode) ok( pRtlIsEcCode( addr1 ), "not EC code %p\n", addr1 ); + + size = 0x2000; + ext.ULong = 0; + status = pNtAllocateVirtualMemoryEx( NtCurrentProcess(), &addr1, &size, MEM_COMMIT, + PAGE_EXECUTE_READWRITE, &ext, 1 ); + ok(status == STATUS_SUCCESS, "Unexpected status %08lx.\n", status); + if (pRtlIsEcCode) + { + ok( pRtlIsEcCode( addr1 ), "not EC code %p\n", addr1 ); + ok( !pRtlIsEcCode( (char *)addr1 + 0x1000 ), "EC code %p\n", (char *)addr1 + 0x1000 ); + } + + size = 0; + NtFreeVirtualMemory( NtCurrentProcess(), &addr1, &size, MEM_RELEASE ); + return; + } + } +#endif + ok(status == STATUS_INVALID_PARAMETER, "Unexpected status %08lx.\n", status); } static void test_NtAllocateVirtualMemoryEx_address_requirements(void) @@ -1928,6 +1998,8 @@ START_TEST(virtual) pRtlFreeUserStack = (void *)GetProcAddress(mod, "RtlFreeUserStack"); pRtlFindExportedRoutineByName = (void *)GetProcAddress(mod, "RtlFindExportedRoutineByName"); pRtlGetEnabledExtendedFeatures = (void *)GetProcAddress(mod, "RtlGetEnabledExtendedFeatures"); + pRtlGetNativeSystemInformation = (void *)GetProcAddress(mod, "RtlGetNativeSystemInformation"); + pRtlIsEcCode = (void *)GetProcAddress(mod, "RtlIsEcCode"); pNtAllocateVirtualMemoryEx = (void *)GetProcAddress(mod, "NtAllocateVirtualMemoryEx"); pNtMapViewOfSectionEx = (void *)GetProcAddress(mod, "NtMapViewOfSectionEx"); pNtSetInformationVirtualMemory = (void *)GetProcAddress(mod, "NtSetInformationVirtualMemory"); diff --git a/dlls/ntdll/unix/virtual.c b/dlls/ntdll/unix/virtual.c index 1301d26eed7..fb2a7120aa8 100644 --- a/dlls/ntdll/unix/virtual.c +++ b/dlls/ntdll/unix/virtual.c @@ -1008,7 +1008,6 @@ static inline UINT64 maskbits( size_t idx ) /*********************************************************************** * set_arm64ec_range */ -#ifdef __aarch64__ static void set_arm64ec_range( const void *addr, size_t size ) { size_t idx = (size_t)addr >> page_shift; @@ -1024,7 +1023,7 @@ static void set_arm64ec_range( const void *addr, size_t size ) } else arm64ec_map[pos] |= maskbits( idx ) & ~maskbits( end ); } -#endif + /*********************************************************************** * clear_arm64ec_range @@ -3958,6 +3957,8 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ return STATUS_INVALID_PARAMETER; } + if (!arm64ec_map && (attributes & MEM_EXTENDED_PARAMETER_EC_CODE)) return STATUS_INVALID_PARAMETER; + /* Reserve the memory */ server_enter_uninterrupted_section( &virtual_mutex, &sigset ); @@ -4000,6 +4001,8 @@ static NTSTATUS allocate_virtual_memory( void **ret, SIZE_T *size_ptr, ULONG typ } } + if (!status && (attributes & MEM_EXTENDED_PARAMETER_EC_CODE)) set_arm64ec_range( base, size ); + if (!status) VIRTUAL_DEBUG_DUMP_VIEW( view ); server_leave_uninterrupted_section( &virtual_mutex, &sigset ); -- 2.11.4.GIT