Rémi Bernon : server: Make sure pids/tids are multiples of four.

Alexandre Julliard julliard at winehq.org
Mon Apr 27 15:19:29 CDT 2020


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

Author: Rémi Bernon <rbernon at codeweavers.com>
Date:   Sat Apr 25 10:05:10 2020 +0200

server: Make sure pids/tids are multiples of four.

Street Fighter V unpacker relies on it when validating other processes
for its anti-debug checks, it uses (PID&0xfffffffc)>>2 as an array index
and then checks back indexes against PIDs, and terminates early if some
PIDs do not match.

Signed-off-by: Rémi Bernon <rbernon at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/ntdll/tests/info.c |  4 ----
 server/process.c        | 31 ++++++++++++++++++-------------
 2 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/dlls/ntdll/tests/info.c b/dlls/ntdll/tests/info.c
index 1576f5ca97..e28eefa986 100644
--- a/dlls/ntdll/tests/info.c
+++ b/dlls/ntdll/tests/info.c
@@ -409,7 +409,6 @@ static void test_query_process(void)
             DWORD_PTR tid;
             DWORD j;
 
-            todo_wine_if(last_pid & 3)
             ok(!(last_pid & 3), "Unexpected PID low bits: %p\n", spi->UniqueProcessId);
             for ( j = 0; j < spi->dwThreadCount; j++) 
             {
@@ -419,7 +418,6 @@ static void test_query_process(void)
                      spi->ti[j].ClientId.UniqueProcess, spi->UniqueProcessId);
 
                 tid = (DWORD_PTR)spi->ti[j].ClientId.UniqueThread;
-                todo_wine_if(tid & 3)
                 ok(!(tid & 3), "Unexpected TID low bits: %p\n", spi->ti[j].ClientId.UniqueThread);
             }
         }
@@ -450,7 +448,6 @@ static void test_query_process(void)
         cid.UniqueThread = 0;
 
         status = NtOpenProcess( &handle, PROCESS_QUERY_LIMITED_INFORMATION, &attr, &cid );
-        todo_wine_if( status != STATUS_SUCCESS )
         ok( status == STATUS_SUCCESS || broken( status == STATUS_ACCESS_DENIED ) /* wxppro */,
             "NtOpenProcess returned:%x\n", status );
         if (status != STATUS_SUCCESS) continue;
@@ -470,7 +467,6 @@ static void test_query_process(void)
         cid.UniqueThread = ULongToHandle(GetCurrentThreadId() + i);
 
         status = NtOpenThread( &handle, THREAD_QUERY_LIMITED_INFORMATION, &attr, &cid );
-        todo_wine_if( status != STATUS_SUCCESS )
         ok( status == STATUS_SUCCESS || broken( status == STATUS_ACCESS_DENIED ) /* wxppro */,
             "NtOpenThread returned:%x\n", status );
         if (status != STATUS_SUCCESS) continue;
diff --git a/server/process.c b/server/process.c
index 73984f363f..211207ed03 100644
--- a/server/process.c
+++ b/server/process.c
@@ -339,21 +339,24 @@ static void kill_all_processes(void);
 
 #define PTID_OFFSET 8  /* offset for first ptid value */
 
+static unsigned int index_from_ptid(unsigned int id) { return id / 4; }
+static unsigned int ptid_from_index(unsigned int index) { return index * 4; }
+
 /* allocate a new process or thread id */
 unsigned int alloc_ptid( void *ptr )
 {
     struct ptid_entry *entry;
-    unsigned int id;
+    unsigned int index;
 
     if (used_ptid_entries < alloc_ptid_entries)
     {
-        id = used_ptid_entries + PTID_OFFSET;
+        index = used_ptid_entries + PTID_OFFSET;
         entry = &ptid_entries[used_ptid_entries++];
     }
     else if (next_free_ptid && num_free_ptids >= 256)
     {
-        id = next_free_ptid;
-        entry = &ptid_entries[id - PTID_OFFSET];
+        index = next_free_ptid;
+        entry = &ptid_entries[index - PTID_OFFSET];
         if (!(next_free_ptid = entry->next)) last_free_ptid = 0;
         num_free_ptids--;
     }
@@ -368,35 +371,37 @@ unsigned int alloc_ptid( void *ptr )
         }
         ptid_entries = entry;
         alloc_ptid_entries = count;
-        id = used_ptid_entries + PTID_OFFSET;
+        index = used_ptid_entries + PTID_OFFSET;
         entry = &ptid_entries[used_ptid_entries++];
     }
 
     entry->ptr = ptr;
-    return id;
+    return ptid_from_index( index );
 }
 
 /* free a process or thread id */
 void free_ptid( unsigned int id )
 {
-    struct ptid_entry *entry = &ptid_entries[id - PTID_OFFSET];
+    unsigned int index = index_from_ptid( id );
+    struct ptid_entry *entry = &ptid_entries[index - PTID_OFFSET];
 
     entry->ptr  = NULL;
     entry->next = 0;
 
     /* append to end of free list so that we don't reuse it too early */
-    if (last_free_ptid) ptid_entries[last_free_ptid - PTID_OFFSET].next = id;
-    else next_free_ptid = id;
-    last_free_ptid = id;
+    if (last_free_ptid) ptid_entries[last_free_ptid - PTID_OFFSET].next = index;
+    else next_free_ptid = index;
+    last_free_ptid = index;
     num_free_ptids++;
 }
 
 /* retrieve the pointer corresponding to a process or thread id */
 void *get_ptid_entry( unsigned int id )
 {
-    if (id < PTID_OFFSET) return NULL;
-    if (id - PTID_OFFSET >= used_ptid_entries) return NULL;
-    return ptid_entries[id - PTID_OFFSET].ptr;
+    unsigned int index = index_from_ptid( id );
+    if (index < PTID_OFFSET) return NULL;
+    if (index - PTID_OFFSET >= used_ptid_entries) return NULL;
+    return ptid_entries[index - PTID_OFFSET].ptr;
 }
 
 /* return the main thread of the process */




More information about the wine-cvs mailing list