Commit 709b536f authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

rpcrt4: The allocation hint in request and response packets is just that - a hint.

It is not an error if the stub data exceeds this size, so reallocate the buffer with the newly calculated size and continue.
parent fbe829cb
...@@ -50,6 +50,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(rpc); ...@@ -50,6 +50,8 @@ WINE_DEFAULT_DEBUG_CHANNEL(rpc);
#define ROUND_UP_AMOUNT(value, alignment) \ #define ROUND_UP_AMOUNT(value, alignment) \
(((alignment) - (((value) % (alignment)))) % (alignment)) (((alignment) - (((value) % (alignment)))) % (alignment))
static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg);
static DWORD RPCRT4_GetHeaderSize(RpcPktHdr *Header) static DWORD RPCRT4_GetHeaderSize(RpcPktHdr *Header)
{ {
static const DWORD header_sizes[] = { static const DWORD header_sizes[] = {
...@@ -476,7 +478,6 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, ...@@ -476,7 +478,6 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
unsigned long data_length; unsigned long data_length;
unsigned long buffer_length; unsigned long buffer_length;
unsigned long auth_length; unsigned long auth_length;
unsigned char *buffer_ptr;
unsigned char *auth_data = NULL; unsigned char *auth_data = NULL;
RpcPktCommonHdr common_hdr; RpcPktCommonHdr common_hdr;
...@@ -545,7 +546,6 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, ...@@ -545,7 +546,6 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
} }
} }
buffer_length = 0; buffer_length = 0;
buffer_ptr = pMsg->Buffer;
while (TRUE) while (TRUE)
{ {
unsigned int header_auth_len = RPC_AUTH_VERIFIER_LEN(&(*Header)->common); unsigned int header_auth_len = RPC_AUTH_VERIFIER_LEN(&(*Header)->common);
...@@ -567,16 +567,24 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, ...@@ -567,16 +567,24 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
goto fail; goto fail;
} }
data_length = (*Header)->common.frag_len - hdr_length - header_auth_len; if (((*Header)->common.flags & RPC_FLG_FIRST) != first_flag) {
if (((*Header)->common.flags & RPC_FLG_FIRST) != first_flag || TRACE("invalid packet flags\n");
data_length + buffer_length > pMsg->BufferLength) {
TRACE("invalid packet flags or buffer length\n");
status = RPC_S_PROTOCOL_ERROR; status = RPC_S_PROTOCOL_ERROR;
goto fail; goto fail;
} }
data_length = (*Header)->common.frag_len - hdr_length - header_auth_len;
if (data_length + buffer_length > pMsg->BufferLength) {
TRACE("allocation hint exceeded, new buffer length = %ld\n",
data_length + buffer_length);
pMsg->BufferLength = data_length + buffer_length;
status = I_RpcReAllocateBuffer(pMsg);
if (status != RPC_S_OK) goto fail;
}
if (data_length == 0) dwRead = 0; else if (data_length == 0) dwRead = 0; else
dwRead = rpcrt4_conn_read(Connection, buffer_ptr, data_length); dwRead = rpcrt4_conn_read(Connection,
(unsigned char *)pMsg->Buffer + buffer_length, data_length);
if (dwRead != data_length) { if (dwRead != data_length) {
WARN("bad data length, %ld/%ld\n", dwRead, data_length); WARN("bad data length, %ld/%ld\n", dwRead, data_length);
status = RPC_S_PROTOCOL_ERROR; status = RPC_S_PROTOCOL_ERROR;
...@@ -610,7 +618,6 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header, ...@@ -610,7 +618,6 @@ RPC_STATUS RPCRT4_Receive(RpcConnection *Connection, RpcPktHdr **Header,
goto fail; goto fail;
} }
buffer_ptr += data_length;
first_flag = 0; first_flag = 0;
} else { } else {
break; break;
...@@ -655,6 +662,18 @@ RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg) ...@@ -655,6 +662,18 @@ RPC_STATUS WINAPI I_RpcGetBuffer(PRPC_MESSAGE pMsg)
} }
/*********************************************************************** /***********************************************************************
* I_RpcReAllocateBuffer (internal)
*/
static RPC_STATUS I_RpcReAllocateBuffer(PRPC_MESSAGE pMsg)
{
TRACE("(%p): BufferLength=%d\n", pMsg, pMsg->BufferLength);
pMsg->Buffer = HeapReAlloc(GetProcessHeap(), 0, pMsg->Buffer, pMsg->BufferLength);
TRACE("Buffer=%p\n", pMsg->Buffer);
return pMsg->Buffer ? RPC_S_OK : RPC_S_OUT_OF_RESOURCES;
}
/***********************************************************************
* I_RpcFreeBuffer [RPCRT4.@] * I_RpcFreeBuffer [RPCRT4.@]
*/ */
RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg) RPC_STATUS WINAPI I_RpcFreeBuffer(PRPC_MESSAGE pMsg)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment