https://bugs.winehq.org/show_bug.cgi?id=40373
Bug ID: 40373 Summary: Double free in RPCRT4 Product: Wine Version: unspecified Hardware: x86 OS: Windows Status: UNCONFIRMED Severity: normal Priority: P2 Component: rpc Assignee: wine-bugs@winehq.org Reporter: timo.kreuzer@web.de
Created attachment 54078 --> https://bugs.winehq.org/attachment.cgi?id=54078 idl file
RPCRT4 can double free parameter allocations from NdrStubCall2
The specific situation where this happened is the following:
- The idl file was lsa.idl from ReactOS (file attached) - The function was LsarRetrievePrivateData - The parameter was EncryptedData - It happened in cleanup of marshalled parameters within NdrStubCall2, after calling this function
What happened:
- NdrStubCall2 iterates though the marshaling phases - On STUBLESS_MUSTFREE: - params[i].attr.MustFree is TRUE for parameter i = 2 (EncryptedData) - call_freer() is invoked with a pointer pointing to the parameter (pointer to the parameter location!) - param->attr.IsByValue is FALSE, so pMemory = *(unsigned char **)pMemory; pMemory is now equal to the value EncryptedData (a pointer to a pointer) - NdrFreer[pFormat[0] & NDR_TABLE_MASK] (NdrPointerFree) is called - NdrPointerFree calls PointerFree - desc = pFormat + *(const SHORT*)pFormat; - (attr & RPC_FC_P_DEREF) is TRUE, so current_pointer = *(unsigned char**)Pointer; (In the observed case this is NULL, since the function returned NULL in that OUT parameter) - NdrFreer[*desc & NDR_TABLE_MASK] (NdrPointerFree) is called with current_pointer (doing nothing, since it's NULL) - Pointer is not within pStubMsg->Buffer - attr & RPC_FC_P_ONSTACK is not set (this is different on midl!) - NdrFree(pStubMsg, Pointer) is called, freeing the pointer - On STUBLESS_FREE: - params[i].attr.ServerAllocSize is != 0 - HeapFree(GetProcessHeap(), 0, *(void **)pArg) is called on the pointer that was freed before.
I cannot say exactly what is wrong here, but I see 2 potential problems: - The type for the parameter has different flags between midl and widl (the parameter data is the same), where widl is missing the [alloced_on_stack] flag: midl: /* 2076 */ 0x11, 0x14, /* FC_RP [alloced_on_stack] [pointer_deref] */ /* 2078 */ NdrFcShort( 0xffb6 ), /* Offset= -74 (2004) */
widl: /* 3112 (PLSAPR_CR_CIPHER_VALUE *) */ 0x11, 0x10, /* FC_RP [pointer_deref] */ NdrFcShort(0xfffa), /* Offset= -6 (3108) */ With this flag, the parameter is not freed, but that might not be the correct solution.
- Parameters with ServerAlloc are allocated from the heap, while according to https://msdn.microsoft.com/library/windows/desktop/aa374362%28v=vs.85%29.asp..., it should be allocated on the stack, so it would not be freed.
https://bugs.winehq.org/show_bug.cgi?id=40373
Zebediah Figura z.figura12@gmail.com changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|UNCONFIRMED |RESOLVED Resolution|--- |FIXED CC| |z.figura12@gmail.com Fixed by SHA1| |76a665a1c676cb64d0fb6f76dee | |3d5c3d5f4f7f5
--- Comment #1 from Zebediah Figura z.figura12@gmail.com --- Judging from the description, this was fixed by https://source.winehq.org/git/wine.git/commitdiff/76a665a1c676cb64d0fb6f76dee3d5c3d5f4f7f5. I recall a very similar problem that incited me to write that patch.
https://bugs.winehq.org/show_bug.cgi?id=40373
Alexandre Julliard julliard@winehq.org changed:
What |Removed |Added ---------------------------------------------------------------------------- Status|RESOLVED |CLOSED
--- Comment #2 from Alexandre Julliard julliard@winehq.org --- Closing bugs fixed in 4.10.