1
1

Merge pull request #7149 from bosilca/fix/datatype_overflow

Prevent overflow when dealing with datatype count.
Этот коммит содержится в:
bosilca 2020-01-07 14:13:32 -05:00 коммит произвёл GitHub
родитель 9caf43a9c2 3de636dc6f
Коммит 1b93a173ab
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
14 изменённых файлов: 41 добавлений и 32 удалений

Просмотреть файл

@ -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,