Merge pull request #7149 from bosilca/fix/datatype_overflow
Prevent overflow when dealing with datatype count.
Этот коммит содержится в:
Коммит
1b93a173ab
@ -403,7 +403,7 @@ opal_convertor_create_stack_at_begining( opal_convertor_t* convertor,
|
||||
pStack[1].count = pElems[0].loop.loops;
|
||||
pStack[1].type = OPAL_DATATYPE_LOOP;
|
||||
} else {
|
||||
pStack[1].count = pElems[0].elem.count * pElems[0].elem.blocklen;
|
||||
pStack[1].count = (size_t)pElems[0].elem.count * pElems[0].elem.blocklen;
|
||||
pStack[1].type = pElems[0].elem.common.type;
|
||||
}
|
||||
return OPAL_SUCCESS;
|
||||
|
@ -125,7 +125,7 @@ opal_convertor_raw( opal_convertor_t* pConvertor,
|
||||
if( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
|
||||
const ddt_elem_desc_t* current = &(pElem->elem);
|
||||
|
||||
if( count_desc != (current->count * current->blocklen) ) { /* Not the full element description */
|
||||
if( count_desc != ((size_t)current->count * current->blocklen) ) { /* Not the full element description */
|
||||
if( (do_now = count_desc % current->blocklen) ) {
|
||||
do_now = current->blocklen - do_now; /* how much left in the block */
|
||||
source_base += current->disp;
|
||||
@ -152,7 +152,7 @@ opal_convertor_raw( opal_convertor_t* pConvertor,
|
||||
source_base += current->disp;
|
||||
|
||||
do_now = current->count;
|
||||
if( count_desc != (current->count * current->blocklen) ) {
|
||||
if( count_desc != ((size_t)current->count * current->blocklen) ) {
|
||||
do_now = count_desc / current->blocklen;
|
||||
assert( 0 == (count_desc % current->blocklen) );
|
||||
}
|
||||
|
@ -376,7 +376,7 @@ opal_datatype_create_from_packed_description( void** packed_buffer,
|
||||
* argument, the number of bytes of the gap at the beginning.
|
||||
*/
|
||||
static inline ptrdiff_t
|
||||
opal_datatype_span( const opal_datatype_t* pData, int64_t count,
|
||||
opal_datatype_span( const opal_datatype_t* pData, size_t count,
|
||||
ptrdiff_t* gap)
|
||||
{
|
||||
if (OPAL_UNLIKELY(0 == pData->size) || (0 == count)) {
|
||||
@ -386,7 +386,7 @@ opal_datatype_span( const opal_datatype_t* pData, int64_t count,
|
||||
*gap = pData->true_lb;
|
||||
ptrdiff_t extent = (pData->ub - pData->lb);
|
||||
ptrdiff_t true_extent = (pData->true_ub - pData->true_lb);
|
||||
return true_extent + (count - 1) * extent;
|
||||
return true_extent + extent * (count - 1);
|
||||
}
|
||||
|
||||
#if OPAL_ENABLE_DEBUG
|
||||
|
@ -285,7 +285,7 @@ int32_t opal_datatype_add( opal_datatype_t* pdtBase, const opal_datatype_t* pdtA
|
||||
pLast->elem.common.flags = pdtAdd->flags & ~(OPAL_DATATYPE_FLAG_COMMITTED);
|
||||
pLast->elem.common.type = pdtAdd->id;
|
||||
pLast->elem.disp = disp;
|
||||
pLast->elem.extent = count * extent;
|
||||
pLast->elem.extent = (ptrdiff_t)count * extent;
|
||||
/* assume predefined datatypes without extent, aka. contiguous */
|
||||
pLast->elem.count = 1;
|
||||
pLast->elem.blocklen = count;
|
||||
@ -328,9 +328,18 @@ int32_t opal_datatype_add( opal_datatype_t* pdtBase, const opal_datatype_t* pdtA
|
||||
pLast->elem.count = count;
|
||||
pLast->elem.extent = extent;
|
||||
}
|
||||
} else if( extent == (ptrdiff_t)(pLast->elem.count * pLast->elem.extent) ) {
|
||||
} else if( extent == ((ptrdiff_t)pLast->elem.count * pLast->elem.extent) ) {
|
||||
/* It's just a repetition of the same element, increase the count */
|
||||
pLast->elem.count *= count;
|
||||
/* We need to protect against the case where the multiplication below results in a
|
||||
* number larger than the max uint32_t. In the unlikely situation where that's the case
|
||||
* we should not try to optimize the item further but instead fall back and build a loop
|
||||
* around it.
|
||||
*/
|
||||
uint32_t cnt = pLast->elem.count * count;
|
||||
if( cnt < pLast->elem.count ) {
|
||||
goto build_loop;
|
||||
}
|
||||
pLast->elem.count = cnt; /* we're good, merge the elements */
|
||||
} else {
|
||||
/* No luck here, no optimization can be applied. Fall back to the
|
||||
* normal case where we add a loop around the datatype.
|
||||
|
@ -128,7 +128,7 @@ static inline int32_t _copy_content_same_ddt( const opal_datatype_t* datatype, i
|
||||
DO_DEBUG( opal_output( 0, "_copy_content_same_ddt( %p, %d, dst %p, src %p )\n",
|
||||
(void*)datatype, count, (void*)destination_base, (void*)source_base ); );
|
||||
|
||||
iov_len_local = count * datatype->size;
|
||||
iov_len_local = (size_t)count * datatype->size;
|
||||
|
||||
/* If we have to copy a contiguous datatype then simply
|
||||
* do a MEM_OP.
|
||||
|
@ -98,7 +98,7 @@ int opal_datatype_dump_data_desc( dt_elem_desc_t* pDesc, int nbElems, char* ptr,
|
||||
pDesc->end_loop.items, pDesc->end_loop.first_elem_disp,
|
||||
pDesc->end_loop.size );
|
||||
else
|
||||
index += snprintf( ptr + index, length - index, "count %" PRIsize_t " disp 0x%tx (%td) blen %u extent %td (size %zd)\n",
|
||||
index += snprintf( ptr + index, length - index, "count %u disp 0x%tx (%td) blen %" PRIsize_t " extent %td (size %zd)\n",
|
||||
pDesc->elem.count, pDesc->elem.disp, pDesc->elem.disp, pDesc->elem.blocklen,
|
||||
pDesc->elem.extent, (pDesc->elem.count * pDesc->elem.blocklen * opal_datatype_basicDatatypes[pDesc->elem.common.type]->size) );
|
||||
pDesc++;
|
||||
|
@ -44,7 +44,7 @@ int opal_convertor_create_stack_with_pos_general( opal_convertor_t* pConvertor,
|
||||
int pos_desc; /* actual position in the description of the derived datatype */
|
||||
size_t lastLength = 0;
|
||||
const opal_datatype_t* pData = pConvertor->pDesc;
|
||||
size_t loop_length, *remoteLength, remote_size;
|
||||
size_t loop_length, *remoteLength, remote_size;
|
||||
size_t resting_place = starting_point;
|
||||
dt_elem_desc_t* pElems;
|
||||
size_t count;
|
||||
@ -152,7 +152,7 @@ int opal_convertor_create_stack_with_pos_general( opal_convertor_t* pConvertor,
|
||||
if( OPAL_DATATYPE_LOOP == pElems->elem.common.type ) {
|
||||
remoteLength[pConvertor->stack_pos] += loop_length;
|
||||
PUSH_STACK( pStack, pConvertor->stack_pos, pos_desc, OPAL_DATATYPE_LOOP,
|
||||
pElems->loop.loops, pStack->disp );
|
||||
pElems->loop.loops, pStack->disp );
|
||||
pos_desc++;
|
||||
pElems++;
|
||||
remoteLength[pConvertor->stack_pos] = 0;
|
||||
@ -161,7 +161,7 @@ int opal_convertor_create_stack_with_pos_general( opal_convertor_t* pConvertor,
|
||||
while( pElems->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
|
||||
/* now here we have a basic datatype */
|
||||
const opal_datatype_t* basic_type = BASIC_DDT_FROM_ELEM( (*pElems) );
|
||||
lastLength = pElems->elem.count * basic_type->size;
|
||||
lastLength = (size_t)pElems->elem.count * basic_type->size;
|
||||
if( resting_place < lastLength ) {
|
||||
int32_t cnt = (int32_t)(resting_place / basic_type->size);
|
||||
loop_length += (cnt * basic_type->size);
|
||||
|
@ -69,14 +69,14 @@ ssize_t opal_datatype_get_element_count( const opal_datatype_t* datatype, size_t
|
||||
while( pElems[pos_desc].elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
|
||||
/* now here we have a basic datatype */
|
||||
const opal_datatype_t* basic_type = BASIC_DDT_FROM_ELEM(pElems[pos_desc]);
|
||||
local_size = (pElems[pos_desc].elem.count * pElems[pos_desc].elem.blocklen) * basic_type->size;
|
||||
local_size = ((size_t)pElems[pos_desc].elem.count * pElems[pos_desc].elem.blocklen) * basic_type->size;
|
||||
if( local_size >= iSize ) {
|
||||
local_size = iSize / basic_type->size;
|
||||
nbElems += (int32_t)local_size;
|
||||
iSize -= local_size * basic_type->size;
|
||||
return (iSize == 0 ? nbElems : -1);
|
||||
}
|
||||
nbElems += (pElems[pos_desc].elem.count * pElems[pos_desc].elem.blocklen);
|
||||
nbElems += ((size_t)pElems[pos_desc].elem.count * pElems[pos_desc].elem.blocklen);
|
||||
iSize -= local_size;
|
||||
pos_desc++; /* advance to the next data */
|
||||
}
|
||||
@ -131,7 +131,7 @@ int32_t opal_datatype_set_element_count( const opal_datatype_t* datatype, size_t
|
||||
while( pElems[pos_desc].elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
|
||||
/* now here we have a basic datatype */
|
||||
const opal_datatype_t* basic_type = BASIC_DDT_FROM_ELEM(pElems[pos_desc]);
|
||||
local_length = (pElems[pos_desc].elem.count * pElems[pos_desc].elem.blocklen);
|
||||
local_length = ((size_t)pElems[pos_desc].elem.count * pElems[pos_desc].elem.blocklen);
|
||||
if( local_length >= count ) {
|
||||
*length += count * basic_type->size;
|
||||
return 0;
|
||||
@ -188,10 +188,10 @@ int opal_datatype_compute_ptypes( opal_datatype_t* datatype )
|
||||
}
|
||||
while( pElems[pos_desc].elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
|
||||
/* now here we have a basic datatype */
|
||||
datatype->ptypes[pElems[pos_desc].elem.common.type] += pElems[pos_desc].elem.count * pElems[pos_desc].elem.blocklen;
|
||||
nbElems += pElems[pos_desc].elem.count * pElems[pos_desc].elem.blocklen;
|
||||
datatype->ptypes[pElems[pos_desc].elem.common.type] += (size_t)pElems[pos_desc].elem.count * pElems[pos_desc].elem.blocklen;
|
||||
nbElems += (size_t)pElems[pos_desc].elem.count * pElems[pos_desc].elem.blocklen;
|
||||
|
||||
DUMP( " compute_ptypes-add: type %d count %"PRIsize_t" (total type %"PRIsize_t" total %lld)\n",
|
||||
DUMP( " compute_ptypes-add: type %d count %"PRIsize_t" (total type %u total %lld)\n",
|
||||
pElems[pos_desc].elem.common.type, datatype->ptypes[pElems[pos_desc].elem.common.type],
|
||||
pElems[pos_desc].elem.count, nbElems );
|
||||
pos_desc++; /* advance to the next data */
|
||||
|
@ -156,8 +156,8 @@ typedef struct ddt_elem_id_description ddt_elem_id_description;
|
||||
*/
|
||||
struct ddt_elem_desc {
|
||||
ddt_elem_id_description common; /**< basic data description and flags */
|
||||
uint32_t blocklen; /**< number of elements on each block */
|
||||
size_t count; /**< number of blocks */
|
||||
uint32_t count; /**< number of blocks */
|
||||
size_t blocklen; /**< number of elements on each block */
|
||||
ptrdiff_t extent; /**< extent of each block (in bytes) */
|
||||
ptrdiff_t disp; /**< displacement of the first block */
|
||||
};
|
||||
|
@ -275,7 +275,7 @@ opal_generic_simple_pack_function( opal_convertor_t* pConvertor,
|
||||
iov_len_local = iov[iov_count].iov_len;
|
||||
|
||||
if( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
|
||||
if( (pElem->elem.count * pElem->elem.blocklen) != count_desc ) {
|
||||
if( ((size_t)pElem->elem.count * pElem->elem.blocklen) != count_desc ) {
|
||||
/* we have a partial (less than blocklen) basic datatype */
|
||||
int rc = PACK_PARTIAL_BLOCKLEN( pConvertor, pElem, count_desc,
|
||||
conv_ptr, iov_ptr, iov_len_local );
|
||||
|
@ -47,7 +47,7 @@ pack_partial_blocklen( opal_convertor_t* CONVERTOR,
|
||||
unsigned char* _memory = (*memory) + _elem->disp;
|
||||
unsigned char* _packed = *packed;
|
||||
|
||||
assert( *(COUNT) <= _elem->count * _elem->blocklen);
|
||||
assert( *(COUNT) <= ((size_t)_elem->count * _elem->blocklen) );
|
||||
|
||||
/**
|
||||
* First check if we already did something on this element ? The COUNT is the number
|
||||
@ -98,7 +98,7 @@ pack_predefined_data( opal_convertor_t* CONVERTOR,
|
||||
unsigned char* _packed = *packed;
|
||||
|
||||
assert( 0 == (cando_count % _elem->blocklen) ); /* no partials here */
|
||||
assert( *(COUNT) <= _elem->count * _elem->blocklen);
|
||||
assert( *(COUNT) <= ((size_t)_elem->count * _elem->blocklen) );
|
||||
|
||||
if( (blocklen_bytes * cando_count) > *(SPACE) )
|
||||
cando_count = (*SPACE) / blocklen_bytes;
|
||||
|
@ -76,12 +76,12 @@ position_predefined_data( opal_convertor_t* CONVERTOR,
|
||||
size_t* SPACE )
|
||||
{
|
||||
const ddt_elem_desc_t* _elem = &((ELEM)->elem);
|
||||
size_t total_count = _elem->count * _elem->blocklen;
|
||||
size_t total_count = (size_t)_elem->count * _elem->blocklen;
|
||||
size_t cando_count = (*SPACE) / opal_datatype_basicDatatypes[_elem->common.type]->size;
|
||||
size_t do_now, do_now_bytes = opal_datatype_basicDatatypes[_elem->common.type]->size;
|
||||
unsigned char* _memory = (*POINTER) + _elem->disp;
|
||||
|
||||
assert( *(COUNT) <= _elem->count * _elem->blocklen);
|
||||
assert( *(COUNT) <= ((size_t)_elem->count * _elem->blocklen) );
|
||||
|
||||
if( cando_count > *(COUNT) )
|
||||
cando_count = *(COUNT);
|
||||
|
@ -282,7 +282,7 @@ opal_generic_simple_unpack_function( opal_convertor_t* pConvertor,
|
||||
for( iov_count = 0; iov_count < (*out_size); iov_count++ ) {
|
||||
iov_ptr = (unsigned char *) iov[iov_count].iov_base;
|
||||
iov_len_local = iov[iov_count].iov_len;
|
||||
|
||||
|
||||
if( 0 != pConvertor->partial_length ) {
|
||||
size_t element_length = opal_datatype_basicDatatypes[pElem->elem.common.type]->size;
|
||||
size_t missing_length = element_length - pConvertor->partial_length;
|
||||
@ -304,7 +304,7 @@ opal_generic_simple_unpack_function( opal_convertor_t* pConvertor,
|
||||
pConvertor->partial_length = 0; /* nothing more inside */
|
||||
}
|
||||
if( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
|
||||
if( (pElem->elem.count * pElem->elem.blocklen) != count_desc ) {
|
||||
if( ((size_t)pElem->elem.count * pElem->elem.blocklen) != count_desc ) {
|
||||
/* we have a partial (less than blocklen) basic datatype */
|
||||
int rc = UNPACK_PARTIAL_BLOCKLEN( pConvertor, pElem, count_desc,
|
||||
iov_ptr, conv_ptr, iov_len_local );
|
||||
@ -317,7 +317,7 @@ opal_generic_simple_unpack_function( opal_convertor_t* pConvertor,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
while( 1 ) {
|
||||
while( pElem->elem.common.flags & OPAL_DATATYPE_FLAG_DATA ) {
|
||||
/* we have a basic datatype (working on full blocks) */
|
||||
|
@ -47,7 +47,7 @@ unpack_partial_blocklen( opal_convertor_t* CONVERTOR,
|
||||
unsigned char* _memory = (*memory) + _elem->disp;
|
||||
unsigned char* _packed = *packed;
|
||||
|
||||
assert( *(COUNT) <= (_elem->count * _elem->blocklen));
|
||||
assert( *(COUNT) <= ((size_t)(_elem->count * _elem->blocklen)) );
|
||||
|
||||
/**
|
||||
* First check if we already did something on this element ? The COUNT is the number
|
||||
@ -95,14 +95,14 @@ unpack_predefined_data( opal_convertor_t* CONVERTOR,
|
||||
unsigned char* _packed = *packed;
|
||||
|
||||
assert( 0 == (cando_count % _elem->blocklen) ); /* no partials here */
|
||||
assert( *(COUNT) <= (_elem->count * _elem->blocklen));
|
||||
assert( *(COUNT) <= ((size_t)_elem->count * _elem->blocklen) );
|
||||
|
||||
if( (blocklen_bytes * cando_count) > *(SPACE) )
|
||||
cando_count = (*SPACE) / blocklen_bytes;
|
||||
|
||||
/* premptively update the number of COUNT we will return. */
|
||||
*(COUNT) -= cando_count;
|
||||
|
||||
|
||||
if( 1 == _elem->blocklen ) { /* Do as many full blocklen as possible */
|
||||
for(; cando_count > 0; cando_count--) {
|
||||
OPAL_DATATYPE_SAFEGUARD_POINTER( _memory, blocklen_bytes, (CONVERTOR)->pBaseBuf,
|
||||
|
Загрузка…
Ссылка в новой задаче
Block a user