diff options
author | Tijoy Tom Kalathiparambil <tijoytk@microsoft.com> | 2016-07-07 15:03:01 -0700 |
---|---|---|
committer | Tijoy Tom Kalathiparambil <tijoytk@microsoft.com> | 2016-07-07 15:03:01 -0700 |
commit | 8d51b631b3f582a093a108acfa28c2390fe85f41 (patch) | |
tree | 21e4d7f608156222c54c4dffcd543f124692ffd3 /src/vm/ilmarshalers.cpp | |
parent | 00eca9ab295420873a551d3a9e0acde0da20338a (diff) | |
download | coreclr-8d51b631b3f582a093a108acfa28c2390fe85f41.tar.gz coreclr-8d51b631b3f582a093a108acfa28c2390fe85f41.tar.bz2 coreclr-8d51b631b3f582a093a108acfa28c2390fe85f41.zip |
MarshalAs(UnManaged.ByValArray) overflow.
For non-blittable embedded array in structs we ignored the SizeConst and wrote past the
buffer when number of elementsin the arrayis greater than SizeConst.Fix is to truncate
the array at SizeConst
MarshalAs(UnManaged.ByValTStr)
Very subtle case when the SizeConst == Number of bytes required to marshal , we
write the null one past the buffer.This happens only on machine with non-english
(multi-byte) locale as default. Fix is to check the number of bytes required and
truncate the correctly leaving space for the terminating null.
Diffstat (limited to 'src/vm/ilmarshalers.cpp')
-rw-r--r-- | src/vm/ilmarshalers.cpp | 16 |
1 files changed, 7 insertions, 9 deletions
diff --git a/src/vm/ilmarshalers.cpp b/src/vm/ilmarshalers.cpp index ebd8250459..114fbe3ccb 100644 --- a/src/vm/ilmarshalers.cpp +++ b/src/vm/ilmarshalers.cpp @@ -4372,20 +4372,19 @@ FCIMPL3(void, MngdNativeArrayMarshaler::ConvertContentsToNative, MngdNativeArray if (*pArrayRef != NULL) { const OleVariant::Marshaler* pMarshaler = OleVariant::GetMarshalerForVarType(pThis->m_vt, TRUE); - + SIZE_T cElements = (*pArrayRef)->GetNumComponents(); if (pMarshaler == NULL || pMarshaler->ComToOleArray == NULL) { - SIZE_T cElements = (*pArrayRef)->GetNumComponents(); - SIZE_T cbArray = cElements; - if ( (!SafeMulSIZE_T(&cbArray, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT))) || cbArray > MAX_SIZE_FOR_INTEROP) + if ( (!SafeMulSIZE_T(&cElements, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT))) || cElements > MAX_SIZE_FOR_INTEROP) COMPlusThrow(kArgumentException, IDS_EE_STRUCTARRAYTOOLARGE); _ASSERTE(!GetTypeHandleForCVType(OleVariant::GetCVTypeForVarType(pThis->m_vt)).GetMethodTable()->ContainsPointers()); - memcpyNoGCRefs(*pNativeHome, (*pArrayRef)->GetDataPtr(), cbArray); + memcpyNoGCRefs(*pNativeHome, (*pArrayRef)->GetDataPtr(), cElements); } else { - pMarshaler->ComToOleArray(pArrayRef, *pNativeHome, pThis->m_pElementMT, pThis->m_BestFitMap, pThis->m_ThrowOnUnmappableChar, pThis->m_NativeDataValid); + pMarshaler->ComToOleArray(pArrayRef, *pNativeHome, pThis->m_pElementMT, pThis->m_BestFitMap, + pThis->m_ThrowOnUnmappableChar, pThis->m_NativeDataValid, cElements); } } HELPER_METHOD_FRAME_END(); @@ -4437,13 +4436,12 @@ FCIMPL3(void, MngdNativeArrayMarshaler::ConvertContentsToManaged, MngdNativeArra if (pMarshaler == NULL || pMarshaler->OleToComArray == NULL) { SIZE_T cElements = (*pArrayRef)->GetNumComponents(); - SIZE_T cbArray = cElements; - if ( (!SafeMulSIZE_T(&cbArray, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT))) || cbArray > MAX_SIZE_FOR_INTEROP) + if ( (!SafeMulSIZE_T(&cElements, OleVariant::GetElementSizeForVarType(pThis->m_vt, pThis->m_pElementMT))) || cElements > MAX_SIZE_FOR_INTEROP) COMPlusThrow(kArgumentException, IDS_EE_STRUCTARRAYTOOLARGE); // If we are copying variants, strings, etc, we need to use write barrier _ASSERTE(!GetTypeHandleForCVType(OleVariant::GetCVTypeForVarType(pThis->m_vt)).GetMethodTable()->ContainsPointers()); - memcpyNoGCRefs((*pArrayRef)->GetDataPtr(), *pNativeHome, cbArray ); + memcpyNoGCRefs((*pArrayRef)->GetDataPtr(), *pNativeHome, cElements); } else { |