frontends/va: Fix out of bounds write in AV1 decode tile info

For invalid streams tile cols and rows may be higher than 64.
This would overwrite data after the height_in_sbs array, but since
the maximum amount of bytes overwritten is bound by the maximum
supported decode resolution, this can't overwrite any important
fields and thus won't cause any observable issue.
As this can only happen with invalid streams, it still won't decode
correctly with this fixed.

Closes: https://gitlab.freedesktop.org/mesa/mesa/-/work_items/15290
Reviewed-by: Benjamin Cheng <benjamin.cheng@amd.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/41016>
This commit is contained in:
David Rosca 2026-04-17 09:38:08 +02:00 committed by Marge Bot
parent c2a4fa33b8
commit 7b5277ce5c

View file

@ -72,6 +72,9 @@ static void tile_info(vlVaContext *context, VADecPictureParameterBufferAV1 *av1)
tileWidthSb = (sbCols + (1 << TileColsLog2) - 1) >> TileColsLog2;
i = 0;
for (startSb = 0; startSb < sbCols; startSb += tileWidthSb) {
if (i >= ARRAY_SIZE(context->desc.av1.picture_parameter.width_in_sbs))
break;
context->desc.av1.picture_parameter.tile_col_start_sb[i] = startSb;
context->desc.av1.picture_parameter.width_in_sbs[i] = tileWidthSb;
i++;
@ -81,6 +84,9 @@ static void tile_info(vlVaContext *context, VADecPictureParameterBufferAV1 *av1)
tileHeightSb = (sbRows + (1 << TileRowsLog2) - 1) >> TileRowsLog2;
i = 0;
for (startSb = 0; startSb < sbRows; startSb += tileHeightSb) {
if (i >= ARRAY_SIZE(context->desc.av1.picture_parameter.height_in_sbs))
break;
context->desc.av1.picture_parameter.tile_row_start_sb[i] = startSb;
context->desc.av1.picture_parameter.height_in_sbs[i] = tileHeightSb;
i++;
@ -91,10 +97,11 @@ static void tile_info(vlVaContext *context, VADecPictureParameterBufferAV1 *av1)
startSb = 0;
for (i = 0; startSb < sbCols; ++i) {
unsigned sizeSb;
if (i >= ARRAY_SIZE(av1->width_in_sbs_minus_1))
break;
unsigned sizeSb = (av1->width_in_sbs_minus_1)[i] + 1;
context->desc.av1.picture_parameter.tile_col_start_sb[i] = startSb;
sizeSb = (av1->width_in_sbs_minus_1)[i] + 1;
context->desc.av1.picture_parameter.width_in_sbs[i] = sizeSb;
widestTileSb = MAX2(sizeSb, widestTileSb);
startSb += sizeSb;
@ -104,9 +111,11 @@ static void tile_info(vlVaContext *context, VADecPictureParameterBufferAV1 *av1)
startSb = 0;
for (i = 0; startSb < sbRows; ++i) {
if (i >= ARRAY_SIZE(av1->height_in_sbs_minus_1))
break;
unsigned height_in_sbs_minus_1 = (av1->height_in_sbs_minus_1)[i];
context->desc.av1.picture_parameter.height_in_sbs[i] = height_in_sbs_minus_1 + 1;
context->desc.av1.picture_parameter.tile_row_start_sb[i] = startSb;
startSb += height_in_sbs_minus_1 + 1;
height_sb -= height_in_sbs_minus_1 + 1;