From 70c4687b47caf485f27cd869a0b92c5a3b630111 Mon Sep 17 00:00:00 2001 From: Sebastian Lackner Date: Mon, 16 May 2016 19:59:21 +0200 Subject: [PATCH] Added patch to fix various issues related to UnmapViewOfFile. --- ...wOfSection-must-succeed-for-all-offs.patch | 112 ++++++++++++++++++ ...-UnmapViewOfFile-on-Win-9X-when-addr.patch | 38 ++++++ patches/ntdll-NtUnmapViewOfSection/definition | 1 + patches/patchinstall.sh | 21 ++++ 4 files changed, 172 insertions(+) create mode 100644 patches/ntdll-NtUnmapViewOfSection/0001-ntdll-NtUnmapViewOfSection-must-succeed-for-all-offs.patch create mode 100644 patches/ntdll-NtUnmapViewOfSection/0002-kernel32-Fail-in-UnmapViewOfFile-on-Win-9X-when-addr.patch create mode 100644 patches/ntdll-NtUnmapViewOfSection/definition diff --git a/patches/ntdll-NtUnmapViewOfSection/0001-ntdll-NtUnmapViewOfSection-must-succeed-for-all-offs.patch b/patches/ntdll-NtUnmapViewOfSection/0001-ntdll-NtUnmapViewOfSection-must-succeed-for-all-offs.patch new file mode 100644 index 00000000..f15846cb --- /dev/null +++ b/patches/ntdll-NtUnmapViewOfSection/0001-ntdll-NtUnmapViewOfSection-must-succeed-for-all-offs.patch @@ -0,0 +1,112 @@ +From fcbd459e01f674633462156e45c77397e5af3e34 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Mon, 16 May 2016 18:50:55 +0200 +Subject: ntdll: NtUnmapViewOfSection must succeed for all offsets within the + mapped range. + +--- + dlls/kernel32/tests/virtual.c | 27 ++++++++++++++++++++++++++- + dlls/ntdll/tests/info.c | 6 +++--- + dlls/ntdll/virtual.c | 3 +-- + 3 files changed, 30 insertions(+), 6 deletions(-) + +diff --git a/dlls/kernel32/tests/virtual.c b/dlls/kernel32/tests/virtual.c +index 37206b5..552cbb4 100644 +--- a/dlls/kernel32/tests/virtual.c ++++ b/dlls/kernel32/tests/virtual.c +@@ -435,7 +435,7 @@ static void test_MapViewOfFile(void) + SetLastError(0xdeadbeef); + file = CreateFileA( testfile, GENERIC_READ|GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0 ); + ok( file != INVALID_HANDLE_VALUE, "CreateFile error %u\n", GetLastError() ); +- SetFilePointer( file, 4096, NULL, FILE_BEGIN ); ++ SetFilePointer( file, 12288, NULL, FILE_BEGIN ); + SetEndOfFile( file ); + + /* read/write mapping */ +@@ -994,6 +994,31 @@ static void test_MapViewOfFile(void) + ok(info.State == MEM_FREE, "%#x != MEM_FREE\n", info.State); + ok(info.Type == 0, "%#x != 0\n", info.Type); + ++ mapping = CreateFileMappingA( file, NULL, PAGE_READONLY, 0, 12288, NULL ); ++ ok( mapping != 0, "CreateFileMappingA failed with error %u\n", GetLastError() ); ++ ++ ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 12288 ); ++ ok( ptr != NULL, "MapViewOfFile failed with error %u\n", GetLastError() ); ++ ++ ret = UnmapViewOfFile( (char *)ptr + 100 ); ++ ok( ret, "UnmapViewOfFile failed with error %u\n", GetLastError() ); ++ if (!ret) UnmapViewOfFile( ptr ); ++ ++ ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 12288 ); ++ ok( ptr != NULL, "MapViewOfFile failed with error %u\n", GetLastError() ); ++ ++ ret = UnmapViewOfFile( (char *)ptr + 4096 ); ++ ok( ret, "UnmapViewOfFile failed with error %u\n", GetLastError() ); ++ if (!ret) UnmapViewOfFile( ptr ); ++ ++ ptr = MapViewOfFile( mapping, FILE_MAP_READ, 0, 0, 12288 ); ++ ok( ptr != NULL, "MapViewOfFile failed with error %u\n", GetLastError() ); ++ ++ ret = UnmapViewOfFile( (char *)ptr + 4096 + 100 ); ++ ok( ret, "UnmapViewOfFile failed with error %u\n", GetLastError() ); ++ if (!ret) UnmapViewOfFile( ptr ); ++ ++ CloseHandle(mapping); + CloseHandle(file); + DeleteFileA(testfile); + } +diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c +index be355fb..19c7d66 100644 +--- a/dlls/ntdll/tests/info.c ++++ b/dlls/ntdll/tests/info.c +@@ -1643,7 +1643,7 @@ static void test_mapprotection(void) + status = pNtSetInformationProcess( GetCurrentProcess(), ProcessExecuteFlags, &flags, sizeof(flags) ); + ok( (status == STATUS_SUCCESS) || (status == STATUS_INVALID_INFO_CLASS), "Expected STATUS_SUCCESS, got %08x\n", status); + +- size.u.LowPart = 0x1000; ++ size.u.LowPart = 0x2000; + size.u.HighPart = 0; + status = pNtCreateSection ( &h, + STANDARD_RIGHTS_REQUIRED | SECTION_QUERY | SECTION_MAP_READ | SECTION_MAP_WRITE | SECTION_MAP_EXECUTE, +@@ -1657,7 +1657,7 @@ static void test_mapprotection(void) + + offset.u.LowPart = 0; + offset.u.HighPart = 0; +- count = 0x1000; ++ count = 0x2000; + addr = NULL; + status = pNtMapViewOfSection ( h, GetCurrentProcess(), &addr, 0, 0, &offset, &count, ViewShare, 0, PAGE_READWRITE); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); +@@ -1680,7 +1680,7 @@ static void test_mapprotection(void) + ok( retlen == sizeof(info), "Expected STATUS_SUCCESS, got %08x\n", status); + ok((info.Protect & ~PAGE_NOCACHE) == PAGE_READWRITE, "addr.Protect is not PAGE_READWRITE, but 0x%x\n", info.Protect); + +- status = pNtUnmapViewOfSection (GetCurrentProcess(), addr); ++ status = pNtUnmapViewOfSection( GetCurrentProcess(), (char *)addr + 0x1050 ); + ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status); + pNtClose (h); + +diff --git a/dlls/ntdll/virtual.c b/dlls/ntdll/virtual.c +index 5c43d26..27daf96 100644 +--- a/dlls/ntdll/virtual.c ++++ b/dlls/ntdll/virtual.c +@@ -2723,7 +2723,6 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr ) + struct file_view *view; + NTSTATUS status = STATUS_NOT_MAPPED_VIEW; + sigset_t sigset; +- void *base = ROUND_ADDR( addr, page_mask ); + + if (process != NtCurrentProcess()) + { +@@ -2740,7 +2739,7 @@ NTSTATUS WINAPI NtUnmapViewOfSection( HANDLE process, PVOID addr ) + } + + server_enter_uninterrupted_section( &csVirtual, &sigset ); +- if ((view = VIRTUAL_FindView( base, 0 )) && (base == view->base) && !(view->protect & VPROT_VALLOC)) ++ if ((view = VIRTUAL_FindView( addr, 0 )) && !(view->protect & VPROT_VALLOC)) + { + delete_view( view ); + status = STATUS_SUCCESS; +-- +2.8.0 + diff --git a/patches/ntdll-NtUnmapViewOfSection/0002-kernel32-Fail-in-UnmapViewOfFile-on-Win-9X-when-addr.patch b/patches/ntdll-NtUnmapViewOfSection/0002-kernel32-Fail-in-UnmapViewOfFile-on-Win-9X-when-addr.patch new file mode 100644 index 00000000..6f3ea667 --- /dev/null +++ b/patches/ntdll-NtUnmapViewOfSection/0002-kernel32-Fail-in-UnmapViewOfFile-on-Win-9X-when-addr.patch @@ -0,0 +1,38 @@ +From 6ca6102f0f4c52dee00013a8e1d0d924f4b6c5a7 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20M=C3=BCller?= +Date: Sat, 14 May 2016 17:21:54 +0200 +Subject: kernel32: Fail in UnmapViewOfFile on Win 9X when addr is not a base + address of a mapping. + +--- + dlls/kernel32/virtual.c | 14 +++++++++++++- + 1 file changed, 13 insertions(+), 1 deletion(-) + +diff --git a/dlls/kernel32/virtual.c b/dlls/kernel32/virtual.c +index 32f2d65..7e9c2f3 100644 +--- a/dlls/kernel32/virtual.c ++++ b/dlls/kernel32/virtual.c +@@ -576,7 +576,19 @@ LPVOID WINAPI MapViewOfFileEx( HANDLE handle, DWORD access, + */ + BOOL WINAPI UnmapViewOfFile( LPCVOID addr ) + { +- NTSTATUS status = NtUnmapViewOfSection( GetCurrentProcess(), (void *)addr ); ++ NTSTATUS status; ++ ++ if (GetVersion() & 0x80000000) ++ { ++ MEMORY_BASIC_INFORMATION info; ++ if (!VirtualQuery( addr, &info, sizeof(info) ) || info.AllocationBase != addr) ++ { ++ SetLastError( ERROR_INVALID_ADDRESS ); ++ return FALSE; ++ } ++ } ++ ++ status = NtUnmapViewOfSection( GetCurrentProcess(), (void *)addr ); + if (status) SetLastError( RtlNtStatusToDosError(status) ); + return !status; + } +-- +2.8.0 + diff --git a/patches/ntdll-NtUnmapViewOfSection/definition b/patches/ntdll-NtUnmapViewOfSection/definition new file mode 100644 index 00000000..990868f8 --- /dev/null +++ b/patches/ntdll-NtUnmapViewOfSection/definition @@ -0,0 +1 @@ +Fixes: [2905] UnmapViewOfFile should fail on Win9x when addr is not the base address of a mapping diff --git a/patches/patchinstall.sh b/patches/patchinstall.sh index e5a680ad..3e2df50a 100755 --- a/patches/patchinstall.sh +++ b/patches/patchinstall.sh @@ -220,6 +220,7 @@ patch_enable_all () enable_ntdll_NtQueryInformationThread="$1" enable_ntdll_NtQuerySection="$1" enable_ntdll_NtSetLdtEntries="$1" + enable_ntdll_NtUnmapViewOfSection="$1" enable_ntdll_OSX_TEB_x86_64="$1" enable_ntdll_Pipe_SpecialCharacters="$1" enable_ntdll_ProcessQuotaLimits="$1" @@ -833,6 +834,9 @@ patch_enable () ntdll-NtSetLdtEntries) enable_ntdll_NtSetLdtEntries="$2" ;; + ntdll-NtUnmapViewOfSection) + enable_ntdll_NtUnmapViewOfSection="$2" + ;; ntdll-OSX_TEB_x86_64) enable_ntdll_OSX_TEB_x86_64="$2" ;; @@ -4978,6 +4982,23 @@ if test "$enable_ntdll_NtSetLdtEntries" -eq 1; then ) >> "$patchlist" fi +# Patchset ntdll-NtUnmapViewOfSection +# | +# | This patchset fixes the following Wine bugs: +# | * [#2905] UnmapViewOfFile should fail on Win9x when addr is not the base address of a mapping +# | +# | Modified files: +# | * dlls/kernel32/tests/virtual.c, dlls/kernel32/virtual.c, dlls/ntdll/tests/info.c, dlls/ntdll/virtual.c +# | +if test "$enable_ntdll_NtUnmapViewOfSection" -eq 1; then + patch_apply ntdll-NtUnmapViewOfSection/0001-ntdll-NtUnmapViewOfSection-must-succeed-for-all-offs.patch + patch_apply ntdll-NtUnmapViewOfSection/0002-kernel32-Fail-in-UnmapViewOfFile-on-Win-9X-when-addr.patch + ( + echo '+ { "Michael Müller", "ntdll: NtUnmapViewOfSection must succeed for all offsets within the mapped range.", 1 },'; + echo '+ { "Michael Müller", "kernel32: Fail in UnmapViewOfFile on Win 9X when addr is not a base address of a mapping.", 1 },'; + ) >> "$patchlist" +fi + # Patchset ntdll-OSX_TEB_x86_64 # | # | Modified files: