Skip to content

services: Fix use-after-free during shutdown.

Yuxuan Shui requested to merge yshui/wine:services-uaf into master

Since rpc processes requests on a work queue, it might hold a referecen to the connection while the main thread is shutting down and freeing the database. When the work item completes, it will release the connection which in turn calls services.exe's rundown function which uses the freed database.


I don't know the trigger condition for this. Logging shows scmdatabase_destroy isn't always reached (does wineserver kill services.exe?). I think terminating all db->processes is supposed to cause all services to be destroyed? but in very rare circumstances, a RPCRT4_worker_thread might be running and hold on to a service preventing it from being freed.

Here is a stack trace for it:

ASan: read of 8 bytes at 00007FFFFF35E660, caller 00006FFFFE40A756 (RtlEnterCriticalSection, ../dlls/ntdll/sync.c:354,13)
stacktrace:
	00006FFFFE40A756 (RtlEnterCriticalSection, ../dlls/ntdll/sync.c:354,13)
	00007FFFFE0158EA (service_lock, ../programs/services/services.c:750,1)
	00007FFFFE002340 (SC_RPC_HANDLE_destroy, ../programs/services/rpc.c:316,13)
	00007FFFFE002578 (SC_RPC_HANDLE_rundown, ../programs/services/rpc.c:2190,1)
	00006FFFEDD4299F (RpcContextHandle_Destroy, ../dlls/rpcrt4/rpc_assoc.c:559,25)
	00006FFFEDD3A9B9 (RpcAssoc_Release, ../dlls/rpcrt4/rpc_assoc.c:210,9)
	00006FFFEDD2EA61 (RPCRT4_ReleaseBinding, ../dlls/rpcrt4/rpc_binding.c:244,15)
	00006FFFEDD2EFF1 (RPCRT4_ReleaseConnection, ../dlls/rpcrt4/rpc_transport.c:3407,41)
	00006FFFEDD376B0 (RPCRT4_worker_thread, ../dlls/rpcrt4/rpc_server.c:539,3)
	00006FFFFE4EA2E3 (NtCurrentTeb, ../include/winnt.h:2484,5 <- GetProcessHeap, ../include/winbase.h:2686,24 <- process_rtl_work_item, ../dlls/ntdll/threadpool.c:414,5)
	00006FFFFE5044AF (tp_object_execute, ../dlls/ntdll/threadpool.c:2234,13)
	00006FFFFE501169 (threadpool_worker_proc, ../dlls/ntdll/threadpool.c:2366,13)
	00006FFFFD074FC3 (BaseThreadInitThunk, ../dlls/kernel32/thread.c:61,5)
	00006FFFFE3DFDB3 (RtlUserThreadStart)
info:
	heap-use-after-free, addr 00007FFFFF35E660
	allocated user region: [00007FFFFF35E610, 00007FFFFF35E668) 88
	allocated by 7c0
	00006FFFFE3F7962 (RtlAllocateHeap, ../dlls/ntdll/heap.c:2320,5)
	00006FFFF794E8E3 (msvcrt_heap_alloc, ../dlls/msvcrt/heap.c:72,1)
	00006FFFF7946070 (malloc, ../dlls/msvcrt/heap.c:436,15)
	00007FFFFE013CBE (scmdatabase_create, ../programs/services/services.c:626,11)
	00007FFFFE00E7B2 (main, ../programs/services/services.c:1310,11)
	00007FFFFE00EB50 (mainCRTStartup, ../dlls/msvcrt/crt_main.c:60,11)
	00006FFFFD074FC3 (BaseThreadInitThunk, ../dlls/kernel32/thread.c:61,5)
	00006FFFFE3DFDB3 (RtlUserThreadStart)
	freed by 1290
	00006FFFFE4116BD (RtlFreeHeap, ../dlls/ntdll/heap.c:2429,13)
	00006FFFF794E9AB (msvcrt_heap_free, ../dlls/msvcrt/heap.c:115,1)
	00006FFFF7932DA0 (free, ../dlls/msvcrt/heap.c:415,1)
	00007FFFFE013FD0 (scmdatabase_destroy, ../programs/services/services.c:652,1)
	00007FFFFE00E91F (main, ../programs/services/services.c:1332,9)
	00007FFFFE00EB50 (mainCRTStartup, ../dlls/msvcrt/crt_main.c:60,11)
	00006FFFFD074FC3 (BaseThreadInitThunk, ../dlls/kernel32/thread.c:61,5)
	00006FFFFE3DFDB3 (RtlUserThreadStart)

Solution here is very dumb, please let me know if there's a better way.

Merge request reports

Loading