From fba19d6c4975c1628ce47473a72b95e4e17992b4 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 26 May 2025 15:42:55 +0200 Subject: [PATCH] h265parser: Fix max_dec_pic_buffering_minus1 bound check Allowed max value is MaxDpbSize - 1 --- gst-libs/gst/codecparsers/gsth265parser.c | 32 ++++++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/gst-libs/gst/codecparsers/gsth265parser.c b/gst-libs/gst/codecparsers/gsth265parser.c index 2e8ef182b..200a06796 100644 --- a/gst-libs/gst/codecparsers/gsth265parser.c +++ b/gst-libs/gst/codecparsers/gsth265parser.c @@ -75,6 +75,8 @@ GST_DEBUG_CATEGORY_STATIC (h265_parser_debug); #define GST_CAT_DEFAULT h265_parser_debug +#define MAX_DPB_SIZE 16 + static gboolean initialized = FALSE; #define INITIALIZE_DEBUG_CATEGORY \ if (!initialized) { \ @@ -1506,7 +1508,7 @@ gst_h265_parse_vps (GstH265NalUnit * nalu, GstH265VPS * vps) for (i = (vps->sub_layer_ordering_info_present_flag ? 0 : vps->max_sub_layers_minus1); i <= vps->max_sub_layers_minus1; i++) { - READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], G_MAXUINT32 - 1); + READ_UE_MAX (&nr, vps->max_dec_pic_buffering_minus1[i], MAX_DPB_SIZE - 1); READ_UE_MAX (&nr, vps->max_num_reorder_pics[i], vps->max_dec_pic_buffering_minus1[i]); READ_UE_MAX (&nr, vps->max_latency_increase_plus1[i], G_MAXUINT32 - 1); @@ -1702,7 +1704,7 @@ gst_h265_parse_sps (GstH265Parser * parser, GstH265NalUnit * nalu, for (i = (sps->sub_layer_ordering_info_present_flag ? 0 : sps->max_sub_layers_minus1); i <= sps->max_sub_layers_minus1; i++) { - READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], 16); + READ_UE_MAX (&nr, sps->max_dec_pic_buffering_minus1[i], MAX_DPB_SIZE - 1); READ_UE_MAX (&nr, sps->max_num_reorder_pics[i], sps->max_dec_pic_buffering_minus1[i]); READ_UE_MAX (&nr, sps->max_latency_increase_plus1[i], G_MAXUINT32 - 1); @@ -2107,6 +2109,8 @@ gst_h265_parser_parse_slice_hdr (GstH265Parser * parser, if ((nalu->type != GST_H265_NAL_SLICE_IDR_W_RADL) && (nalu->type != GST_H265_NAL_SLICE_IDR_N_LP)) { + const GstH265ShortTermRefPicSet *ref_pic_sets = NULL; + READ_UINT16 (&nr, slice->pic_order_cnt_lsb, (sps->log2_max_pic_order_cnt_lsb_minus4 + 4)); @@ -2116,21 +2120,41 @@ gst_h265_parser_parse_slice_hdr (GstH265Parser * parser, (&slice->short_term_ref_pic_sets, &nr, sps->num_short_term_ref_pic_sets, sps)) goto error; + ref_pic_sets = &slice->short_term_ref_pic_sets; } else if (sps->num_short_term_ref_pic_sets > 1) { const guint n = ceil_log2 (sps->num_short_term_ref_pic_sets); READ_UINT8 (&nr, slice->short_term_ref_pic_set_idx, n); CHECK_ALLOWED_MAX (slice->short_term_ref_pic_set_idx, sps->num_short_term_ref_pic_sets - 1); + ref_pic_sets = + &sps->short_term_ref_pic_set[slice->short_term_ref_pic_set_idx]; + } else { + ref_pic_sets = &sps->short_term_ref_pic_set[0]; } if (sps->long_term_ref_pics_present_flag) { guint32 limit; + gint max_num_long_term_pics = 0; - if (sps->num_long_term_ref_pics_sps > 0) + if (sps->num_long_term_ref_pics_sps > 0) { READ_UE_MAX (&nr, slice->num_long_term_sps, sps->num_long_term_ref_pics_sps); + } + + /* Calculated upper bound num_long_term_pics can have. 7.4.7.1 */ + max_num_long_term_pics = + /* sps_max_dec_pic_buffering_minus1[TemporalId], allowed max is + * MaxDpbSize - 1 */ + MAX_DPB_SIZE - 1 + - (gint) slice->num_long_term_sps + - (gint) ref_pic_sets->NumNegativePics + - (gint) ref_pic_sets->NumPositivePics; + if (max_num_long_term_pics < 0) { + GST_WARNING ("Invalid stream, too many reference pictures"); + goto error; + } - READ_UE_MAX (&nr, slice->num_long_term_pics, 16); + READ_UE_MAX (&nr, slice->num_long_term_pics, max_num_long_term_pics); limit = slice->num_long_term_sps + slice->num_long_term_pics; for (i = 0; i < limit; i++) { if (i < slice->num_long_term_sps) { -- 2.49.0