Commit 5a3c34eb authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

rpcrt4: Check there is enough space in the buffer and that the size doesn't…

rpcrt4: Check there is enough space in the buffer and that the size doesn't cause an overflow when copying data to it.
parent d0223ecc
...@@ -577,7 +577,7 @@ static inline ULONG safe_multiply(ULONG a, ULONG b) ...@@ -577,7 +577,7 @@ static inline ULONG safe_multiply(ULONG a, ULONG b)
static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size) static inline void safe_buffer_increment(MIDL_STUB_MESSAGE *pStubMsg, ULONG size)
{ {
if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */ if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
(pStubMsg->Buffer + size > pStubMsg->BufferEnd)) (pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
RpcRaiseException(RPC_X_BAD_STUB_DATA); RpcRaiseException(RPC_X_BAD_STUB_DATA);
pStubMsg->Buffer += size; pStubMsg->Buffer += size;
} }
...@@ -604,6 +604,21 @@ static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, U ...@@ -604,6 +604,21 @@ static inline void safe_copy_from_buffer(MIDL_STUB_MESSAGE *pStubMsg, void *p, U
pStubMsg->Buffer += size; pStubMsg->Buffer += size;
} }
/* copies data to the buffer, checking that there is enough space to do so */
static inline void safe_copy_to_buffer(MIDL_STUB_MESSAGE *pStubMsg, const void *p, ULONG size)
{
if ((pStubMsg->Buffer + size < pStubMsg->Buffer) || /* integer overflow of pStubMsg->Buffer */
(pStubMsg->Buffer + size > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength))
{
ERR("buffer overflow - Buffer = %p, BufferEnd = %p, size = %u\n",
pStubMsg->Buffer, (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength,
size);
RpcRaiseException(RPC_X_BAD_STUB_DATA);
}
memcpy(pStubMsg->Buffer, p, size);
pStubMsg->Buffer += size;
}
/* /*
* NdrConformantString: * NdrConformantString:
* *
...@@ -656,10 +671,7 @@ unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg, ...@@ -656,10 +671,7 @@ unsigned char *WINAPI NdrConformantStringMarshall(MIDL_STUB_MESSAGE *pStubMsg,
WriteVariance(pStubMsg); WriteVariance(pStubMsg);
size = safe_multiply(esize, pStubMsg->ActualCount); size = safe_multiply(esize, pStubMsg->ActualCount);
memcpy(pStubMsg->Buffer, pszMessage, size); /* the string itself */ safe_copy_to_buffer(pStubMsg, pszMessage, size); /* the string itself */
pStubMsg->Buffer += size;
STD_OVERFLOW_CHECK(pStubMsg);
/* success */ /* success */
return NULL; /* is this always right? */ return NULL; /* is this always right? */
...@@ -1519,15 +1531,13 @@ unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -1519,15 +1531,13 @@ unsigned char * WINAPI NdrPointerMarshall(PMIDL_STUB_MESSAGE pStubMsg,
{ {
ALIGN_POINTER(pStubMsg->Buffer, 4); ALIGN_POINTER(pStubMsg->Buffer, 4);
Buffer = pStubMsg->Buffer; Buffer = pStubMsg->Buffer;
pStubMsg->Buffer += 4; safe_buffer_increment(pStubMsg, 4);
} }
else else
Buffer = pStubMsg->Buffer; Buffer = pStubMsg->Buffer;
PointerMarshall(pStubMsg, Buffer, pMemory, pFormat); PointerMarshall(pStubMsg, Buffer, pMemory, pFormat);
STD_OVERFLOW_CHECK(pStubMsg);
return NULL; return NULL;
} }
...@@ -1635,15 +1645,12 @@ unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -1635,15 +1645,12 @@ unsigned char * WINAPI NdrSimpleStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1); ALIGN_POINTER(pStubMsg->Buffer, pFormat[1] + 1);
memcpy(pStubMsg->Buffer, pMemory, size);
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
pStubMsg->Buffer += size; safe_copy_to_buffer(pStubMsg, pMemory, size);
if (pFormat[0] != RPC_FC_STRUCT) if (pFormat[0] != RPC_FC_STRUCT)
EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4); EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat+4);
STD_OVERFLOW_CHECK(pStubMsg);
return NULL; return NULL;
} }
...@@ -1792,30 +1799,26 @@ static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -1792,30 +1799,26 @@ static unsigned char * ComplexMarshall(PMIDL_STUB_MESSAGE pStubMsg,
case RPC_FC_SMALL: case RPC_FC_SMALL:
case RPC_FC_USMALL: case RPC_FC_USMALL:
TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory); TRACE("byte=%d <= %p\n", *(WORD*)pMemory, pMemory);
memcpy(pStubMsg->Buffer, pMemory, 1); safe_copy_to_buffer(pStubMsg, pMemory, 1);
pStubMsg->Buffer += 1;
pMemory += 1; pMemory += 1;
break; break;
case RPC_FC_WCHAR: case RPC_FC_WCHAR:
case RPC_FC_SHORT: case RPC_FC_SHORT:
case RPC_FC_USHORT: case RPC_FC_USHORT:
TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory); TRACE("short=%d <= %p\n", *(WORD*)pMemory, pMemory);
memcpy(pStubMsg->Buffer, pMemory, 2); safe_copy_to_buffer(pStubMsg, pMemory, 2);
pStubMsg->Buffer += 2;
pMemory += 2; pMemory += 2;
break; break;
case RPC_FC_LONG: case RPC_FC_LONG:
case RPC_FC_ULONG: case RPC_FC_ULONG:
case RPC_FC_ENUM32: case RPC_FC_ENUM32:
TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory); TRACE("long=%d <= %p\n", *(DWORD*)pMemory, pMemory);
memcpy(pStubMsg->Buffer, pMemory, 4); safe_copy_to_buffer(pStubMsg, pMemory, 4);
pStubMsg->Buffer += 4;
pMemory += 4; pMemory += 4;
break; break;
case RPC_FC_HYPER: case RPC_FC_HYPER:
TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory); TRACE("longlong=%s <= %p\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory), pMemory);
memcpy(pStubMsg->Buffer, pMemory, 8); safe_copy_to_buffer(pStubMsg, pMemory, 8);
pStubMsg->Buffer += 8;
pMemory += 8; pMemory += 8;
break; break;
case RPC_FC_POINTER: case RPC_FC_POINTER:
...@@ -2521,14 +2524,11 @@ unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -2521,14 +2524,11 @@ unsigned char * WINAPI NdrConformantArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
ALIGN_POINTER(pStubMsg->Buffer, alignment); ALIGN_POINTER(pStubMsg->Buffer, alignment);
size = safe_multiply(esize, pStubMsg->MaxCount); size = safe_multiply(esize, pStubMsg->MaxCount);
memcpy(pStubMsg->Buffer, pMemory, size);
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
pStubMsg->Buffer += size; safe_copy_to_buffer(pStubMsg, pMemory, size);
EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
STD_OVERFLOW_CHECK(pStubMsg);
return NULL; return NULL;
} }
...@@ -2660,14 +2660,11 @@ unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStu ...@@ -2660,14 +2660,11 @@ unsigned char* WINAPI NdrConformantVaryingArrayMarshall( PMIDL_STUB_MESSAGE pStu
bufsize = safe_multiply(esize, pStubMsg->ActualCount); bufsize = safe_multiply(esize, pStubMsg->ActualCount);
memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
pStubMsg->Buffer += bufsize; safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
STD_OVERFLOW_CHECK(pStubMsg);
return NULL; return NULL;
} }
...@@ -3383,14 +3380,11 @@ unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -3383,14 +3380,11 @@ unsigned char * WINAPI NdrConformantStructMarshall(PMIDL_STUB_MESSAGE pStubMsg,
bufsize = safe_multiply(esize, pStubMsg->MaxCount); bufsize = safe_multiply(esize, pStubMsg->MaxCount);
/* copy constant sized part of struct */ /* copy constant sized part of struct */
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
memcpy(pStubMsg->Buffer, pMemory, pCStructFormat->memory_size + bufsize); safe_copy_to_buffer(pStubMsg, pMemory, pCStructFormat->memory_size + bufsize);
pStubMsg->Buffer += pCStructFormat->memory_size + bufsize;
if (pCStructFormat->type == RPC_FC_CPSTRUCT) if (pCStructFormat->type == RPC_FC_CPSTRUCT)
EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
STD_OVERFLOW_CHECK(pStubMsg);
return NULL; return NULL;
} }
...@@ -3580,21 +3574,17 @@ unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pS ...@@ -3580,21 +3574,17 @@ unsigned char * WINAPI NdrConformantVaryingStructMarshall(PMIDL_STUB_MESSAGE pS
/* write constant sized part */ /* write constant sized part */
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
memcpy(pStubMsg->Buffer, pMemory, pCVStructFormat->memory_size); safe_copy_to_buffer(pStubMsg, pMemory, pCVStructFormat->memory_size);
pStubMsg->Buffer += pCVStructFormat->memory_size;
WriteVariance(pStubMsg); WriteVariance(pStubMsg);
bufsize = safe_multiply(esize, pStubMsg->ActualCount); bufsize = safe_multiply(esize, pStubMsg->ActualCount);
/* write array part */ /* write array part */
memcpy(pStubMsg->Buffer, pMemory + pCVStructFormat->memory_size, bufsize); safe_copy_to_buffer(pStubMsg, pMemory + pCVStructFormat->memory_size, bufsize);
pStubMsg->Buffer += bufsize;
EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
STD_OVERFLOW_CHECK(pStubMsg);
return NULL; return NULL;
} }
...@@ -3954,9 +3944,8 @@ unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -3954,9 +3944,8 @@ unsigned char * WINAPI NdrFixedArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
pFormat = (const unsigned char *)(pLgFArrayFormat + 1); pFormat = (const unsigned char *)(pLgFArrayFormat + 1);
} }
memcpy(pStubMsg->Buffer, pMemory, total_size);
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
pStubMsg->Buffer += total_size; safe_copy_to_buffer(pStubMsg, pMemory, total_size);
pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); pFormat = EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
...@@ -4171,14 +4160,11 @@ unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg, ...@@ -4171,14 +4160,11 @@ unsigned char * WINAPI NdrVaryingArrayMarshall(PMIDL_STUB_MESSAGE pStubMsg,
ALIGN_POINTER(pStubMsg->Buffer, alignment); ALIGN_POINTER(pStubMsg->Buffer, alignment);
bufsize = safe_multiply(esize, pStubMsg->ActualCount); bufsize = safe_multiply(esize, pStubMsg->ActualCount);
memcpy(pStubMsg->Buffer, pMemory + pStubMsg->Offset, bufsize);
pStubMsg->BufferMark = pStubMsg->Buffer; pStubMsg->BufferMark = pStubMsg->Buffer;
pStubMsg->Buffer += bufsize; safe_copy_to_buffer(pStubMsg, pMemory + pStubMsg->Offset, bufsize);
EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat); EmbeddedPointerMarshall(pStubMsg, pMemory, pFormat);
STD_OVERFLOW_CHECK(pStubMsg);
return NULL; return NULL;
} }
...@@ -5326,16 +5312,14 @@ static unsigned char *WINAPI NdrBaseTypeMarshall( ...@@ -5326,16 +5312,14 @@ static unsigned char *WINAPI NdrBaseTypeMarshall(
case RPC_FC_CHAR: case RPC_FC_CHAR:
case RPC_FC_SMALL: case RPC_FC_SMALL:
case RPC_FC_USMALL: case RPC_FC_USMALL:
*(UCHAR *)pStubMsg->Buffer = *(UCHAR *)pMemory; safe_copy_to_buffer(pStubMsg, pMemory, sizeof(UCHAR));
pStubMsg->Buffer += sizeof(UCHAR);
TRACE("value: 0x%02x\n", *(UCHAR *)pMemory); TRACE("value: 0x%02x\n", *(UCHAR *)pMemory);
break; break;
case RPC_FC_WCHAR: case RPC_FC_WCHAR:
case RPC_FC_SHORT: case RPC_FC_SHORT:
case RPC_FC_USHORT: case RPC_FC_USHORT:
ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
*(USHORT *)pStubMsg->Buffer = *(USHORT *)pMemory; safe_copy_to_buffer(pStubMsg, pMemory, sizeof(USHORT));
pStubMsg->Buffer += sizeof(USHORT);
TRACE("value: 0x%04x\n", *(USHORT *)pMemory); TRACE("value: 0x%04x\n", *(USHORT *)pMemory);
break; break;
case RPC_FC_LONG: case RPC_FC_LONG:
...@@ -5343,24 +5327,20 @@ static unsigned char *WINAPI NdrBaseTypeMarshall( ...@@ -5343,24 +5327,20 @@ static unsigned char *WINAPI NdrBaseTypeMarshall(
case RPC_FC_ERROR_STATUS_T: case RPC_FC_ERROR_STATUS_T:
case RPC_FC_ENUM32: case RPC_FC_ENUM32:
ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG)); ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONG));
*(ULONG *)pStubMsg->Buffer = *(ULONG *)pMemory; safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONG));
pStubMsg->Buffer += sizeof(ULONG);
TRACE("value: 0x%08x\n", *(ULONG *)pMemory); TRACE("value: 0x%08x\n", *(ULONG *)pMemory);
break; break;
case RPC_FC_FLOAT: case RPC_FC_FLOAT:
ALIGN_POINTER(pStubMsg->Buffer, sizeof(float)); ALIGN_POINTER(pStubMsg->Buffer, sizeof(float));
*(float *)pStubMsg->Buffer = *(float *)pMemory; safe_copy_to_buffer(pStubMsg, pMemory, sizeof(float));
pStubMsg->Buffer += sizeof(float);
break; break;
case RPC_FC_DOUBLE: case RPC_FC_DOUBLE:
ALIGN_POINTER(pStubMsg->Buffer, sizeof(double)); ALIGN_POINTER(pStubMsg->Buffer, sizeof(double));
*(double *)pStubMsg->Buffer = *(double *)pMemory; safe_copy_to_buffer(pStubMsg, pMemory, sizeof(double));
pStubMsg->Buffer += sizeof(double);
break; break;
case RPC_FC_HYPER: case RPC_FC_HYPER:
ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG)); ALIGN_POINTER(pStubMsg->Buffer, sizeof(ULONGLONG));
*(ULONGLONG *)pStubMsg->Buffer = *(ULONGLONG *)pMemory; safe_copy_to_buffer(pStubMsg, pMemory, sizeof(ULONGLONG));
pStubMsg->Buffer += sizeof(ULONGLONG);
TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory)); TRACE("value: %s\n", wine_dbgstr_longlong(*(ULONGLONG*)pMemory));
break; break;
case RPC_FC_ENUM16: case RPC_FC_ENUM16:
...@@ -5368,6 +5348,8 @@ static unsigned char *WINAPI NdrBaseTypeMarshall( ...@@ -5368,6 +5348,8 @@ static unsigned char *WINAPI NdrBaseTypeMarshall(
if (*(UINT *)pMemory > SHRT_MAX) if (*(UINT *)pMemory > SHRT_MAX)
RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE); RpcRaiseException(RPC_X_ENUM_VALUE_OUT_OF_RANGE);
ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT)); ALIGN_POINTER(pStubMsg->Buffer, sizeof(USHORT));
if (pStubMsg->Buffer + sizeof(USHORT) > (unsigned char *)pStubMsg->RpcMsg->Buffer + pStubMsg->BufferLength)
RpcRaiseException(RPC_X_BAD_STUB_DATA);
*(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory; *(USHORT *)pStubMsg->Buffer = *(UINT *)pMemory;
pStubMsg->Buffer += sizeof(USHORT); pStubMsg->Buffer += sizeof(USHORT);
TRACE("value: 0x%04x\n", *(UINT *)pMemory); TRACE("value: 0x%04x\n", *(UINT *)pMemory);
...@@ -5378,8 +5360,6 @@ static unsigned char *WINAPI NdrBaseTypeMarshall( ...@@ -5378,8 +5360,6 @@ static unsigned char *WINAPI NdrBaseTypeMarshall(
FIXME("Unhandled base type: 0x%02x\n", *pFormat); FIXME("Unhandled base type: 0x%02x\n", *pFormat);
} }
STD_OVERFLOW_CHECK(pStubMsg);
/* FIXME: what is the correct return value? */ /* FIXME: what is the correct return value? */
return NULL; return NULL;
} }
......
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