Qian Hong : ntdll: Fixed buffer size checking for ProcessWow64Information on 64bit in NtQueryInformationProcess.

Alexandre Julliard julliard at wine.codeweavers.com
Thu Jan 15 15:55:41 CST 2015


Module: wine
Branch: master
Commit: d45bda3014cbf21e8fa8e8e429531aed4eeb530e
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=d45bda3014cbf21e8fa8e8e429531aed4eeb530e

Author: Qian Hong <qhong at codeweavers.com>
Date:   Thu Jan 15 16:52:26 2015 +0800

ntdll: Fixed buffer size checking for ProcessWow64Information on 64bit in NtQueryInformationProcess.

---

 dlls/ntdll/process.c    | 12 +++++---
 dlls/ntdll/tests/info.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 89 insertions(+), 5 deletions(-)

diff --git a/dlls/ntdll/process.c b/dlls/ntdll/process.c
index 633a668..3defb6e 100644
--- a/dlls/ntdll/process.c
+++ b/dlls/ntdll/process.c
@@ -403,10 +403,13 @@ NTSTATUS WINAPI NtQueryInformationProcess(
         break;
 
     case ProcessWow64Information:
-        len = sizeof(DWORD);
-        if (ProcessInformationLength == len)
+        len = sizeof(ULONG_PTR);
+        if (ProcessInformationLength != len) ret = STATUS_INFO_LENGTH_MISMATCH;
+        else if (!ProcessInformation) ret = STATUS_ACCESS_VIOLATION;
+        else if(!ProcessHandle) ret = STATUS_INVALID_HANDLE;
+        else
         {
-            DWORD val = 0;
+            ULONG_PTR val = 0;
 
             if (ProcessHandle == GetCurrentProcess()) val = is_wow64;
             else if (server_cpus & (1 << CPU_x86_64))
@@ -418,9 +421,8 @@ NTSTATUS WINAPI NtQueryInformationProcess(
                 }
                 SERVER_END_REQ;
             }
-            *(DWORD *)ProcessInformation = val;
+            *(ULONG_PTR *)ProcessInformation = val;
         }
-        else ret = STATUS_INFO_LENGTH_MISMATCH;
         break;
     case ProcessImageFileName:
         /* FIXME: this will return a DOS path. Windows returns an NT path. Changing this would require also changing kernel32.QueryFullProcessImageName.
diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index af00401..5fff490 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -737,6 +737,84 @@ static void test_query_processor_power_info(void)
     HeapFree(GetProcessHeap(), 0, ppi);
 }
 
+static void test_query_process_wow64(void)
+{
+    NTSTATUS status;
+    ULONG ReturnLength;
+    ULONG_PTR pbi[2], dummy;
+
+    memset(&dummy, 0xcc, sizeof(dummy));
+
+    /* Do not give a handle and buffer */
+    status = pNtQueryInformationProcess(NULL, ProcessWow64Information, NULL, 0, NULL);
+    ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+
+    /* Use a correct info class and buffer size, but still no handle and buffer */
+    status = pNtQueryInformationProcess(NULL, ProcessWow64Information, NULL, sizeof(ULONG_PTR), NULL);
+    ok( status == STATUS_ACCESS_VIOLATION || status == STATUS_INVALID_HANDLE,
+        "Expected STATUS_ACCESS_VIOLATION or STATUS_INVALID_HANDLE, got %08x\n", status);
+
+    /* Use a correct info class, buffer size and handle, but no buffer */
+    status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, NULL, sizeof(ULONG_PTR), NULL);
+    ok( status == STATUS_ACCESS_VIOLATION , "Expected STATUS_ACCESS_VIOLATION, got %08x\n", status);
+
+    /* Use a correct info class, buffer and buffer size, but no handle */
+    pbi[0] = pbi[1] = dummy;
+    status = pNtQueryInformationProcess(NULL, ProcessWow64Information, pbi, sizeof(ULONG_PTR), NULL);
+    ok( status == STATUS_INVALID_HANDLE, "Expected STATUS_INVALID_HANDLE, got %08x\n", status);
+    ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]);
+    ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
+
+    /* Use a greater buffer size */
+    pbi[0] = pbi[1] = dummy;
+    status = pNtQueryInformationProcess(NULL, ProcessWow64Information, pbi, sizeof(ULONG_PTR) + 1, NULL);
+    ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+    ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]);
+    ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
+
+    /* Use no ReturnLength */
+    pbi[0] = pbi[1] = dummy;
+    status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR), NULL);
+    ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
+    trace( "Platform is_wow64 %d, ProcessInformation of ProcessWow64Information %lx\n", is_wow64, pbi[0]);
+    ok( is_wow64 == (pbi[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64, pbi[0]);
+    ok( pbi[0] != dummy, "pbi[0] %lx\n", pbi[0]);
+    ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
+    /* Test written size on 64 bit by checking high 32 bit buffer */
+    if (sizeof(ULONG_PTR) > sizeof(DWORD))
+    {
+        DWORD *ptr = (DWORD *)pbi;
+        ok( ptr[1] != (DWORD)dummy, "ptr[1] unchanged!\n");
+    }
+
+    /* Finally some correct calls */
+    pbi[0] = pbi[1] = dummy;
+    ReturnLength = 0xdeadbeef;
+    status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR), &ReturnLength);
+    ok( status == STATUS_SUCCESS, "Expected STATUS_SUCCESS, got %08x\n", status);
+    ok( is_wow64 == (pbi[0] != 0), "is_wow64 %x, pbi[0] %lx\n", is_wow64, pbi[0]);
+    ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
+    ok( ReturnLength == sizeof(ULONG_PTR), "Inconsistent length %d\n", ReturnLength);
+
+    /* Everything is correct except a too small buffer size */
+    pbi[0] = pbi[1] = dummy;
+    ReturnLength = 0xdeadbeef;
+    status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR) - 1, &ReturnLength);
+    ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+    ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]);
+    ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
+    todo_wine ok( ReturnLength == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength);
+
+    /* Everything is correct except a too large buffer size */
+    pbi[0] = pbi[1] = dummy;
+    ReturnLength = 0xdeadbeef;
+    status = pNtQueryInformationProcess(GetCurrentProcess(), ProcessWow64Information, pbi, sizeof(ULONG_PTR) + 1, &ReturnLength);
+    ok( status == STATUS_INFO_LENGTH_MISMATCH, "Expected STATUS_INFO_LENGTH_MISMATCH, got %08x\n", status);
+    ok( pbi[0] == dummy, "pbi[0] changed to %lx\n", pbi[0]);
+    ok( pbi[1] == dummy, "pbi[1] changed to %lx\n", pbi[1]);
+    todo_wine ok( ReturnLength == 0xdeadbeef, "Expected 0xdeadbeef, got %d\n", ReturnLength);
+}
+
 static void test_query_process_basic(void)
 {
     NTSTATUS status;
@@ -1714,6 +1792,10 @@ START_TEST(info)
     trace("Starting test_query_process_handlecount()\n");
     test_query_process_handlecount();
 
+    /* 0x1A ProcessWow64Information */
+    trace("Starting test_query_process_wow64()\n");
+    test_query_process_wow64();
+
     /* 0x1B ProcessImageFileName */
     trace("Starting test_query_process_image_file_name()\n");
     test_query_process_image_file_name();




More information about the wine-cvs mailing list