In IcmpSendEcho2Ex, if STATUS_PENDING is returned from NtDeviceIoControlFile, there are two cases. If no event handle or apc rountine were given, we wait for the request to completion before returning, thus freeing the apc context is fine in this case. But if an event handle _is_ given, we will return STATUS_PENDING, and the request will still be in flight at this point, and we cannot free the apc context.
However, the condition for freeing the context only checks for apc_routine, and not event, resulting in use-after-free if an apc_routine is not given but an event is.
-- v2: iphlpapi: Fix use-after-free of apc context.
From: Yuxuan Shui yshui@codeweavers.com
In IcmpSendEcho2Ex, if STATUS_PENDING is returned from NtDeviceIoControlFile, there are two cases. If no event handle or apc rountine were given, we wait for the request to completion before returning, thus freeing the apc context is fine in this case. But if an event handle _is_ given, we will return STATUS_PENDING, and the request will still be in flight at this point, and we cannot free the apc context.
However, the condition for freeing the context only checks for apc_routine, and not event, resulting in use-after-free if an apc_routine is not given but an event is. --- dlls/iphlpapi/iphlpapi_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/iphlpapi/iphlpapi_main.c b/dlls/iphlpapi/iphlpapi_main.c index 172afbd62b8..78000a628b7 100644 --- a/dlls/iphlpapi/iphlpapi_main.c +++ b/dlls/iphlpapi/iphlpapi_main.c @@ -4820,7 +4820,7 @@ DWORD WINAPI IcmpSendEcho2Ex( HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc_r ret = IcmpParseReplies( reply, reply_size );
if (!event && request_event) CloseHandle( request_event ); - if (!apc_routine || status != STATUS_PENDING) heap_free( ctxt ); + if ((!apc_routine && !event) || status != STATUS_PENDING) heap_free( ctxt ); heap_free( in );
if (status) SetLastError( RtlNtStatusToDosError( status ) );