diff --git a/nifti2/nifti2_io.c b/nifti2/nifti2_io.c index 43a26f71..12cd59ab 100644 --- a/nifti2/nifti2_io.c +++ b/nifti2/nifti2_io.c @@ -4807,8 +4807,14 @@ nifti_image* nifti_convert_n1hdr2nim(nifti_1_header nhdr, const char * fname) nim->nv = nim->dim[6] = nhdr.dim[6]; nim->nw = nim->dim[7] = nhdr.dim[7]; - for( ii=1, nim->nvox=1; ii <= nhdr.dim[0]; ii++ ) + /* the product of the dimensions becomes an allocation size, so refuse + the header rather than let it wrap */ + for( ii=1, nim->nvox=1; ii <= nhdr.dim[0]; ii++ ){ + if( nhdr.dim[ii] > 0 && nim->nvox > INT64_MAX / nhdr.dim[ii] ){ + free(nim); ERREX("dim[] overflows the voxel count"); + } nim->nvox *= nhdr.dim[ii]; + } /**- set the type of data in voxels and how many bytes per voxel */ @@ -4817,6 +4823,11 @@ nifti_image* nifti_convert_n1hdr2nim(nifti_1_header nhdr, const char * fname) nifti_datatype_sizes( nim->datatype , &(nim->nbyper) , &(nim->swapsize) ) ; if( nim->nbyper == 0 ){ free(nim); ERREX("bad datatype"); } + /* nifti_get_volsize() multiplies these two */ + if( nim->nvox > INT64_MAX / nim->nbyper ){ + free(nim); ERREX("dim[] and datatype overflow the volume size"); + } + /**- set the grid spacings */ nim->dx = nim->pixdim[1] = nhdr.pixdim[1] ; @@ -5077,8 +5088,14 @@ nifti_image* nifti_convert_n2hdr2nim(nifti_2_header nhdr, const char * fname) nim->nv = nim->dim[6] = nhdr.dim[6]; nim->nw = nim->dim[7] = nhdr.dim[7]; - for( ii=1, nim->nvox=1; ii <= nhdr.dim[0]; ii++ ) + /* the product of the dimensions becomes an allocation size, so refuse + the header rather than let it wrap */ + for( ii=1, nim->nvox=1; ii <= nhdr.dim[0]; ii++ ){ + if( nhdr.dim[ii] > 0 && nim->nvox > INT64_MAX / nhdr.dim[ii] ){ + free(nim); ERREX("dim[] overflows the voxel count"); + } nim->nvox *= nhdr.dim[ii]; + } /**- set the type of data in voxels and how many bytes per voxel */ @@ -5087,6 +5104,11 @@ nifti_image* nifti_convert_n2hdr2nim(nifti_2_header nhdr, const char * fname) nifti_datatype_sizes( nim->datatype , &(nim->nbyper) , &(nim->swapsize) ) ; if( nim->nbyper == 0 ){ free(nim); ERREX("bad datatype"); } + /* nifti_get_volsize() multiplies these two */ + if( nim->nvox > INT64_MAX / nim->nbyper ){ + free(nim); ERREX("dim[] and datatype overflow the volume size"); + } + /**- set the grid spacings */ nim->dx = nim->pixdim[1] = nhdr.pixdim[1] ; diff --git a/niftilib/nifti1_io.c b/niftilib/nifti1_io.c index 0580c629..f25d3df8 100644 --- a/niftilib/nifti1_io.c +++ b/niftilib/nifti1_io.c @@ -3766,8 +3766,15 @@ nifti_image* nifti_convert_nhdr2nim(struct nifti_1_header nhdr, nim->nv = nim->dim[6] = nhdr.dim[6]; nim->nw = nim->dim[7] = nhdr.dim[7]; - for( ii=1, nim->nvox=1; ii <= nhdr.dim[0]; ii++ ) + /* the product of the dimensions becomes an allocation size, so refuse + the header rather than let it wrap. nvox is a size_t here, where the + NIFTI-2 library uses int64_t, so the bound is SIZE_MAX. */ + for( ii=1, nim->nvox=1; ii <= nhdr.dim[0]; ii++ ){ + if( nhdr.dim[ii] > 0 && nim->nvox > SIZE_MAX / (size_t)nhdr.dim[ii] ){ + free(nim); ERREX("dim[] overflows the voxel count"); + } nim->nvox *= nhdr.dim[ii]; + } /**- set the type of data in voxels and how many bytes per voxel */ @@ -3776,6 +3783,11 @@ nifti_image* nifti_convert_nhdr2nim(struct nifti_1_header nhdr, nifti_datatype_sizes( nim->datatype , &(nim->nbyper) , &(nim->swapsize) ) ; if( nim->nbyper == 0 ){ free(nim); ERREX("bad datatype"); } + /* nifti_get_volsize() multiplies these two */ + if( nim->nvox > SIZE_MAX / (size_t)nim->nbyper ){ + free(nim); ERREX("dim[] and datatype overflow the volume size"); + } + /**- set the grid spacings */ nim->dx = nim->pixdim[1] = nhdr.pixdim[1] ;