@@ -192,9 +192,15 @@ exif_data_load_data_entry (ExifData *data, ExifEntry *entry,
192192 doff = offset + 8 ;
193193
194194 /* Sanity checks */
195- if (( doff + s < doff ) || ( doff + s < s ) || ( doff + s > size ) ) {
195+ if (doff >= size ) {
196196 exif_log (data -> priv -> log , EXIF_LOG_CODE_DEBUG , "ExifData" ,
197- "Tag data past end of buffer (%u > %u)" , doff + s , size );
197+ "Tag starts past end of buffer (%u > %u)" , doff , size );
198+ return 0 ;
199+ }
200+
201+ if (s > size - doff ) {
202+ exif_log (data -> priv -> log , EXIF_LOG_CODE_DEBUG , "ExifData" ,
203+ "Tag data goes past end of buffer (%u > %u)" , doff + s , size );
198204 return 0 ;
199205 }
200206
@@ -315,13 +321,14 @@ exif_data_load_data_thumbnail (ExifData *data, const unsigned char *d,
315321 unsigned int ds , ExifLong o , ExifLong s )
316322{
317323 /* Sanity checks */
318- if ((o + s < o ) || (o + s < s ) || (o + s > ds ) || (o > ds )) {
319- exif_log (data -> priv -> log , EXIF_LOG_CODE_DEBUG , "ExifData" ,
320- "Bogus thumbnail offset (%u) or size (%u)." ,
321- o , s );
324+ if (o >= ds ) {
325+ exif_log (data -> priv -> log , EXIF_LOG_CODE_DEBUG , "ExifData" , "Bogus thumbnail offset (%u)." , o );
326+ return ;
327+ }
328+ if (s > ds - o ) {
329+ exif_log (data -> priv -> log , EXIF_LOG_CODE_DEBUG , "ExifData" , "Bogus thumbnail size (%u), max would be %u." , s , ds - o );
322330 return ;
323331 }
324-
325332 if (data -> data )
326333 exif_mem_free (data -> priv -> mem , data -> data );
327334 if (!(data -> data = exif_data_alloc (data , s ))) {
@@ -947,7 +954,7 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
947954 exif_log (data -> priv -> log , EXIF_LOG_CODE_DEBUG , "ExifData" ,
948955 "IFD 0 at %i." , (int ) offset );
949956
950- /* Sanity check the offset, being careful about overflow */
957+ /* ds is restricted to 16 bit above, so offset is restricted too, and offset+8 should not overflow. */
951958 if (offset > ds || offset + 6 + 2 > ds )
952959 return ;
953960
@@ -956,6 +963,7 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
956963
957964 /* IFD 1 offset */
958965 n = exif_get_short (d + 6 + offset , data -> priv -> order );
966+ /* offset < 2<<16, n is 16 bit at most, so this op will not overflow */
959967 if (offset + 6 + 2 + 12 * n + 4 > ds )
960968 return ;
961969
@@ -964,8 +972,8 @@ exif_data_load_data (ExifData *data, const unsigned char *d_orig,
964972 exif_log (data -> priv -> log , EXIF_LOG_CODE_DEBUG , "ExifData" ,
965973 "IFD 1 at %i." , (int ) offset );
966974
967- /* Sanity check. */
968- if (offset > ds || offset + 6 > ds ) {
975+ /* Sanity check. ds is ensured to be above 6 above, offset is 16bit */
976+ if (offset > ds - 6 ) {
969977 exif_log (data -> priv -> log , EXIF_LOG_CODE_CORRUPT_DATA ,
970978 "ExifData" , "Bogus offset of IFD1." );
971979 } else {
0 commit comments