PR #21275 opened by charles URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21275 Patch URL: https://code.ffmpeg.org/FFmpeg/FFmpeg/pulls/21275.patch
The patches were cherry-picked from fixes in other stable branches and they fix (plus some other regressions or code changes needed): - CVE-2023-6603 - CVE-2024-36615 - CVE-2025-1594 - CVE-2025-7700 - CVE-2025-9951 - CVE-2025-10256 I've run make fate and make check with the default configure options and there wasn't regressions. I've also tested the fixes for vulnerabilities with PoCs available. The patches that required a more intrusive backporting have a comment added to the commit message too. >From d26d148024cdae6d608ff700b7f1592806a6d031 Mon Sep 17 00:00:00 2001 From: Marton Balint <[email protected]> Date: Sat, 10 Apr 2021 11:59:00 +0200 Subject: [PATCH 1/9] avformat/hls: check return value of new_init_section() Fixes part of ticket #8931. Fixes: CVE-2023-6603 Signed-off-by: Marton Balint <[email protected]> (cherry picked from commit 28c83584e8f3cd747c1476a74cc2841d3d1fa7f3) Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit e3e479d077044175dca0376739eeafde49610573) Signed-off-by: Carlos Henrique Lima Melara <[email protected]> --- libavformat/hls.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/libavformat/hls.c b/libavformat/hls.c index acfb382faa..0e40dceec9 100644 --- a/libavformat/hls.c +++ b/libavformat/hls.c @@ -886,6 +886,10 @@ static int parse_playlist(HLSContext *c, const char *url, ff_parse_key_value(ptr, (ff_parse_key_val_cb) handle_init_section_args, &info); cur_init_section = new_init_section(pls, &info, url); + if (!cur_init_section) { + ret = AVERROR(ENOMEM); + goto fail; + } cur_init_section->key_type = key_type; if (has_iv) { memcpy(cur_init_section->iv, iv, sizeof(iv)); -- 2.49.1 >From e31552bbad5812adeeb14f82adee90d2fae7befd Mon Sep 17 00:00:00 2001 From: Andreas Rheinhardt <[email protected]> Date: Fri, 12 Aug 2022 03:05:34 +0200 Subject: [PATCH 2/9] avcodec/vp9: Fix race when attaching side-data for show-existing frame When outputting a show-existing frame, the VP9 decoder simply created a reference to said frame and returned it immediately to the caller, without waiting for it to have finished decoding. In case of frame-threading it is possible for the frame to only be decoded while it was waiting to be output. This is normally benign. But there is one case where it is not: If the user wants video encoding parameters to be exported, said side data will only be attached to the src AVFrame at the end of decoding the frame that is actually being shown. Without synchronisation adding said side data in the decoder thread and the reads in av_frame_ref() in the output thread constitute a data race. This happens e.g. when using the venc_data_dump tool with vp90-2-10-show-existing-frame.webm from the FATE-suite. Fix this by actually waiting for the frame to be output. Backport comment: in 7.1 there was a switch to ProgressFrames (7bd3b737163), so there was the need to convert the calls back to ThreadFrames calls. Fixes: CVE-2024-36615 Signed-off-by: Andreas Rheinhardt <[email protected]> (cherry picked from commit 0ba058579f332b3060d8470a04ddd3fbf305be61) Signed-off-by: Carlos Henrique Lima Melara <[email protected]> --- libavcodec/vp9.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index fd0bab14a2..bc58d647ab 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -1566,6 +1566,8 @@ static int vp9_decode_frame(AVCodecContext *avctx, void *frame, av_log(avctx, AV_LOG_ERROR, "Requested reference %d not available\n", ref); return AVERROR_INVALIDDATA; } + ff_thread_await_progress(&s->s.refs[ref], INT_MAX, 0); + if ((ret = av_frame_ref(frame, s->s.refs[ref].f)) < 0) return ret; ((AVFrame *)frame)->pts = pkt->pts; @@ -1732,10 +1734,8 @@ FF_ENABLE_DEPRECATION_WARNINGS #endif { ret = decode_tiles(avctx, data, size); - if (ret < 0) { - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); - return ret; - } + if (ret < 0) + goto fail; } // Sum all counts fields into td[0].counts for tile threading @@ -1749,18 +1749,19 @@ FF_ENABLE_DEPRECATION_WARNINGS ff_thread_finish_setup(avctx); } } while (s->pass++ == 1); - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); if (s->td->error_info < 0) { av_log(avctx, AV_LOG_ERROR, "Failed to decode tile data\n"); s->td->error_info = 0; - return AVERROR_INVALIDDATA; + ret = AVERROR_INVALIDDATA; + goto fail; } if (avctx->export_side_data & AV_CODEC_EXPORT_DATA_VIDEO_ENC_PARAMS) { ret = vp9_export_enc_params(s, &s->s.frames[CUR_FRAME]); if (ret < 0) - return ret; + goto fail; } + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); finish: // ref frame setup @@ -1779,6 +1780,9 @@ finish: } return pkt->size; +fail: + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); + return ret; } static void vp9_decode_flush(AVCodecContext *avctx) -- 2.49.1 >From 446d08494e2fb6806245ca0eb447973834eaa3e3 Mon Sep 17 00:00:00 2001 From: Haihao Xiang <[email protected]> Date: Mon, 22 Apr 2024 14:57:08 +0800 Subject: [PATCH 3/9] lavc/vp9: Fix regression introduced in 0ba05857 It is possible that ff_progress_frame_await() is called but ff_progress_frame_report() isn't called when a hardware acceleration method is used, so a thread for vp9 decoding might get stuck. Backport comment: in 7.1 there was a switch to ProgressFrames (7bd3b737163), so there was the need to convert the calls back to ThreadFrames calls. In this case, it was just moving the progress report function inside the finish label. Reviewed-by: Andreas Rheinhardt <[email protected]> Signed-off-by: Haihao Xiang <[email protected]> (cherry picked from commit 8c62d77139ca07390414fcfd26b2a4d506fed3b9) Signed-off-by: Carlos Henrique Lima Melara <[email protected]> --- libavcodec/vp9.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/vp9.c b/libavcodec/vp9.c index bc58d647ab..3ea02e0773 100644 --- a/libavcodec/vp9.c +++ b/libavcodec/vp9.c @@ -1761,9 +1761,9 @@ FF_ENABLE_DEPRECATION_WARNINGS if (ret < 0) goto fail; } - ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); finish: + ff_thread_report_progress(&s->s.frames[CUR_FRAME].tf, INT_MAX, 0); // ref frame setup for (i = 0; i < 8; i++) { if (s->s.refs[i].f->buf[0]) -- 2.49.1 >From 37751e8d1ab080cb117005e440d549705a80d72a Mon Sep 17 00:00:00 2001 From: Lynne <[email protected]> Date: Sat, 8 Feb 2025 04:35:31 +0100 Subject: [PATCH 4/9] aacenc_tns: clamp filter direction energy measurement The issue is that: float en[2]; ... tns->n_filt[w] = is8 ? 1 : order != TNS_MAX_ORDER ? 2 : 3; for (g = 0; g < tns->n_filt[w]; g++) { tns->direction[w][g] = slant != 2 ? slant : en[g] < en[!g]; When using the AAC Main profile, n_filt = 3, and slant is by default 2 (normal long frames), g can go above 1. en is the evolution of energy in the frequency domain for every band at the given window. E.g. whether the energy is concentrated at the top of each band, or the bottom. For 2-pole filters, its straightforward. For 3-pole filters, we need more than 2 measurements. This commit properly implements support for 3-pole filters, by measuring the band energy across three areas. Do note that even xHE-AAC caps n_filt to 2, and only AAC Main allows n_filt == 3. Fixes https://trac.ffmpeg.org/ticket/11418 Fixes: CVE-2025-1594 (cherry picked from commit ed09aa28ae3b4509f00a24a9ebdeb084ee00736a) (cherry picked from commit f98f142da571653436596ccad2d09c7e39bfd4fb) Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit 21fe514152a22cc5653fd95f065320adfcf076e9) Signed-off-by: Carlos Henrique Lima Melara <[email protected]> --- libavcodec/aacenc_tns.c | 40 +++++++++++++++++++++++++++------------- 1 file changed, 27 insertions(+), 13 deletions(-) diff --git a/libavcodec/aacenc_tns.c b/libavcodec/aacenc_tns.c index 2ffe1f8de8..f56226c0c7 100644 --- a/libavcodec/aacenc_tns.c +++ b/libavcodec/aacenc_tns.c @@ -173,6 +173,7 @@ void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce) sce->ics.window_sequence[0] == LONG_START_SEQUENCE ? 0 : 2; const int sfb_len = sfb_end - sfb_start; const int coef_len = sce->ics.swb_offset[sfb_end] - sce->ics.swb_offset[sfb_start]; + const int n_filt = is8 ? 1 : order != TNS_MAX_ORDER ? 2 : 3; if (coef_len <= 0 || sfb_len <= 0) { sce->tns.present = 0; @@ -180,16 +181,30 @@ void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce) } for (w = 0; w < sce->ics.num_windows; w++) { - float en[2] = {0.0f, 0.0f}; - int oc_start = 0, os_start = 0; + float en[4] = {0.0f, 0.0f, 0.0f, 0.0f}; + int oc_start = 0; int coef_start = sce->ics.swb_offset[sfb_start]; - for (g = sfb_start; g < sce->ics.num_swb && g <= sfb_end; g++) { - FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[w*16+g]; - if (g > sfb_start + (sfb_len/2)) - en[1] += band->energy; - else - en[0] += band->energy; + if (n_filt == 2) { + for (g = sfb_start; g < sce->ics.num_swb && g <= sfb_end; g++) { + FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[w*16+g]; + if (g > sfb_start + (sfb_len/2)) + en[1] += band->energy; /* End */ + else + en[0] += band->energy; /* Start */ + } + en[2] = en[0]; + } else { + for (g = sfb_start; g < sce->ics.num_swb && g <= sfb_end; g++) { + FFPsyBand *band = &s->psy.ch[s->cur_channel].psy_bands[w*16+g]; + if (g > sfb_start + (sfb_len/2) + (sfb_len/4)) + en[2] += band->energy; /* End */ + else if (g > sfb_start + (sfb_len/2) - (sfb_len/4)) + en[1] += band->energy; /* Middle */ + else + en[0] += band->energy; /* Start */ + } + en[3] = en[0]; } /* LPC */ @@ -199,15 +214,14 @@ void ff_aac_search_for_tns(AACEncContext *s, SingleChannelElement *sce) if (!order || !isfinite(gain) || gain < TNS_GAIN_THRESHOLD_LOW || gain > TNS_GAIN_THRESHOLD_HIGH) continue; - tns->n_filt[w] = is8 ? 1 : order != TNS_MAX_ORDER ? 2 : 3; + tns->n_filt[w] = n_filt; for (g = 0; g < tns->n_filt[w]; g++) { - tns->direction[w][g] = slant != 2 ? slant : en[g] < en[!g]; - tns->order[w][g] = g < tns->n_filt[w] ? order/tns->n_filt[w] : order - oc_start; - tns->length[w][g] = g < tns->n_filt[w] ? sfb_len/tns->n_filt[w] : sfb_len - os_start; + tns->direction[w][g] = slant != 2 ? slant : en[g] < en[g + 1]; + tns->order[w][g] = order/tns->n_filt[w]; + tns->length[w][g] = sfb_len/tns->n_filt[w]; quantize_coefs(&coefs[oc_start], tns->coef_idx[w][g], tns->coef[w][g], tns->order[w][g], c_bits); oc_start += tns->order[w][g]; - os_start += tns->length[w][g]; } count++; } -- 2.49.1 >From bbba019328b854bd5c5ee2d570f365c82116660c Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang <[email protected]> Date: Thu, 10 Jul 2025 16:26:39 +0000 Subject: [PATCH 5/9] libavcodec/alsdec.c: Add check for av_malloc_array() and av_calloc() Add check for the return value of av_malloc_array() and av_calloc() to avoid potential NULL pointer dereference. Backport comment: In v5.1 and newer, av_calloc is used, but in v4.3 we had av_mallocz_array, but it's susceptible to ENOMEM just the same. Fixes: CVE-2025-7700 Fixes: dcfd24b10c ("avcodec/alsdec: Implement floating point sample data decoding") Signed-off-by: Jiasheng Jiang <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit 35a6de137a39f274d5e01ed0e0e6c4f04d0aaf07) Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit aad4b59cfee1f0a3cf02f5e2b1f291ce013bf27e) Signed-off-by: Carlos Henrique Lima Melara <[email protected]> --- libavcodec/alsdec.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libavcodec/alsdec.c b/libavcodec/alsdec.c index fd2f6f022f..6f03c6508d 100644 --- a/libavcodec/alsdec.c +++ b/libavcodec/alsdec.c @@ -2116,8 +2116,8 @@ static av_cold int decode_init(AVCodecContext *avctx) ctx->nbits = av_malloc_array(ctx->cur_frame_length, sizeof(*ctx->nbits)); ctx->mlz = av_mallocz(sizeof(*ctx->mlz)); - if (!ctx->mlz || !ctx->acf || !ctx->shift_value || !ctx->last_shift_value - || !ctx->last_acf_mantissa || !ctx->raw_mantissa) { + if (!ctx->larray || !ctx->nbits || !ctx->mlz || !ctx->acf || !ctx->shift_value + || !ctx->last_shift_value || !ctx->last_acf_mantissa || !ctx->raw_mantissa) { av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); ret = AVERROR(ENOMEM); goto fail; @@ -2128,6 +2128,10 @@ static av_cold int decode_init(AVCodecContext *avctx) for (c = 0; c < avctx->channels; ++c) { ctx->raw_mantissa[c] = av_mallocz_array(ctx->cur_frame_length, sizeof(**ctx->raw_mantissa)); + if (!ctx->raw_mantissa[c]) { + av_log(avctx, AV_LOG_ERROR, "Allocating buffer memory failed.\n"); + return AVERROR(ENOMEM); + } } } -- 2.49.1 >From 3a8d7720f08770da996e4f323fa1561dac78f202 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 5 Aug 2025 23:18:47 +0200 Subject: [PATCH 6/9] avcodec/jpeg2000dec: move cdef default check into get_siz() This way cdef is at its final value earlier Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit 104d6846c1be0cb757dc95d5801a416f4d7c687d) Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit de97cc3892f9655e292af8d7d235f2c1eb77b3b7) Signed-off-by: Carlos Henrique Lima Melara <[email protected]> --- libavcodec/jpeg2000dec.c | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 5f36bc6e35..51fd5dd2dc 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -340,6 +340,17 @@ static int get_siz(Jpeg2000DecoderContext *s) return AVERROR_INVALIDDATA; } + for (i = 0; i < s->ncomponents; i++) { + if (s->cdef[i] < 0) { + for (i = 0; i < s->ncomponents; i++) { + s->cdef[i] = i + 1; + } + if ((s->ncomponents & 1) == 0) + s->cdef[s->ncomponents-1] = 0; + } + } + // after here we no longer have to consider negative cdef + for (i = 0; i < s->ncomponents; i++) { // Ssiz_i XRsiz_i, YRsiz_i uint8_t x = bytestream2_get_byteu(&s->g); s->cbps[i] = (x & 0x7f) + 1; -- 2.49.1 >From 24b9705d679df51d282adbde18c3fad1ff885639 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Tue, 5 Aug 2025 23:42:23 +0200 Subject: [PATCH 7/9] avcodec/jpeg2000dec: implement cdef remapping during pixel format matching Fixes: out of array access Fixes: poc.jp2 Fixes: CVE-2025-9951 Found-by: Andy Nguyen <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit 01a292c7e36545ddeb3c7f79cd02e2611cd37d73) Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit eb80096cbe8b11105f7be0eb99233667e8836c1a) Signed-off-by: Carlos Henrique Lima Melara <[email protected]> --- libavcodec/jpeg2000dec.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index 51fd5dd2dc..a04c545669 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -351,6 +351,14 @@ static int get_siz(Jpeg2000DecoderContext *s) } // after here we no longer have to consider negative cdef + int cdef_used = 0; + for (i = 0; i < s->ncomponents; i++) + cdef_used |= 1<<s->cdef[i]; + + // Check that the channels we have are what we expect for the number of components + if (cdef_used != ((int[]){0,2,3,14,15})[s->ncomponents]) + return AVERROR_INVALIDDATA; + for (i = 0; i < s->ncomponents; i++) { // Ssiz_i XRsiz_i, YRsiz_i uint8_t x = bytestream2_get_byteu(&s->g); s->cbps[i] = (x & 0x7f) + 1; @@ -363,7 +371,9 @@ static int get_siz(Jpeg2000DecoderContext *s) av_log(s->avctx, AV_LOG_ERROR, "Invalid sample separation %d/%d\n", s->cdx[i], s->cdy[i]); return AVERROR_INVALIDDATA; } - log2_chroma_wh |= s->cdy[i] >> 1 << i * 4 | s->cdx[i] >> 1 << i * 4 + 2; + int i_remapped = s->cdef[i] ? s->cdef[i]-1 : (s->ncomponents-1); + + log2_chroma_wh |= s->cdy[i] >> 1 << i_remapped * 4 | s->cdx[i] >> 1 << i_remapped * 4 + 2; } s->numXtiles = ff_jpeg2000_ceildiv(s->width - s->tile_offset_x, s->tile_width); -- 2.49.1 >From 893142c932081f1467d492131557b02d0571b005 Mon Sep 17 00:00:00 2001 From: Michael Niedermayer <[email protected]> Date: Sat, 9 Aug 2025 11:38:07 +0200 Subject: [PATCH 8/9] avcodec/jpeg2000dec: Make sure the 4 extra bytes allocated are initialized Fixes: use of uninitialized memory Fixes: 429130590/clusterfuzz-testcase-minimized-ffmpeg_AV_CODEC_ID_JPEG2000_DEC_fuzzer-5736930522497024 Found-by: continuous fuzzing process https://github.com/google/oss-fuzz/tree/master/projects/ffmpeg Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit d6fe3786cd8c06437756d407f727ff01cf1774ff) Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit 39f4a60035085e7b1465fa7159d3ef03114dfe27) Signed-off-by: Carlos Henrique Lima Melara <[email protected]> --- libavcodec/jpeg2000dec.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c index a04c545669..096a06b79b 100644 --- a/libavcodec/jpeg2000dec.c +++ b/libavcodec/jpeg2000dec.c @@ -1219,6 +1219,7 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, bytestream2_get_bufferu(&s->g, cblk->data + cblk->length, cblk->lengthinc[cwsno]); cblk->length += cblk->lengthinc[cwsno]; + memset(cblk->data + cblk->length, 0, 4); cblk->lengthinc[cwsno] = 0; if (cblk->nb_terminationsinc) { cblk->nb_terminationsinc--; -- 2.49.1 >From 48205aaee52aa6f34d45829a93a14b5c63141b59 Mon Sep 17 00:00:00 2001 From: Jiasheng Jiang <[email protected]> Date: Wed, 6 Aug 2025 16:39:47 +0000 Subject: [PATCH 9/9] libavfilter/af_firequalizer: Add check for av_malloc_array() Add check for the return value of av_malloc_array() to avoid potential NULL pointer dereference. Fixes: CVE-2025-10256 Fixes: d3be186ed1 ("avfilter/firequalizer: add dumpfile and dumpscale option") Signed-off-by: Jiasheng Jiang <[email protected]> Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit a25462482c02c004d685a8fcf2fa63955aaa0931) Signed-off-by: Michael Niedermayer <[email protected]> (cherry picked from commit 00b5af29a4203a31574c11b3df892d78d5d862ec) Signed-off-by: Carlos Henrique Lima Melara <[email protected]> --- libavfilter/af_firequalizer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libavfilter/af_firequalizer.c b/libavfilter/af_firequalizer.c index f4513a1c46..748172945a 100644 --- a/libavfilter/af_firequalizer.c +++ b/libavfilter/af_firequalizer.c @@ -822,6 +822,8 @@ static int config_input(AVFilterLink *inlink) if (s->dumpfile) { s->analysis_rdft = av_rdft_init(rdft_bits, DFT_R2C); s->dump_buf = av_malloc_array(s->analysis_rdft_len, sizeof(*s->dump_buf)); + if (!s->dump_buf) + return AVERROR(ENOMEM); } s->analysis_buf = av_malloc_array(s->analysis_rdft_len, sizeof(*s->analysis_buf)); -- 2.49.1 _______________________________________________ ffmpeg-devel mailing list -- [email protected] To unsubscribe send an email to [email protected]
