PR #23036 opened by michaelni URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23036 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/23036.patch
Modifying the keys of a sorted structure, be that a tree or other can lead to changes in the ordering and undefined behavior. It can also lead to collisions with existing keys. All these cases need to be handled unless there is a bug elsewhere that would prevent them. Fixes: out of array access Fixes: 504281984/clusterfuzz-testcase-minimized-ffmpeg_BSF_DTS2PTS_fuzzer-6032368162111488 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer <[email protected]> >From 093e3bd3f7d790520080f881c794ff7e13d10825 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Thu, 7 May 2026 03:03:31 +0200 Subject: [PATCH] avcodec/bsf/dts2pts: fix binary tree invariant violation on selective dec_poc Modifying the keys of a sorted structure, be that a tree or other can lead to changes in the ordering and undefined behavior. It can also lead to collisions with existing keys. All these cases need to be handled unless there is a bug elsewhere that would prevent them. Fixes: out of array access Fixes: 504281984/clusterfuzz-testcase-minimized-ffmpeg_BSF_DTS2PTS_fuzzer-6032368162111488 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer <[email protected]> --- libavcodec/bsf/dts2pts.c | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/libavcodec/bsf/dts2pts.c b/libavcodec/bsf/dts2pts.c index ff03508c18..6e391c291f 100644 --- a/libavcodec/bsf/dts2pts.c +++ b/libavcodec/bsf/dts2pts.c @@ -413,11 +413,23 @@ static int hevc_init_nb_frame(AVBSFContext *ctx, int poc) return 0; } -static int same_gop(void *opaque, void *elem) +typedef struct DTS2PTSCollect { + int gop; + DTS2PTSNode **out; + int count; + int max; +} DTS2PTSCollect; + +static int collect_same_gop(void *opaque, void *elem) { + DTS2PTSCollect *c = opaque; DTS2PTSNode *node = elem; - int gop = ((int *)opaque)[1]; - return FFDIFFSIGN(gop, node->gop); + if (node->gop == c->gop) { + if (c->count < c->max) + c->out[c->count] = node; + c->count++; + } + return 0; } static int hevc_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, bool *queued) @@ -441,10 +453,26 @@ static int hevc_queue_frame(AVBSFContext *ctx, AVPacket *pkt, int poc, bool *que } if (poc < s->nb_frame && hevc->gop == s->gop) { - int tmp[] = {s->nb_frame - poc, s->gop}; + int dec = s->nb_frame - poc; + DTS2PTSNode *nodes[HEVC_MAX_DPB_SIZE * 2]; + DTS2PTSCollect c = { s->gop, nodes, 0, FF_ARRAY_ELEMS(nodes) }; - s->nb_frame -= tmp[0]; - av_tree_enumerate(s->root, tmp, same_gop, dec_poc); + s->nb_frame -= dec; + + av_tree_enumerate(s->root, &c, NULL, collect_same_gop); + av_assert0(c.count <= c.max); + for (int i = 0; i < c.count; i++) { + struct AVTreeNode *tnode = NULL; + DTS2PTSNode *r; + av_tree_insert(&s->root, nodes[i], cmp_insert, &tnode); + nodes[i]->poc -= dec; + r = av_tree_insert(&s->root, nodes[i], cmp_insert, &tnode); + if (r && r != nodes[i]) { + *r = *nodes[i]; + av_refstruct_unref(&nodes[i]); + av_free(tnode); + } + } } ret = alloc_and_insert_node(ctx, pkt->dts, pkt->duration, s->nb_frame, 1, s->gop); -- 2.52.0 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
