Skip to content

Commit

Permalink
Validate some sizes avifParseCondensedImageBox
Browse files Browse the repository at this point in the history
avifROStreamReadVarInt() may read a uint32_t value as large as
UINT32_MAX. Check the uint32_t variables before incrementing them.

Declare `offset` as uint64_t instead of size_t, because it is assigned
to uint64_t struct members.
  • Loading branch information
wantehchang committed Sep 27, 2023
1 parent fc592f0 commit 57dd2a9
Showing 1 changed file with 15 additions and 8 deletions.
23 changes: 15 additions & 8 deletions src/read.c
Original file line number Diff line number Diff line change
Expand Up @@ -3296,9 +3296,11 @@ static avifResult avifParseCondensedImageBox(avifMeta * meta, uint64_t rawOffset
AVIF_CHECKERR(version == 0, AVIF_RESULT_NOT_IMPLEMENTED);

uint32_t width, height;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &width), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) width_minus_one;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &height), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) height_minus_one;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &width), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) width_minus_one;
AVIF_CHECKERR(width != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++width;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &height), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) height_minus_one;
AVIF_CHECKERR(height != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++height;

uint32_t isFloat;
Expand Down Expand Up @@ -3326,7 +3328,8 @@ static avifResult avifParseCondensedImageBox(avifMeta * meta, uint64_t rawOffset
colorPrimaries = AVIF_COLOR_PRIMARIES_UNSPECIFIED;
transferCharacteristics = AVIF_TRANSFER_CHARACTERISTICS_UNSPECIFIED;
AVIF_CHECKERR(avifROStreamReadBits(&s, &matrixCoefficients, 8), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(8) matrix_coefficients;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &iccDataSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) icc_data_size;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &iccDataSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) icc_data_size_minus_one;
AVIF_CHECKERR(iccDataSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++iccDataSize;
} else if (colorType == AVIF_CONI_COLOR_TYPE_SRGB) {
// sRGB
Expand All @@ -3351,7 +3354,8 @@ static avifResult avifParseCondensedImageBox(avifMeta * meta, uint64_t rawOffset
uint32_t colorItemCodecConfigSize, colorItemDataSize;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &colorItemCodecConfigSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) main_item_codec_config_size;
AVIF_CHECKERR(colorItemCodecConfigSize == 4, AVIF_RESULT_NOT_IMPLEMENTED);
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &colorItemDataSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) main_item_data_size;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &colorItemDataSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) main_item_data_size_minus_one;
AVIF_CHECKERR(colorItemDataSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++colorItemDataSize;

uint32_t hasAlpha;
Expand All @@ -3370,17 +3374,20 @@ static avifResult avifParseCondensedImageBox(avifMeta * meta, uint64_t rawOffset
uint32_t extendedMetaSize = 0, exifSize = 0, xmpSize = 0;
AVIF_CHECKERR(avifROStreamReadBits(&s, &hasExtendedMeta, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) has_extended_meta;
if (hasExtendedMeta) {
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &extendedMetaSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) extended_meta_size;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &extendedMetaSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) extended_meta_size_minus_one;
AVIF_CHECKERR(extendedMetaSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++extendedMetaSize;
}
AVIF_CHECKERR(avifROStreamReadBits(&s, &hasExif, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) has_exif;
if (hasExif) {
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &exifSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) exif_data_size;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &exifSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) exif_data_size_minus_one;
AVIF_CHECKERR(exifSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++exifSize;
}
AVIF_CHECKERR(avifROStreamReadBits(&s, &hasXMP, 1), AVIF_RESULT_BMFF_PARSE_FAILED); // unsigned int(1) has_xmp;
if (hasXMP) {
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &xmpSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) xmp_data_size;
AVIF_CHECKERR(avifROStreamReadVarInt(&s, &xmpSize), AVIF_RESULT_BMFF_PARSE_FAILED); // varint(32) xmp_data_size_minus_one;
AVIF_CHECKERR(xmpSize != UINT32_MAX, AVIF_RESULT_BMFF_PARSE_FAILED);
++xmpSize;
}

Expand Down Expand Up @@ -3409,7 +3416,7 @@ static avifResult avifParseCondensedImageBox(avifMeta * meta, uint64_t rawOffset
// Store and update the offset for the following item extents and properties.
// The extendedMeta field is parsed after creating the items defined by the CondensedImageBox
// so the stream s cannot be used for keeping track of the position.
size_t offset = (size_t)rawOffset + avifROStreamOffset(&s) + (size_t)extendedMetaSize;
uint64_t offset = rawOffset + avifROStreamOffset(&s) + extendedMetaSize;

// Create the items and properties generated by the CondensedImageBox.
// The CondensedImageBox always creates 8 properties for specification easiness.
Expand Down

0 comments on commit 57dd2a9

Please sign in to comment.