From f23ff69f864b16dd7cdaa9614600cf86de17443f Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Sat, 2 May 2015 18:55:34 +0200 Subject: [PATCH] Added patch to return failure in NtProtectVirtualMemory when last argument is omitted. --- README.md | 3 +- debian/changelog | 1 + ...dd-tests-for-calling-VirtualProtect-.patch | 73 +++++++++++++++++++ ...omit-mandatory-argument-for-VirtualP.patch | 33 +++++++++ ...-not-omit-mandatory-argument-for-Vir.patch | 68 +++++++++++++++++ ...t-mandatory-argument-for-VirtualProt.patch | 25 +++++++ ...t-omit-mandatory-argument-for-Virtua.patch | 33 +++++++++ ...lure-in-NtProtectVirtualMemory-when-.patch | 58 +++++++++++++++ .../ntdll-NtProtectVirtualMemory/definition | 1 + ...2-tests-Add-tests-for-NtQuerySection.patch | 16 ++-- patches/ntdll-NtQuerySection/definition | 1 + patches/patchinstall.sh | 44 +++++++++++ ...-invalid-memory-access-when-relocati.patch | 10 +-- patches/winedevice-Fix_Relocation/definition | 1 + 14 files changed, 354 insertions(+), 13 deletions(-) create mode 100644 patches/ntdll-NtProtectVirtualMemory/0001-kernel32-tests-Add-tests-for-calling-VirtualProtect-.patch create mode 100644 patches/ntdll-NtProtectVirtualMemory/0002-kernel32-Do-not-omit-mandatory-argument-for-VirtualP.patch create mode 100644 patches/ntdll-NtProtectVirtualMemory/0003-krnl386.exe16-Do-not-omit-mandatory-argument-for-Vir.patch create mode 100644 patches/ntdll-NtProtectVirtualMemory/0004-ntdll-Do-not-omit-mandatory-argument-for-VirtualProt.patch create mode 100644 patches/ntdll-NtProtectVirtualMemory/0005-winedevice-Do-not-omit-mandatory-argument-for-Virtua.patch create mode 100644 patches/ntdll-NtProtectVirtualMemory/0006-ntdll-Return-failure-in-NtProtectVirtualMemory-when-.patch create mode 100644 patches/ntdll-NtProtectVirtualMemory/definition diff --git a/README.md b/README.md index 26762713..50bcc014 100644 --- a/README.md +++ b/README.md @@ -39,13 +39,14 @@ Wine. All those differences are also documented on the Included bug fixes and improvements ----------------------------------- -**Bug fixes and features included in the next upcoming release [6]:** +**Bug fixes and features included in the next upcoming release [7]:** * Add stub for D3DXFrameFind ([Wine Bug #38334](https://bugs.winehq.org/show_bug.cgi?id=38334)) * Add stub for advapi32.ImpersonateAnonymousToken * Add stub for d3d11.D3D11CreateDeviceAndSwapChain ([Wine Bug #33153](https://bugs.winehq.org/show_bug.cgi?id=33153)) * Fix regression caused by blacklisting supported OpenGL extensions ([Wine Bug #38480](https://bugs.winehq.org/show_bug.cgi?id=38480)) * Ignore garbage after decoding gif lines ([Wine Bug #32227](https://bugs.winehq.org/show_bug.cgi?id=32227)) +* Return failure in NtProtectVirtualMemory when last argument is omitted ([Wine Bug #38495](https://bugs.winehq.org/show_bug.cgi?id=38495)) * Support for FileFsFullSizeInformation information class diff --git a/debian/changelog b/debian/changelog index 1491eab3..b5cf8206 100644 --- a/debian/changelog +++ b/debian/changelog @@ -7,6 +7,7 @@ wine-staging (1.7.42) UNRELEASED; urgency=low * Added patch to fix various issues related to advapi32.LookupAccountSidA. * Added patch with stub for d3d11.D3D11CreateDeviceAndSwapChain. * Added patch with stub for D3DXFrameFind. + * Added patch to return failure in NtProtectVirtualMemory when last argument is omitted. * Removed patch to avoid crash when trying to bind mshtml event scripts to window (fixed upstream). * Removed patch for stub of ntdll.WinSqmIsOptedIn (fixed upstream). * Removed patch to fix issues with invalid console handles for new processes (accepted upstream). diff --git a/patches/ntdll-NtProtectVirtualMemory/0001-kernel32-tests-Add-tests-for-calling-VirtualProtect-.patch b/patches/ntdll-NtProtectVirtualMemory/0001-kernel32-tests-Add-tests-for-calling-VirtualProtect-.patch new file mode 100644 index 00000000..4be5c8f0 --- /dev/null +++ b/patches/ntdll-NtProtectVirtualMemory/0001-kernel32-tests-Add-tests-for-calling-VirtualProtect-.patch @@ -0,0 +1,73 @@ +From e99c972628d923d9fa53a57899b6835844ec83a2 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 2 May 2015 18:37:26 +0200 +Subject: kernel32/tests: Add tests for calling VirtualProtect with NULL as + last argument. + +--- + dlls/kernel32/tests/virtual.c | 28 ++++++++++++++++++++++++++++ + 1 file changed, 28 insertions(+) + +diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c +index 75e91d5..311e87b 100644 +--- a/dlls/kernel32/tests/virtual.c ++++ b/dlls/kernel32/tests/virtual.c +@@ -47,6 +47,7 @@ static struct _TEB * (WINAPI *pNtCurrentTeb)(void); + static PVOID (WINAPI *pRtlAddVectoredExceptionHandler)(ULONG, PVECTORED_EXCEPTION_HANDLER); + static ULONG (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID); + static BOOL (WINAPI *pGetProcessDEPPolicy)(HANDLE, LPDWORD, PBOOL); ++static NTSTATUS (WINAPI *pNtProtectVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG *); + + /* ############################### */ + +@@ -2478,6 +2479,9 @@ static void test_VirtualProtect(void) + DWORD ret, old_prot, rw_prot, exec_prot, i, j; + MEMORY_BASIC_INFORMATION info; + SYSTEM_INFO si; ++ void *addr; ++ SIZE_T size; ++ NTSTATUS status; + + GetSystemInfo(&si); + trace("system page size %#x\n", si.dwPageSize); +@@ -2486,6 +2490,29 @@ static void test_VirtualProtect(void) + base = VirtualAlloc(0, si.dwPageSize, MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS); + ok(base != NULL, "VirtualAlloc failed %d\n", GetLastError()); + ++ SetLastError(0xdeadbeef); ++ ret = VirtualProtect(base, si.dwPageSize, PAGE_READONLY, NULL); ++ todo_wine ++ ok(!ret, "VirtualProtect should fail\n"); ++ todo_wine ++ ok(GetLastError() == ERROR_NOACCESS, "expected ERROR_NOACCESS, got %d\n", GetLastError()); ++ old_prot = 0xdeadbeef; ++ ret = VirtualProtect(base, si.dwPageSize, PAGE_NOACCESS, &old_prot); ++ ok(ret, "VirtualProtect failed %d\n", GetLastError()); ++ todo_wine ++ ok(old_prot == PAGE_NOACCESS, "got %#x != expected PAGE_NOACCESS\n", old_prot); ++ ++ addr = base; size = si.dwPageSize; ++ status = pNtProtectVirtualMemory(GetCurrentProcess(), &addr, &size, PAGE_READONLY, NULL); ++ todo_wine ++ ok(status == STATUS_ACCESS_VIOLATION, "NtProtectVirtualMemory should fail, got %08x\n", status); ++ old_prot = 0xdeadbeef; ++ addr = base; size = si.dwPageSize; ++ status = pNtProtectVirtualMemory(GetCurrentProcess(), &addr, &size, PAGE_NOACCESS, &old_prot); ++ ok(status == STATUS_SUCCESS, "NtProtectVirtualMemory should succeed, got %08x\n", status); ++ todo_wine ++ ok(old_prot == PAGE_NOACCESS, "got %#x != expected PAGE_NOACCESS\n", old_prot); ++ + for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) + { + SetLastError(0xdeadbeef); +@@ -3477,6 +3504,7 @@ START_TEST(virtual) + pNtCurrentTeb = (void *)GetProcAddress( hntdll, "NtCurrentTeb" ); + pRtlAddVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlAddVectoredExceptionHandler" ); + pRtlRemoveVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlRemoveVectoredExceptionHandler" ); ++ pNtProtectVirtualMemory = (void *)GetProcAddress( hntdll, "NtProtectVirtualMemory" ); + + test_shared_memory(FALSE); + test_shared_memory_ro(FALSE, FILE_MAP_READ|FILE_MAP_WRITE); +-- +2.3.5 + diff --git a/patches/ntdll-NtProtectVirtualMemory/0002-kernel32-Do-not-omit-mandatory-argument-for-VirtualP.patch b/patches/ntdll-NtProtectVirtualMemory/0002-kernel32-Do-not-omit-mandatory-argument-for-VirtualP.patch new file mode 100644 index 00000000..da150949 --- /dev/null +++ b/patches/ntdll-NtProtectVirtualMemory/0002-kernel32-Do-not-omit-mandatory-argument-for-VirtualP.patch @@ -0,0 +1,33 @@ +From 6e645b3f441ca310a17a06487b0a55fa629aa0d1 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 2 May 2015 18:42:09 +0200 +Subject: kernel32: Do not omit mandatory argument for VirtualProtect. + +--- + dlls/kernel32/except.c | 3 ++- + 1 file changed, 2 insertions(+), 1 deletion(-) + +diff --git a/dlls/kernel32/except.c b/dlls/kernel32/except.c +index bd50e88..2a7dbaa 100644 +--- a/dlls/kernel32/except.c ++++ b/dlls/kernel32/except.c +@@ -401,6 +401,7 @@ static BOOL start_debugger_atomic(PEXCEPTION_POINTERS epointers) + */ + static inline BOOL check_resource_write( void *addr ) + { ++ DWORD old_prot; + void *rsrc; + DWORD size; + MEMORY_BASIC_INFORMATION info; +@@ -412,7 +413,7 @@ static inline BOOL check_resource_write( void *addr ) + return FALSE; + if (addr < rsrc || (char *)addr >= (char *)rsrc + size) return FALSE; + TRACE( "Broken app is writing to the resource data, enabling work-around\n" ); +- VirtualProtect( rsrc, size, PAGE_READWRITE, NULL ); ++ VirtualProtect( rsrc, size, PAGE_READWRITE, &old_prot ); + return TRUE; + } + +-- +2.3.5 + diff --git a/patches/ntdll-NtProtectVirtualMemory/0003-krnl386.exe16-Do-not-omit-mandatory-argument-for-Vir.patch b/patches/ntdll-NtProtectVirtualMemory/0003-krnl386.exe16-Do-not-omit-mandatory-argument-for-Vir.patch new file mode 100644 index 00000000..ea926c3a --- /dev/null +++ b/patches/ntdll-NtProtectVirtualMemory/0003-krnl386.exe16-Do-not-omit-mandatory-argument-for-Vir.patch @@ -0,0 +1,68 @@ +From 0c9bbd27acb0df45ec7e6a501cb5e2b14bd69161 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 2 May 2015 18:43:05 +0200 +Subject: krnl386.exe16: Do not omit mandatory argument for VirtualProtect. + +--- + dlls/krnl386.exe16/dosmem.c | 6 ++++-- + dlls/krnl386.exe16/dosvm.c | 3 ++- + 2 files changed, 6 insertions(+), 3 deletions(-) + +diff --git a/dlls/krnl386.exe16/dosmem.c b/dlls/krnl386.exe16/dosmem.c +index f0feba9..b899f7b 100644 +--- a/dlls/krnl386.exe16/dosmem.c ++++ b/dlls/krnl386.exe16/dosmem.c +@@ -302,6 +302,7 @@ BOOL DOSMEM_InitDosMemory(void) + { + static BOOL done; + static HANDLE hRunOnce; ++ DWORD old_prot; + + if (done) return TRUE; + +@@ -317,7 +318,7 @@ BOOL DOSMEM_InitDosMemory(void) + /* ok, we're the winning thread */ + if (!(ret = VirtualProtect( DOSMEM_dosmem + DOSMEM_protect, + DOSMEM_SIZE - DOSMEM_protect, +- PAGE_READWRITE, NULL ))) ++ PAGE_READWRITE, &old_prot ))) + ERR("Cannot load access low 1Mb, DOS subsystem unavailable\n"); + RemoveVectoredExceptionHandler( vectored_handler ); + +@@ -650,10 +651,11 @@ UINT DOSMEM_Available(void) + BOOL DOSMEM_MapDosLayout(void) + { + static BOOL already_mapped; ++ DWORD old_prot; + + if (!already_mapped) + { +- if (DOSMEM_dosmem || !VirtualProtect( NULL, DOSMEM_SIZE, PAGE_EXECUTE_READWRITE, NULL )) ++ if (DOSMEM_dosmem || !VirtualProtect( NULL, DOSMEM_SIZE, PAGE_EXECUTE_READWRITE, &old_prot )) + { + ERR( "Need full access to the first megabyte for DOS mode\n" ); + ExitProcess(1); +diff --git a/dlls/krnl386.exe16/dosvm.c b/dlls/krnl386.exe16/dosvm.c +index 87adf33..4e76215 100644 +--- a/dlls/krnl386.exe16/dosvm.c ++++ b/dlls/krnl386.exe16/dosvm.c +@@ -827,6 +827,7 @@ LPVOID DOSVM_AllocDataUMB( DWORD size, WORD *segment, WORD *selector ) + */ + void DOSVM_InitSegments(void) + { ++ DWORD old_prot; + LPSTR ptr; + int i; + +@@ -966,7 +967,7 @@ void DOSVM_InitSegments(void) + /* + * As we store code in UMB we should make sure it is executable + */ +- VirtualProtect((void *)DOSVM_UMB_BOTTOM, DOSVM_UMB_TOP - DOSVM_UMB_BOTTOM, PAGE_EXECUTE_READWRITE, NULL); ++ VirtualProtect((void *)DOSVM_UMB_BOTTOM, DOSVM_UMB_TOP - DOSVM_UMB_BOTTOM, PAGE_EXECUTE_READWRITE, &old_prot); + + event_notifier = CreateEventW(NULL, FALSE, FALSE, NULL); + } +-- +2.3.5 + diff --git a/patches/ntdll-NtProtectVirtualMemory/0004-ntdll-Do-not-omit-mandatory-argument-for-VirtualProt.patch b/patches/ntdll-NtProtectVirtualMemory/0004-ntdll-Do-not-omit-mandatory-argument-for-VirtualProt.patch new file mode 100644 index 00000000..aa34f490 --- /dev/null +++ b/patches/ntdll-NtProtectVirtualMemory/0004-ntdll-Do-not-omit-mandatory-argument-for-VirtualProt.patch @@ -0,0 +1,25 @@ +From 7eacc14beee477a470f66c2d7524054f0a38ff86 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 2 May 2015 18:43:24 +0200 +Subject: ntdll: Do not omit mandatory argument for VirtualProtect. + +--- + dlls/ntdll/loader.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c +index 9810f07..921bf57 100644 +--- a/dlls/ntdll/loader.c ++++ b/dlls/ntdll/loader.c +@@ -685,7 +685,7 @@ static WINE_MODREF *import_dll( HMODULE module, const IMAGE_IMPORT_DESCRIPTOR *d + + done: + /* restore old protection of the import address table */ +- NtProtectVirtualMemory( NtCurrentProcess(), &protect_base, &protect_size, protect_old, NULL ); ++ NtProtectVirtualMemory( NtCurrentProcess(), &protect_base, &protect_size, protect_old, &protect_old ); + return wmImp; + } + +-- +2.3.5 + diff --git a/patches/ntdll-NtProtectVirtualMemory/0005-winedevice-Do-not-omit-mandatory-argument-for-Virtua.patch b/patches/ntdll-NtProtectVirtualMemory/0005-winedevice-Do-not-omit-mandatory-argument-for-Virtua.patch new file mode 100644 index 00000000..4bbfe3f7 --- /dev/null +++ b/patches/ntdll-NtProtectVirtualMemory/0005-winedevice-Do-not-omit-mandatory-argument-for-Virtua.patch @@ -0,0 +1,33 @@ +From 52dd3d51573897cc41a78f86a66518946d2dca40 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 2 May 2015 18:43:34 +0200 +Subject: winedevice: Do not omit mandatory argument for VirtualProtect. + +--- + programs/winedevice/device.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c +index 9677a82..ef1e1ef 100644 +--- a/programs/winedevice/device.c ++++ b/programs/winedevice/device.c +@@ -98,14 +98,14 @@ static HMODULE load_driver_module( const WCHAR *name ) + VirtualProtect( page, info.PageSize, PAGE_EXECUTE_READWRITE, &old ); + rel = LdrProcessRelocationBlock( page, (rel->SizeOfBlock - sizeof(*rel)) / sizeof(USHORT), + (USHORT *)(rel + 1), delta ); +- if (old != PAGE_EXECUTE_READWRITE) VirtualProtect( page, info.PageSize, old, NULL ); ++ if (old != PAGE_EXECUTE_READWRITE) VirtualProtect( page, info.PageSize, old, &old ); + if (!rel) goto error; + } + /* make sure we don't try again */ + size = FIELD_OFFSET( IMAGE_NT_HEADERS, OptionalHeader ) + nt->FileHeader.SizeOfOptionalHeader; + VirtualProtect( nt, size, PAGE_READWRITE, &old ); + nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0; +- VirtualProtect( nt, size, old, NULL ); ++ VirtualProtect( nt, size, old, &old ); + } + } + +-- +2.3.5 + diff --git a/patches/ntdll-NtProtectVirtualMemory/0006-ntdll-Return-failure-in-NtProtectVirtualMemory-when-.patch b/patches/ntdll-NtProtectVirtualMemory/0006-ntdll-Return-failure-in-NtProtectVirtualMemory-when-.patch new file mode 100644 index 00000000..fc5f60b9 --- /dev/null +++ b/patches/ntdll-NtProtectVirtualMemory/0006-ntdll-Return-failure-in-NtProtectVirtualMemory-when-.patch @@ -0,0 +1,58 @@ +From 4fa917bcdc3685a9181df8d1d7c1b3b07d816fc6 Mon Sep 17 00:00:00 2001 +From: Sebastian Lackner +Date: Sat, 2 May 2015 18:46:38 +0200 +Subject: ntdll: Return failure in NtProtectVirtualMemory when last argument is + omitted. + +--- + dlls/kernel32/tests/virtual.c | 5 ----- + dlls/ntdll/virtual.c | 3 +++ + 2 files changed, 3 insertions(+), 5 deletions(-) + +diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c +index 311e87b..1c70eca 100644 +--- a/dlls/kernel32/tests/virtual.c ++++ b/dlls/kernel32/tests/virtual.c +@@ -2492,25 +2492,20 @@ static void test_VirtualProtect(void) + + SetLastError(0xdeadbeef); + ret = VirtualProtect(base, si.dwPageSize, PAGE_READONLY, NULL); +- todo_wine + ok(!ret, "VirtualProtect should fail\n"); +- todo_wine + ok(GetLastError() == ERROR_NOACCESS, "expected ERROR_NOACCESS, got %d\n", GetLastError()); + old_prot = 0xdeadbeef; + ret = VirtualProtect(base, si.dwPageSize, PAGE_NOACCESS, &old_prot); + ok(ret, "VirtualProtect failed %d\n", GetLastError()); +- todo_wine + ok(old_prot == PAGE_NOACCESS, "got %#x != expected PAGE_NOACCESS\n", old_prot); + + addr = base; size = si.dwPageSize; + status = pNtProtectVirtualMemory(GetCurrentProcess(), &addr, &size, PAGE_READONLY, NULL); +- todo_wine + ok(status == STATUS_ACCESS_VIOLATION, "NtProtectVirtualMemory should fail, got %08x\n", status); + old_prot = 0xdeadbeef; + addr = base; size = si.dwPageSize; + status = pNtProtectVirtualMemory(GetCurrentProcess(), &addr, &size, PAGE_NOACCESS, &old_prot); + ok(status == STATUS_SUCCESS, "NtProtectVirtualMemory should succeed, got %08x\n", status); +- todo_wine + ok(old_prot == PAGE_NOACCESS, "got %#x != expected PAGE_NOACCESS\n", old_prot); + + for (i = 0; i < sizeof(td)/sizeof(td[0]); i++) +diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c +index 9d29c33..0629816 100644 +--- a/dlls/ntdll/virtual.c ++++ b/dlls/ntdll/virtual.c +@@ -2164,6 +2164,9 @@ NTSTATUS WINAPI NtProtectVirtualMemory( HANDLE process, PVOID *addr_ptr, SIZE_T + + TRACE("%p %p %08lx %08x\n", process, addr, size, new_prot ); + ++ if (!old_prot) ++ return STATUS_ACCESS_VIOLATION; ++ + if (process != NtCurrentProcess()) + { + apc_call_t call; +-- +2.3.5 + diff --git a/patches/ntdll-NtProtectVirtualMemory/definition b/patches/ntdll-NtProtectVirtualMemory/definition new file mode 100644 index 00000000..eaa0b4e8 --- /dev/null +++ b/patches/ntdll-NtProtectVirtualMemory/definition @@ -0,0 +1 @@ +Fixes: [38495] Return failure in NtProtectVirtualMemory when last argument is omitted diff --git a/patches/ntdll-NtQuerySection/0002-kernel32-tests-Add-tests-for-NtQuerySection.patch b/patches/ntdll-NtQuerySection/0002-kernel32-tests-Add-tests-for-NtQuerySection.patch index d7a45813..303ad181 100644 --- a/patches/ntdll-NtQuerySection/0002-kernel32-tests-Add-tests-for-NtQuerySection.patch +++ b/patches/ntdll-NtQuerySection/0002-kernel32-tests-Add-tests-for-NtQuerySection.patch @@ -1,4 +1,4 @@ -From 26fabea3f9d17e404f802c130f6cb8c74b1d265d Mon Sep 17 00:00:00 2001 +From 8ae00b9ad7636141e206f76ca685286311e44aca Mon Sep 17 00:00:00 2001 From: Dmitry Timoshkov Date: Thu, 16 Oct 2014 23:26:35 +0200 Subject: kernel32/tests: Add tests for NtQuerySection. (try 2) @@ -8,14 +8,15 @@ Subject: kernel32/tests: Add tests for NtQuerySection. (try 2) 1 file changed, 258 insertions(+) diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c -index 75e91d5..8abe554 100644 +index 1c70eca..fcfb254 100644 --- a/dlls/kernel32/tests/virtual.c +++ b/dlls/kernel32/tests/virtual.c -@@ -47,9 +47,27 @@ static struct _TEB * (WINAPI *pNtCurrentTeb)(void); +@@ -47,10 +47,28 @@ static struct _TEB * (WINAPI *pNtCurrentTeb)(void); static PVOID (WINAPI *pRtlAddVectoredExceptionHandler)(ULONG, PVECTORED_EXCEPTION_HANDLER); static ULONG (WINAPI *pRtlRemoveVectoredExceptionHandler)(PVOID); static BOOL (WINAPI *pGetProcessDEPPolicy)(HANDLE, LPDWORD, PBOOL); +static NTSTATUS (WINAPI *pNtQuerySection)(HANDLE, int, PVOID, ULONG, PULONG); + static NTSTATUS (WINAPI *pNtProtectVirtualMemory)(HANDLE, PVOID *, SIZE_T *, ULONG, ULONG *); /* ############################### */ @@ -39,7 +40,7 @@ index 75e91d5..8abe554 100644 static HANDLE create_target_process(const char *arg) { char **argv; -@@ -3425,6 +3443,244 @@ static void test_shared_memory_ro(BOOL is_child, DWORD child_access) +@@ -3447,6 +3465,244 @@ static void test_shared_memory_ro(BOOL is_child, DWORD child_access) CloseHandle(mapping); } @@ -284,14 +285,15 @@ index 75e91d5..8abe554 100644 START_TEST(virtual) { int argc; -@@ -3477,12 +3733,14 @@ START_TEST(virtual) +@@ -3499,6 +3755,7 @@ START_TEST(virtual) pNtCurrentTeb = (void *)GetProcAddress( hntdll, "NtCurrentTeb" ); pRtlAddVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlAddVectoredExceptionHandler" ); pRtlRemoveVectoredExceptionHandler = (void *)GetProcAddress( hntdll, "RtlRemoveVectoredExceptionHandler" ); + pNtQuerySection = (void *)GetProcAddress( hntdll, "NtQuerySection" ); + pNtProtectVirtualMemory = (void *)GetProcAddress( hntdll, "NtProtectVirtualMemory" ); test_shared_memory(FALSE); - test_shared_memory_ro(FALSE, FILE_MAP_READ|FILE_MAP_WRITE); +@@ -3506,6 +3763,7 @@ START_TEST(virtual) test_shared_memory_ro(FALSE, FILE_MAP_COPY); test_shared_memory_ro(FALSE, FILE_MAP_COPY|FILE_MAP_WRITE); test_mapping(); @@ -300,5 +302,5 @@ index 75e91d5..8abe554 100644 test_VirtualAlloc_protection(); test_VirtualProtect(); -- -2.3.0 +2.3.5 diff --git a/patches/ntdll-NtQuerySection/definition b/patches/ntdll-NtQuerySection/definition index 6a86d72c..896594cf 100644 --- a/patches/ntdll-NtQuerySection/definition +++ b/patches/ntdll-NtQuerySection/definition @@ -1 +1,2 @@ Fixes: [37338] Support for NtQuerySection +Depends: ntdll-NtProtectVirtualMemory diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index 18879cc4..fefe24bb 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -152,6 +152,7 @@ patch_enable_all () enable_ntdll_Heap_FreeLists="$1" enable_ntdll_Junction_Points="$1" enable_ntdll_LZNT1_Compression="$1" + enable_ntdll_NtProtectVirtualMemory="$1" enable_ntdll_NtQuerySection="$1" enable_ntdll_NtSetLdtEntries="$1" enable_ntdll_Pipe_SpecialCharacters="$1" @@ -532,6 +533,9 @@ patch_enable () ntdll-LZNT1_Compression) enable_ntdll_LZNT1_Compression="$2" ;; + ntdll-NtProtectVirtualMemory) + enable_ntdll_NtProtectVirtualMemory="$2" + ;; ntdll-NtQuerySection) enable_ntdll_NtQuerySection="$2" ;; @@ -1208,6 +1212,13 @@ if test "$enable_category_stable" -eq 1; then enable_ws2_32_Select=1 fi +if test "$enable_winedevice_Fix_Relocation" -eq 1; then + if test "$enable_ntdll_NtProtectVirtualMemory" -gt 1; then + abort "Patchset ntdll-NtProtectVirtualMemory disabled, but winedevice-Fix_Relocation depends on that." + fi + enable_ntdll_NtProtectVirtualMemory=1 +fi + if test "$enable_shell32_SHFileOperation" -eq 1; then if test "$enable_shell32_Progress_Dialog" -gt 1; then abort "Patchset shell32-Progress_Dialog disabled, but shell32-SHFileOperation depends on that." @@ -1327,6 +1338,13 @@ if test "$enable_ntdll_RtlIpStringToAddress" -eq 1; then enable_ntdll_LZNT1_Compression=1 fi +if test "$enable_ntdll_NtQuerySection" -eq 1; then + if test "$enable_ntdll_NtProtectVirtualMemory" -gt 1; then + abort "Patchset ntdll-NtProtectVirtualMemory disabled, but ntdll-NtQuerySection depends on that." + fi + enable_ntdll_NtProtectVirtualMemory=1 +fi + if test "$enable_ntdll_Junction_Points" -eq 1; then if test "$enable_ntdll_Fix_Free" -gt 1; then abort "Patchset ntdll-Fix_Free disabled, but ntdll-Junction_Points depends on that." @@ -3546,6 +3564,32 @@ if test "$enable_ntdll_LZNT1_Compression" -eq 1; then ) >> "$patchlist" fi +# Patchset ntdll-NtProtectVirtualMemory +# | +# | This patchset fixes the following Wine bugs: +# | * [#38495] Return failure in NtProtectVirtualMemory when last argument is omitted +# | +# | Modified files: +# | * dlls/kernel32/except.c, dlls/kernel32/tests/virtual.c, dlls/krnl386.exe16/dosmem.c, dlls/krnl386.exe16/dosvm.c, +# | dlls/ntdll/loader.c, dlls/ntdll/virtual.c, programs/winedevice/device.c +# | +if test "$enable_ntdll_NtProtectVirtualMemory" -eq 1; then + patch_apply ntdll-NtProtectVirtualMemory/0001-kernel32-tests-Add-tests-for-calling-VirtualProtect-.patch + patch_apply ntdll-NtProtectVirtualMemory/0002-kernel32-Do-not-omit-mandatory-argument-for-VirtualP.patch + patch_apply ntdll-NtProtectVirtualMemory/0003-krnl386.exe16-Do-not-omit-mandatory-argument-for-Vir.patch + patch_apply ntdll-NtProtectVirtualMemory/0004-ntdll-Do-not-omit-mandatory-argument-for-VirtualProt.patch + patch_apply ntdll-NtProtectVirtualMemory/0005-winedevice-Do-not-omit-mandatory-argument-for-Virtua.patch + patch_apply ntdll-NtProtectVirtualMemory/0006-ntdll-Return-failure-in-NtProtectVirtualMemory-when-.patch + ( + echo '+ { "Sebastian Lackner", "kernel32/tests: Add tests for calling VirtualProtect with NULL as last argument.", 1 },'; + echo '+ { "Sebastian Lackner", "kernel32: Do not omit mandatory argument for VirtualProtect.", 1 },'; + echo '+ { "Sebastian Lackner", "krnl386.exe16: Do not omit mandatory argument for VirtualProtect.", 1 },'; + echo '+ { "Sebastian Lackner", "ntdll: Do not omit mandatory argument for VirtualProtect.", 1 },'; + echo '+ { "Sebastian Lackner", "winedevice: Do not omit mandatory argument for VirtualProtect.", 1 },'; + echo '+ { "Sebastian Lackner", "ntdll: Return failure in NtProtectVirtualMemory when last argument is omitted.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-NtQuerySection # | # | This patchset fixes the following Wine bugs: diff --git a/patches/winedevice-Fix_Relocation/0001-winedevice-Avoid-invalid-memory-access-when-relocati.patch b/patches/winedevice-Fix_Relocation/0001-winedevice-Avoid-invalid-memory-access-when-relocati.patch index 81273354..4016781f 100644 --- a/patches/winedevice-Fix_Relocation/0001-winedevice-Avoid-invalid-memory-access-when-relocati.patch +++ b/patches/winedevice-Fix_Relocation/0001-winedevice-Avoid-invalid-memory-access-when-relocati.patch @@ -1,4 +1,4 @@ -From 3257b681aade105c7356f18f95cfedc49c1b3045 Mon Sep 17 00:00:00 2001 +From d0620ed863ec0155f65ef1844ee75127aa003f07 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 10 Nov 2014 04:05:38 +0100 Subject: winedevice: Avoid invalid memory access when relocation block @@ -9,7 +9,7 @@ Subject: winedevice: Avoid invalid memory access when relocation block 1 file changed, 43 insertions(+), 6 deletions(-) diff --git a/programs/winedevice/device.c b/programs/winedevice/device.c -index 9677a82..28a252d 100644 +index ef1e1ef..101fdf9 100644 --- a/programs/winedevice/device.c +++ b/programs/winedevice/device.c @@ -61,6 +61,39 @@ static LDR_MODULE *find_ldr_module( HMODULE module ) @@ -77,7 +77,7 @@ index 9677a82..28a252d 100644 + virtual_protect_save( page, 0xfff + 8, PAGE_EXECUTE_READWRITE, old_prot ); rel = LdrProcessRelocationBlock( page, (rel->SizeOfBlock - sizeof(*rel)) / sizeof(USHORT), (USHORT *)(rel + 1), delta ); -- if (old != PAGE_EXECUTE_READWRITE) VirtualProtect( page, info.PageSize, old, NULL ); +- if (old != PAGE_EXECUTE_READWRITE) VirtualProtect( page, info.PageSize, old, &old ); + virtual_protect_load( page, 0xfff + 8, old_prot ); if (!rel) goto error; } @@ -86,8 +86,8 @@ index 9677a82..28a252d 100644 - VirtualProtect( nt, size, PAGE_READWRITE, &old ); + VirtualProtect( nt, size, PAGE_READWRITE, &old_prot[0] ); nt->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = 0; -- VirtualProtect( nt, size, old, NULL ); -+ VirtualProtect( nt, size, old_prot[0], NULL ); +- VirtualProtect( nt, size, old, &old ); ++ VirtualProtect( nt, size, old_prot[0], &old_prot[0] ); } } diff --git a/patches/winedevice-Fix_Relocation/definition b/patches/winedevice-Fix_Relocation/definition index 98073111..700f4400 100644 --- a/patches/winedevice-Fix_Relocation/definition +++ b/patches/winedevice-Fix_Relocation/definition @@ -1 +1,2 @@ Fixes: [28254] Fix crash of winedevice when relocation entry crosses page boundary +Depends: ntdll-NtProtectVirtualMemory