[Bug 40373] New: Double free in RPCRT4

wine-bugs at winehq.org wine-bugs at winehq.org
Mon Mar 28 16:30:53 CDT 2016


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 at winehq.org
          Reporter: timo.kreuzer at 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.aspx,
it should be allocated on the stack, so it would not be freed.

-- 
Do not reply to this email, post in Bugzilla using the
above URL to reply.
You are receiving this mail because:
You are watching all bug changes.



More information about the wine-bugs mailing list