Skip to content

Commit 95e5ce8

Browse files
committed
Remove potential out of bound access to alphaItemIndices
It is possible to craft a file that has more alpha auxiliary items than color items and trigger an out of bound access into alphaItemIndices in the for loop. Fix is to ensure that each color grid item has exactly one alpha grid item. Also, ensure that there are exactly the same number of color grids as informed in the grid config before trying to find the alpha item. Also, update a diagnostic error message to cover all cases (i.e.) there can be more grids than necessary as well. This is a manual cherry-pick of commit `6d62963` (PR #1756) on to v1.0.x branch.
1 parent 456f78a commit 95e5ce8

File tree

1 file changed

+30
-8
lines changed

1 file changed

+30
-8
lines changed

src/read.c

Lines changed: 30 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1419,7 +1419,7 @@ static avifBool avifDecoderGenerateImageGridTiles(avifDecoder * decoder, avifIma
14191419

14201420
if (tilesAvailable != grid->rows * grid->columns) {
14211421
avifDiagnosticsPrintf(&decoder->diag,
1422-
"Grid image of dimensions %ux%u requires %u tiles, and only %u were found",
1422+
"Grid image of dimensions %ux%u requires %u tiles, but %u were found",
14231423
grid->columns,
14241424
grid->rows,
14251425
grid->rows * grid->columns,
@@ -3664,21 +3664,33 @@ static avifResult avifDecoderDataFindAlphaItem(avifDecoderData * data,
36643664
maxItemID = item->id;
36653665
}
36663666
if (item->dimgForID == colorItem->id) {
3667+
avifBool seenAlphaForCurrentItem = AVIF_FALSE;
36673668
for (uint32_t j = 0; j < colorItem->meta->items.count; ++j) {
36683669
avifDecoderItem * auxlItem = &colorItem->meta->items.item[j];
36693670
if (avifDecoderItemIsAlphaAux(auxlItem, item->id)) {
3671+
if (seenAlphaForCurrentItem || auxlItem->dimgForID != 0) {
3672+
// One of the following invalid cases:
3673+
// * Multiple items are claiming to be the alpha auxiliary of the current item.
3674+
// * Alpha auxiliary is dimg for another item.
3675+
avifFree(alphaItemIndices);
3676+
*alphaItem = NULL;
3677+
*isAlphaItemInInput = AVIF_FALSE;
3678+
return AVIF_RESULT_INVALID_IMAGE_GRID;
3679+
}
36703680
alphaItemIndices[alphaItemCount++] = j;
3681+
seenAlphaForCurrentItem = AVIF_TRUE;
36713682
}
36723683
}
3684+
if (!seenAlphaForCurrentItem) {
3685+
// No alpha auxiliary item was found for the current item. Treat this as an image without alpha.
3686+
avifFree(alphaItemIndices);
3687+
*alphaItem = NULL;
3688+
*isAlphaItemInInput = AVIF_FALSE;
3689+
return AVIF_RESULT_OK;
3690+
}
36733691
}
36743692
}
3675-
if (alphaItemCount != colorItemCount) {
3676-
// Not all the color items had an alpha auxiliary attached to it. Report this case as an image without alpha channel.
3677-
avifFree(alphaItemIndices);
3678-
*alphaItem = NULL;
3679-
*isAlphaItemInInput = AVIF_FALSE;
3680-
return AVIF_RESULT_OK;
3681-
}
3693+
assert(alphaItemCount == colorItemCount);
36823694

36833695
int colorItemIndex = -1;
36843696
for (uint32_t i = 0; i < data->meta->items.count; ++i) {
@@ -3937,6 +3949,16 @@ avifResult avifDecoderReset(avifDecoder * decoder)
39373949
decoder->imageDimensionLimit,
39383950
data->diag),
39393951
AVIF_RESULT_INVALID_IMAGE_GRID);
3952+
// Validate that there are exactly the same number of dimg items to form the grid.
3953+
uint32_t dimgItemCount = 0;
3954+
for (uint32_t i = 0; i < colorItem->meta->items.count; ++i) {
3955+
if (colorItem->meta->items.item[i].dimgForID == colorItem->id) {
3956+
++dimgItemCount;
3957+
}
3958+
}
3959+
if (dimgItemCount != data->color.grid.rows * data->color.grid.columns) {
3960+
return AVIF_RESULT_INVALID_IMAGE_GRID;
3961+
}
39403962
colorCodecType = avifDecoderItemGetGridCodecType(colorItem);
39413963
if (colorCodecType == AVIF_CODEC_TYPE_UNKNOWN) {
39423964
return AVIF_RESULT_INVALID_IMAGE_GRID;

0 commit comments

Comments
 (0)