Skip to content

Commit

Permalink
Fix illegal memory access
Browse files Browse the repository at this point in the history
  • Loading branch information
tbeu committed Jan 3, 2021
1 parent 0f7f27c commit 054b285
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 41 deletions.
5 changes: 3 additions & 2 deletions src/mat.c
Original file line number Diff line number Diff line change
Expand Up @@ -310,16 +310,17 @@ int Add(size_t* res, size_t a, size_t b)
* @param count Element count
* @param fp File pointer
* @param[out] bytesread Number of bytes read from the file
* @param acceptEOF Flag for valid read beyond EOF
* @retval 0 on success
*/
int
Read(void* buf, size_t size, size_t count, FILE* fp, size_t* bytesread) {
Read(void* buf, size_t size, size_t count, FILE* fp, size_t* bytesread, int acceptEOF) {
const size_t readcount = fread(buf, size, count, fp);
int err = readcount != count;
if ( NULL != bytesread ) {
*bytesread += readcount*size;
}
if ( err && feof(fp) && 0 == readcount) {
if ( acceptEOF && err && feof(fp) && 0 == readcount) {
err = MATIO_E_NO_ERROR;
}
if ( err ) {
Expand Down
12 changes: 6 additions & 6 deletions src/mat4.c
Original file line number Diff line number Diff line change
Expand Up @@ -922,7 +922,7 @@ Mat_VarReadNextInfo4(mat_t *mat)

{
size_t nbytes = 0;
int err = Read(&tmp, sizeof(mat_int32_t), 1, (FILE*)mat->fp, &nbytes);
int err = Read(&tmp, sizeof(mat_int32_t), 1, (FILE*)mat->fp, &nbytes, READ_ACCEPT_EOF);
if ( err || 0 == nbytes )
return NULL;
}
Expand Down Expand Up @@ -1011,31 +1011,31 @@ Mat_VarReadNextInfo4(mat_t *mat)
Mat_VarFree(matvar);
return NULL;
}
if ( 0 != Read(&tmp, sizeof(int), 1, (FILE*)mat->fp, NULL) ) {
if ( 0 != Read(&tmp, sizeof(int), 1, (FILE*)mat->fp, NULL, READ_STRICT) ) {
Mat_VarFree(matvar);
return NULL;
}
if ( mat->byteswap )
Mat_int32Swap(&tmp);
matvar->dims[0] = tmp;

if ( 0 != Read(&tmp, sizeof(int), 1, (FILE*)mat->fp, NULL) ) {
if ( 0 != Read(&tmp, sizeof(int), 1, (FILE*)mat->fp, NULL, READ_STRICT) ) {
Mat_VarFree(matvar);
return NULL;
}
if ( mat->byteswap )
Mat_int32Swap(&tmp);
matvar->dims[1] = tmp;

if ( 0 != Read(&(matvar->isComplex), sizeof(int), 1, (FILE*)mat->fp, NULL) ) {
if ( 0 != Read(&(matvar->isComplex), sizeof(int), 1, (FILE*)mat->fp, NULL, READ_STRICT) ) {
Mat_VarFree(matvar);
return NULL;
}
if ( matvar->isComplex && MAT_C_CHAR == matvar->class_type ) {
Mat_VarFree(matvar);
return NULL;
}
if ( 0 != Read(&tmp, sizeof(int), 1, (FILE*)mat->fp, NULL) ) {
if ( 0 != Read(&tmp, sizeof(int), 1, (FILE*)mat->fp, NULL, READ_STRICT) ) {
Mat_VarFree(matvar);
return NULL;
}
Expand All @@ -1051,7 +1051,7 @@ Mat_VarReadNextInfo4(mat_t *mat)
Mat_VarFree(matvar);
return NULL;
}
if ( 0 != Read(matvar->name, sizeof(char), tmp, (FILE*)mat->fp, NULL) ) {
if ( 0 != Read(matvar->name, sizeof(char), tmp, (FILE*)mat->fp, NULL, READ_STRICT) ) {
Mat_VarFree(matvar);
return NULL;
} else {
Expand Down
64 changes: 32 additions & 32 deletions src/mat5.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,7 @@ ReadSparse(mat_t *mat, matvar_t *matvar, mat_uint32_t *n, mat_uint32_t **v)
}
#endif
} else {
if ( 0 != Read(tag, 4, 1, (FILE*)mat->fp, &bytesread) ) {
if ( 0 != Read(tag, 4, 1, (FILE*)mat->fp, &bytesread, READ_STRICT) ) {
return bytesread;
}
if ( mat->byteswap )
Expand All @@ -513,7 +513,7 @@ ReadSparse(mat_t *mat, matvar_t *matvar, mat_uint32_t *n, mat_uint32_t **v)
N = (tag[0] & 0xffff0000) >> 16;
} else {
data_in_tag = 0;
if ( 0 != Read(&N, 4, 1, (FILE*)mat->fp, &bytesread) ) {
if ( 0 != Read(&N, 4, 1, (FILE*)mat->fp, &bytesread, READ_STRICT) ) {
return bytesread;
}
if ( mat->byteswap )
Expand Down Expand Up @@ -1235,7 +1235,7 @@ ReadNextCell( mat_t *mat, matvar_t *matvar )
}

/* Read variable tag for cell */
err = Read(buf, 4, 2, (FILE*)mat->fp, &nbytes);
err = Read(buf, 4, 2, (FILE*)mat->fp, &nbytes, READ_STRICT);

/* Empty cells at the end of a file may cause an EOF */
if ( 0 == err && 0 == nbytes )
Expand Down Expand Up @@ -1265,7 +1265,7 @@ ReadNextCell( mat_t *mat, matvar_t *matvar )
}

/* Read array flags and the dimensions tag */
err = Read(buf, 4, 6, (FILE*)mat->fp, &bytesread);
err = Read(buf, 4, 6, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
Mat_VarFree(cells[i]);
cells[i] = NULL;
Expand Down Expand Up @@ -1303,7 +1303,7 @@ ReadNextCell( mat_t *mat, matvar_t *matvar )
break;
}
/* Variable name tag */
if ( 0 != Read(buf, 1, 8, (FILE*)mat->fp, &bytesread) ) {
if ( 0 != Read(buf, 1, 8, (FILE*)mat->fp, &bytesread, READ_STRICT) ) {
Mat_VarFree(cells[i]);
cells[i] = NULL;
break;
Expand Down Expand Up @@ -1645,7 +1645,7 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar )
mat_uint32_t buf[6] = {0,};
mat_uint32_t array_flags, len;

err = Read(buf, 4, 2, (FILE*)mat->fp, &bytesread);
err = Read(buf, 4, 2, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
return bytesread;
}
Expand All @@ -1661,7 +1661,7 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar )
}

/* Field name tag */
err = Read(buf, 4, 2, (FILE*)mat->fp, &bytesread);
err = Read(buf, 4, 2, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
return bytesread;
}
Expand All @@ -1677,7 +1677,7 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar )
if ( nfields ) {
char *ptr = (char*)malloc(nfields*fieldname_size);
if ( NULL != ptr ) {
err = Read(ptr, 1, nfields*fieldname_size, (FILE*)mat->fp, &bytesread);
err = Read(ptr, 1, nfields*fieldname_size, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( 0 == err ) {
SetFieldNames(matvar, ptr, nfields, fieldname_size);
} else {
Expand Down Expand Up @@ -1738,7 +1738,7 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar )
}

/* Read variable tag for struct field */
err = Read(buf, 4, 2, (FILE*)mat->fp, &bytesread);
err = Read(buf, 4, 2, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
Mat_VarFree(fields[i]);
fields[i] = NULL;
Expand All @@ -1763,7 +1763,7 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar )
}

/* Read array flags and the dimensions tag */
err = Read(buf, 4, 6, (FILE*)mat->fp, &bytesread);
err = Read(buf, 4, 6, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
Mat_VarFree(fields[i]);
fields[i] = NULL;
Expand Down Expand Up @@ -1803,7 +1803,7 @@ ReadNextStructField( mat_t *mat, matvar_t *matvar )
}
}
/* Variable name tag */
err = Read(buf, 1, 8, (FILE*)mat->fp, &bytesread);
err = Read(buf, 1, 8, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
Mat_VarFree(fields[i]);
fields[i] = NULL;
Expand Down Expand Up @@ -1903,7 +1903,7 @@ ReadRankDims(mat_t *mat, matvar_t *matvar, enum matio_types data_type, mat_uint3
mat_uint32_t buf;

for ( i = 0; i < matvar->rank; i++) {
err = Read(&buf, sizeof(mat_uint32_t), 1, (FILE*)mat->fp, read_bytes);
err = Read(&buf, sizeof(mat_uint32_t), 1, (FILE*)mat->fp, read_bytes, READ_STRICT);
if ( MATIO_E_NO_ERROR == err ) {
if ( mat->byteswap ) {
matvar->dims[i] = Mat_uint32Swap(&buf);
Expand All @@ -1919,7 +1919,7 @@ ReadRankDims(mat_t *mat, matvar_t *matvar, enum matio_types data_type, mat_uint3
}

if ( matvar->rank % 2 != 0 ) {
err = Read(&buf, sizeof(mat_uint32_t), 1, (FILE*)mat->fp, read_bytes);
err = Read(&buf, sizeof(mat_uint32_t), 1, (FILE*)mat->fp, read_bytes, READ_STRICT);
if ( err ) {
free(matvar->dims);
matvar->dims = NULL;
Expand Down Expand Up @@ -2897,7 +2897,7 @@ Mat_VarReadNumeric5(mat_t *mat,matvar_t *matvar,void *data,size_t N)
}
#endif
} else {
err = Read(tag, 4, 1, (FILE*)mat->fp, NULL);
err = Read(tag, 4, 1, (FILE*)mat->fp, NULL, READ_STRICT);
if ( err ) {
return err;
}
Expand All @@ -2909,7 +2909,7 @@ Mat_VarReadNumeric5(mat_t *mat,matvar_t *matvar,void *data,size_t N)
nBytes = (tag[0] & 0xffff0000) >> 16;
} else {
data_in_tag = 0;
err = Read(tag+1, 4, 1, (FILE*)mat->fp, NULL);
err = Read(tag+1, 4, 1, (FILE*)mat->fp, NULL, READ_STRICT);
if ( err ) {
return err;
}
Expand Down Expand Up @@ -3171,7 +3171,7 @@ Mat_VarRead5(mat_t *mat, matvar_t *matvar)
matvar->data_size = Mat_SizeOf(matvar->data_type);
matvar->nbytes = nBytes;
} else {
err = Read(tag, 4, 1, (FILE*)mat->fp, &bytesread);
err = Read(tag, 4, 1, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
break;
}
Expand All @@ -3183,7 +3183,7 @@ Mat_VarRead5(mat_t *mat, matvar_t *matvar)
/* nBytes = (tag[0] & 0xffff0000) >> 16; */
} else {
data_in_tag = 0;
err = Read(tag+1, 4, 1, (FILE*)mat->fp, &bytesread);
err = Read(tag+1, 4, 1, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
break;
}
Expand Down Expand Up @@ -3328,7 +3328,7 @@ Mat_VarRead5(mat_t *mat, matvar_t *matvar)
}
#endif
} else {
err = Read(tag, 4, 1, (FILE*)mat->fp, &bytesread);
err = Read(tag, 4, 1, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
break;
}
Expand All @@ -3340,7 +3340,7 @@ Mat_VarRead5(mat_t *mat, matvar_t *matvar)
N = (tag[0] & 0xffff0000) >> 16;
} else {
data_in_tag = 0;
err = Read(&N, 4, 1, (FILE*)mat->fp, &bytesread);
err = Read(&N, 4, 1, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
break;
}
Expand Down Expand Up @@ -3440,7 +3440,7 @@ Mat_VarRead5(mat_t *mat, matvar_t *matvar)
(void)fseek((FILE*)mat->fp,8-(nBytes % 8),SEEK_CUR);

/* Complex Data Tag */
err = Read(tag, 4, 1, (FILE*)mat->fp, &bytesread);
err = Read(tag, 4, 1, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
break;
}
Expand All @@ -3452,7 +3452,7 @@ Mat_VarRead5(mat_t *mat, matvar_t *matvar)
nBytes = (tag[0] & 0xffff0000) >> 16;
} else {
data_in_tag = 0;
err = Read(tag+1, 4, 1, (FILE*)mat->fp, &bytesread);
err = Read(tag+1, 4, 1, (FILE*)mat->fp, &bytesread, READ_STRICT);
if ( err ) {
break;
}
Expand Down Expand Up @@ -4476,7 +4476,7 @@ Mat_VarReadData5(mat_t *mat,matvar_t *matvar,void *data,

(void)fseek((FILE*)mat->fp,matvar->internal->datapos,SEEK_SET);
if ( matvar->compression == MAT_COMPRESSION_NONE ) {
err = Read(tag, 4, 2, (FILE*)mat->fp, NULL);
err = Read(tag, 4, 2, (FILE*)mat->fp, NULL, READ_STRICT);
if ( err ) {
return err;
}
Expand Down Expand Up @@ -4558,7 +4558,7 @@ Mat_VarReadData5(mat_t *mat,matvar_t *matvar,void *data,
ReadDataSlab2(mat,complex_data->Re,matvar->class_type,
matvar->data_type,matvar->dims,start,stride,edge);
(void)fseek((FILE*)mat->fp,matvar->internal->datapos+real_bytes,SEEK_SET);
err = Read(tag, 4, 2, (FILE*)mat->fp, NULL);
err = Read(tag, 4, 2, (FILE*)mat->fp, NULL, READ_STRICT);
if ( err ) {
return err;
}
Expand Down Expand Up @@ -4628,7 +4628,7 @@ Mat_VarReadData5(mat_t *mat,matvar_t *matvar,void *data,
start,stride,edge);

(void)fseek((FILE*)mat->fp,matvar->internal->datapos+real_bytes,SEEK_SET);
err = Read(tag, 4, 2, (FILE*)mat->fp, NULL);
err = Read(tag, 4, 2, (FILE*)mat->fp, NULL, READ_STRICT);
if ( err ) {
return err;
}
Expand Down Expand Up @@ -4725,7 +4725,7 @@ Mat_VarReadDataLinear5(mat_t *mat,matvar_t *matvar,void *data,int start,
return -1;
(void)fseek((FILE*)mat->fp,matvar->internal->datapos,SEEK_SET);
if ( matvar->compression == MAT_COMPRESSION_NONE ) {
err = Read(tag, 4, 2, (FILE*)mat->fp, NULL);
err = Read(tag, 4, 2, (FILE*)mat->fp, NULL, READ_STRICT);
if ( err ) {
return err;
}
Expand Down Expand Up @@ -4808,7 +4808,7 @@ Mat_VarReadDataLinear5(mat_t *mat,matvar_t *matvar,void *data,int start,
ReadDataSlab1(mat,complex_data->Re,matvar->class_type,
matvar->data_type,start,stride,edge);
(void)fseek((FILE*)mat->fp,matvar->internal->datapos+real_bytes,SEEK_SET);
err = Read(tag, 4, 2, (FILE*)mat->fp, NULL);
err = Read(tag, 4, 2, (FILE*)mat->fp, NULL, READ_STRICT);
if ( err ) {
return err;
}
Expand Down Expand Up @@ -5161,11 +5161,11 @@ Mat_VarReadNextInfo5( mat_t *mat )
}
{
size_t nbytes = 0;
err = Read(&data_type, sizeof(mat_uint32_t), 1, (FILE*)mat->fp, &nbytes);
err = Read(&data_type, sizeof(mat_uint32_t), 1, (FILE*)mat->fp, &nbytes, READ_ACCEPT_EOF);
if ( err || 0 == nbytes )
return NULL;
}
err = Read(&nBytes, sizeof(mat_uint32_t), 1, (FILE*)mat->fp, NULL);
err = Read(&nBytes, sizeof(mat_uint32_t), 1, (FILE*)mat->fp, NULL, READ_STRICT);
if ( err )
return NULL;
if ( mat->byteswap ) {
Expand Down Expand Up @@ -5373,7 +5373,7 @@ Mat_VarReadNextInfo5( mat_t *mat )
mat_uint32_t buf[6];

/* Read array flags and the dimensions tag */
err = Read(buf, 4, 6, (FILE*)mat->fp, NULL);
err = Read(buf, 4, 6, (FILE*)mat->fp, NULL, READ_STRICT);
if ( err ) {
(void)fseek((FILE*)mat->fp, fpos, SEEK_SET);
break;
Expand Down Expand Up @@ -5409,15 +5409,15 @@ Mat_VarReadNextInfo5( mat_t *mat )
{
size_t nbytes = 0;
err = ReadRankDims(mat, matvar, (enum matio_types)buf[4], buf[5], &nbytes);
if ( 0 == nbytes && 0 < matvar->rank ) {
if ( err ) {
Mat_VarFree(matvar);
matvar = NULL;
(void)fseek((FILE*)mat->fp, fpos, SEEK_SET);
break;
}
}
/* Variable name tag */
err = Read(buf, 4, 2, (FILE*)mat->fp, NULL);
err = Read(buf, 4, 2, (FILE*)mat->fp, NULL, READ_STRICT);
if ( err ) {
Mat_VarFree(matvar);
matvar = NULL;
Expand Down Expand Up @@ -5445,7 +5445,7 @@ Mat_VarReadNextInfo5( mat_t *mat )
}
matvar->name = (char*)malloc(len_pad + 1);
if ( NULL != matvar->name ) {
err = Read(matvar->name, 1, len_pad, (FILE*)mat->fp, NULL);
err = Read(matvar->name, 1, len_pad, (FILE*)mat->fp, NULL, READ_STRICT);
if ( MATIO_E_NO_ERROR == err ) {
matvar->name[len] = '\0';
} else {
Expand Down
5 changes: 4 additions & 1 deletion src/matio_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@
#define _CAT(X, Y) X ## Y
#define CAT(X, Y) _CAT(X, Y)

#define READ_STRICT (0)
#define READ_ACCEPT_EOF (1)

/** @if mat_devman
* @brief Matlab MAT File information
*
Expand Down Expand Up @@ -226,7 +229,7 @@ EXTERN enum matio_types ClassType2DataType(enum matio_classes class_type);
EXTERN int Add(size_t* res, size_t a, size_t b);
EXTERN int Mul(size_t* res, size_t a, size_t b);
EXTERN int Mat_MulDims(const matvar_t *matvar, size_t* nelems);
EXTERN int Read(void* buf, size_t size, size_t count, FILE* fp, size_t* bytesread);
EXTERN int Read(void* buf, size_t size, size_t count, FILE* fp, size_t* bytesread, int checkEOF);

/* io.c */
#if defined(_WIN32) && defined(_MSC_VER)
Expand Down

0 comments on commit 054b285

Please sign in to comment.