[PATCH 1/4] ntdll: Decrement IO pending count in ioqueue_thread_proc().

Paul Gofman pgofman at codeweavers.com
Tue Jul 27 17:06:59 CDT 2021


Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
    The main goal of these patches is to address use after free which happens with TPIO objects when
    the completion arrives after TpReleaseIoCompletion() was called. Windows seems to keep the TPIO
    object alive after TpReleaseIoCompletion() until it receives the number of completions equal
    to what it expects. The following aspects are currently different in Wine:
        - TpWaitForIoCompletion with cancel_pending set to TRUE in Wine treats that essentially the same
          way as TpCancelAsyncIoOperatio(). As far as my testing goes, TpCancelAsyncIoOperatio() tells us
          that the operation is canceled and the completion is not expected. While with
          TpWaitForIoCompletion(..., TRUE) Windows still expects completions but doesn't call the callback.
        - The memory for TPIO object should not freed after TpReleaseIoCompletion() until the expected number of
          completions is received.

 dlls/ntdll/threadpool.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/dlls/ntdll/threadpool.c b/dlls/ntdll/threadpool.c
index 9e99398bdee..b82d06e5e42 100644
--- a/dlls/ntdll/threadpool.c
+++ b/dlls/ntdll/threadpool.c
@@ -1536,6 +1536,8 @@ static void CALLBACK ioqueue_thread_proc( void *param )
         {
             RtlEnterCriticalSection( &io->pool->cs );
 
+            --io->u.io.pending_count;
+
             if (!array_reserve((void **)&io->u.io.completions, &io->u.io.completion_max,
                     io->u.io.completion_count + 1, sizeof(*io->u.io.completions)))
             {
@@ -2138,7 +2140,6 @@ static void tp_object_execute( struct threadpool_object *object, BOOL wait_threa
     {
         assert( object->u.io.completion_count );
         completion = object->u.io.completions[--object->u.io.completion_count];
-        object->u.io.pending_count--;
     }
 
     /* Leave critical section and do the actual callback. */
-- 
2.31.1




More information about the wine-devel mailing list