From 9f58c4d11169f301e2b476a2b0ae8c2d5f759998 Mon Sep 17 00:00:00 2001 From: happyworker <208suo@208suo.com> Date: Tue, 8 Jul 2025 10:34:56 +0800 Subject: [PATCH] Fix CVE-2021-38090/CVE-2020-21697/CVE-2020-22042/CVE-2020-21688/CVE-2020-22037/CVE-2020-22051/CVE-2020-22020/CVE-2025-22921/CVE-2025-22919 s (cherry picked from commit f9f3df71cfee4529f3f2b5f7123ce9e69a369e29) --- ffmpeg.spec | 6 +- fix-CVE-2020-2.patch | 277 +++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 fix-CVE-2020-2.patch diff --git a/ffmpeg.spec b/ffmpeg.spec index d817860..804726b 100644 --- a/ffmpeg.spec +++ b/ffmpeg.spec @@ -60,7 +60,7 @@ Summary: Digital VCR and streaming server Name: ffmpeg%{?flavor} Version: 4.2.4 -Release: 23 +Release: 24 License: %{ffmpeg_license} URL: http://ffmpeg.org/ %if 0%{?date} @@ -95,6 +95,7 @@ Patch23: backport-CVE-2024-36618.patch Patch24: backport-CVE-2024-36617.patch Patch25: backport-CVE-2024-36613.patch Patch26: fix-CVE-2020.patch +Patch27: fix-CVE-2020-2.patch Requires: %{name}-libs%{?_isa} = %{version}-%{release} %{?_with_cuda:BuildRequires: cuda-minimal-build-%{_cuda_version_rpm} cuda-drivers-devel} @@ -428,6 +429,9 @@ install -pm755 tools/qt-faststart %{buildroot}%{_bindir} %changelog +* Tue Jul 8 2025 happyworker <208suo@208suo.com> - 4.2.4-24 +- Fix CVE-2021-38090/CVE-2020-21697/CVE-2020-22042/CVE-2020-21688/CVE-2020-22037/CVE-2020-22051/CVE-2020-22020/CVE-2025-22921/CVE-2025-22919 + * Fri Jul 4 2025 happyworker <208suo@208suo.com> - 4.2.4-23 - Fix CVE-2020-22026/CVE-2020-22019/CVE-2020-22021/CVE-2020-22038/CVE-2020-22039/CVE-2020-22044/CVE-2020-22043 diff --git a/fix-CVE-2020-2.patch b/fix-CVE-2020-2.patch new file mode 100644 index 0000000..21763d5 --- /dev/null +++ b/fix-CVE-2020-2.patch @@ -0,0 +1,277 @@ +From 52d148aea54ad9d5fa33a65474d71095ba61cb43 Mon Sep 17 00:00:00 2001 +From: Michael Niedermayer +Date: Tue, 8 Jul 2025 10:52:12 +0800 +Subject: [PATCH] avcodec/frame_thread_encoder: Free AVCodecContext structure on error during init + +--- + libavcodec/frame_thread_encoder.c | 12 ++++++--- + libavcodec/jpeg2000dec.c | 1 + + libavfilter/buffersrc.c | 6 +++++ + libavfilter/vf_convolution.c | 41 ++++++++++++++++--------------- + libavfilter/vf_fieldmatch.c | 2 +- + libavfilter/vf_tile.c | 2 +- + libavformat/movenc.c | 4 +++ + libavformat/mpegenc.c | 21 ++++++++++------ + 8 files changed, 56 insertions(+), 33 deletions(-) + +diff --git a/libavcodec/frame_thread_encoder.c b/libavcodec/frame_thread_encoder.c +index 55756c4..3f21351 100644 +--- a/libavcodec/frame_thread_encoder.c ++++ b/libavcodec/frame_thread_encoder.c +@@ -117,6 +117,7 @@ end: + int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ + int i=0; + ThreadContext *c; ++ AVCodecContext *thread_avctx = NULL; + + + if( !(avctx->thread_type & FF_THREAD_FRAME) +@@ -195,16 +196,18 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ + AVDictionary *tmp = NULL; + int ret; + void *tmpv; +- AVCodecContext *thread_avctx = avcodec_alloc_context3(avctx->codec); ++ thread_avctx = avcodec_alloc_context3(avctx->codec); + if(!thread_avctx) + goto fail; + tmpv = thread_avctx->priv_data; + *thread_avctx = *avctx; ++ thread_avctx->priv_data = tmpv; ++ thread_avctx->internal = NULL; ++ thread_avctx->hw_frames_ctx = NULL; ++ + ret = av_opt_copy(thread_avctx, avctx); + if (ret < 0) + goto fail; +- thread_avctx->priv_data = tmpv; +- thread_avctx->internal = NULL; + if (avctx->codec->priv_class) { + int ret = av_opt_copy(thread_avctx->priv_data, avctx->priv_data); + if (ret < 0) +@@ -232,6 +235,9 @@ int ff_frame_thread_encoder_init(AVCodecContext *avctx, AVDictionary *options){ + + return 0; + fail: ++ avcodec_close(thread_avctx); ++ av_freep(&thread_avctx); ++ + avctx->thread_count = i; + av_log(avctx, AV_LOG_ERROR, "ff_frame_thread_encoder_init failed\n"); + ff_frame_thread_encoder_free(avctx); +diff --git a/libavcodec/jpeg2000dec.c b/libavcodec/jpeg2000dec.c +index 019dc81..ea3b87b 100644 +--- a/libavcodec/jpeg2000dec.c ++++ b/libavcodec/jpeg2000dec.c +@@ -1091,6 +1091,7 @@ static int jpeg2000_decode_packet(Jpeg2000DecoderContext *s, Jpeg2000Tile *tile, + } + } + av_freep(&cblk->lengthinc); ++ cblk->nb_lengthinc = 0; + } + } + return 0; +diff --git a/libavfilter/buffersrc.c b/libavfilter/buffersrc.c +index e0ff7e4..d4d5340 100644 +--- a/libavfilter/buffersrc.c ++++ b/libavfilter/buffersrc.c +@@ -372,6 +372,12 @@ static av_cold int init_audio(AVFilterContext *ctx) + if (!(s->fifo = av_fifo_alloc(sizeof(AVFrame*)))) + return AVERROR(ENOMEM); + ++ if (s->sample_rate <= 0) { ++ av_log(ctx, AV_LOG_ERROR, "Sample rate not set\n"); ++ return AVERROR(EINVAL); ++ } ++ ++ + if (!s->time_base.num) + s->time_base = (AVRational){1, s->sample_rate}; + +diff --git a/libavfilter/vf_convolution.c b/libavfilter/vf_convolution.c +index 1305569..67aa18f 100644 +--- a/libavfilter/vf_convolution.c ++++ b/libavfilter/vf_convolution.c +@@ -152,10 +152,10 @@ static void filter16_prewitt(uint8_t *dstp, int width, + int x; + + for (x = 0; x < width; x++) { +- int suma = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[1][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * -1 + +- AV_RN16A(&c[6][2 * x]) * 1 + AV_RN16A(&c[7][2 * x]) * 1 + AV_RN16A(&c[8][2 * x]) * 1; +- int sumb = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -1 + +- AV_RN16A(&c[5][2 * x]) * 1 + AV_RN16A(&c[6][2 * x]) * -1 + AV_RN16A(&c[8][2 * x]) * 1; ++ float suma = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[1][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * -1 + ++ AV_RN16A(&c[6][2 * x]) * 1 + AV_RN16A(&c[7][2 * x]) * 1 + AV_RN16A(&c[8][2 * x]) * 1; ++ float sumb = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -1 + ++ AV_RN16A(&c[5][2 * x]) * 1 + AV_RN16A(&c[6][2 * x]) * -1 + AV_RN16A(&c[8][2 * x]) * 1; + + dst[x] = av_clip(sqrtf(suma*suma + sumb*sumb) * scale + delta, 0, peak); + } +@@ -170,8 +170,8 @@ static void filter16_roberts(uint8_t *dstp, int width, + int x; + + for (x = 0; x < width; x++) { +- int suma = AV_RN16A(&c[0][2 * x]) * 1 + AV_RN16A(&c[1][2 * x]) * -1; +- int sumb = AV_RN16A(&c[4][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -1; ++ float suma = AV_RN16A(&c[0][2 * x]) * 1 + AV_RN16A(&c[1][2 * x]) * -1; ++ float sumb = AV_RN16A(&c[4][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -1; + + dst[x] = av_clip(sqrtf(suma*suma + sumb*sumb) * scale + delta, 0, peak); + } +@@ -186,10 +186,10 @@ static void filter16_sobel(uint8_t *dstp, int width, + int x; + + for (x = 0; x < width; x++) { +- int suma = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[1][2 * x]) * -2 + AV_RN16A(&c[2][2 * x]) * -1 + +- AV_RN16A(&c[6][2 * x]) * 1 + AV_RN16A(&c[7][2 * x]) * 2 + AV_RN16A(&c[8][2 * x]) * 1; +- int sumb = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -2 + +- AV_RN16A(&c[5][2 * x]) * 2 + AV_RN16A(&c[6][2 * x]) * -1 + AV_RN16A(&c[8][2 * x]) * 1; ++ float suma = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[1][2 * x]) * -2 + AV_RN16A(&c[2][2 * x]) * -1 + ++ AV_RN16A(&c[6][2 * x]) * 1 + AV_RN16A(&c[7][2 * x]) * 2 + AV_RN16A(&c[8][2 * x]) * 1; ++ float sumb = AV_RN16A(&c[0][2 * x]) * -1 + AV_RN16A(&c[2][2 * x]) * 1 + AV_RN16A(&c[3][2 * x]) * -2 + ++ AV_RN16A(&c[5][2 * x]) * 2 + AV_RN16A(&c[6][2 * x]) * -1 + AV_RN16A(&c[8][2 * x]) * 1; + + dst[x] = av_clip(sqrtf(suma*suma + sumb*sumb) * scale + delta, 0, peak); + } +@@ -206,10 +206,10 @@ static void filter_prewitt(uint8_t *dst, int width, + int x; + + for (x = 0; x < width; x++) { +- int suma = c0[x] * -1 + c1[x] * -1 + c2[x] * -1 + +- c6[x] * 1 + c7[x] * 1 + c8[x] * 1; +- int sumb = c0[x] * -1 + c2[x] * 1 + c3[x] * -1 + +- c5[x] * 1 + c6[x] * -1 + c8[x] * 1; ++ float suma = c0[x] * -1 + c1[x] * -1 + c2[x] * -1 + ++ c6[x] * 1 + c7[x] * 1 + c8[x] * 1; ++ float sumb = c0[x] * -1 + c2[x] * 1 + c3[x] * -1 + ++ c5[x] * 1 + c6[x] * -1 + c8[x] * 1; + + dst[x] = av_clip_uint8(sqrtf(suma*suma + sumb*sumb) * scale + delta); + } +@@ -223,8 +223,8 @@ static void filter_roberts(uint8_t *dst, int width, + int x; + + for (x = 0; x < width; x++) { +- int suma = c[0][x] * 1 + c[1][x] * -1; +- int sumb = c[4][x] * 1 + c[3][x] * -1; ++ float suma = c[0][x] * 1 + c[1][x] * -1; ++ float sumb = c[4][x] * 1 + c[3][x] * -1; + + dst[x] = av_clip_uint8(sqrtf(suma*suma + sumb*sumb) * scale + delta); + } +@@ -241,10 +241,11 @@ static void filter_sobel(uint8_t *dst, int width, + int x; + + for (x = 0; x < width; x++) { +- int suma = c0[x] * -1 + c1[x] * -2 + c2[x] * -1 + +- c6[x] * 1 + c7[x] * 2 + c8[x] * 1; +- int sumb = c0[x] * -1 + c2[x] * 1 + c3[x] * -2 + +- c5[x] * 2 + c6[x] * -1 + c8[x] * 1; ++ float suma = c0[x] * -1 + c1[x] * -2 + c2[x] * -1 + ++ c6[x] * 1 + c7[x] * 2 + c8[x] * 1; ++ float sumb = c0[x] * -1 + c2[x] * 1 + c3[x] * -2 + ++ c5[x] * 2 + c6[x] * -1 + c8[x] * 1; ++ + + dst[x] = av_clip_uint8(sqrtf(suma*suma + sumb*sumb) * scale + delta); + } +diff --git a/libavfilter/vf_fieldmatch.c b/libavfilter/vf_fieldmatch.c +index 5a73eb4..8d1e68b 100644 +--- a/libavfilter/vf_fieldmatch.c ++++ b/libavfilter/vf_fieldmatch.c +@@ -938,7 +938,7 @@ static int config_input(AVFilterLink *inlink) + fm->tpitchy = FFALIGN(w, 16); + fm->tpitchuv = FFALIGN(w >> 1, 16); + +- fm->tbuffer = av_malloc(h/2 * fm->tpitchy); ++ fm->tbuffer = av_calloc((h/2 + 4) * fm->tpitchy, sizeof(*fm->tbuffer)); + fm->c_array = av_malloc((((w + fm->blockx/2)/fm->blockx)+1) * + (((h + fm->blocky/2)/fm->blocky)+1) * + 4 * sizeof(*fm->c_array)); +diff --git a/libavfilter/vf_tile.c b/libavfilter/vf_tile.c +index 439689a..5a56f1b 100644 +--- a/libavfilter/vf_tile.c ++++ b/libavfilter/vf_tile.c +@@ -261,7 +261,7 @@ static int request_frame(AVFilterLink *outlink) + static av_cold void uninit(AVFilterContext *ctx) + { + TileContext *tile = ctx->priv; +- ++ av_frame_free(&tile->out_ref); + av_frame_free(&tile->prev_out_ref); + } + +diff --git a/libavformat/movenc.c b/libavformat/movenc.c +index d0bd182..1eee034 100644 +--- a/libavformat/movenc.c ++++ b/libavformat/movenc.c +@@ -1551,6 +1551,10 @@ static int mov_get_rawvideo_codec_tag(AVFormatContext *s, MOVTrack *track) + static unsigned int mov_get_codec_tag(AVFormatContext *s, MOVTrack *track) + { + unsigned int tag = track->par->codec_tag; ++ // "rtp " is used to distinguish internally created RTP-hint tracks ++ // (with rtp_ctx) from other tracks. ++ if (tag == MKTAG('r','t','p',' ')) ++ tag = 0; + + if (!tag || (s->strict_std_compliance >= FF_COMPLIANCE_NORMAL && + (track->par->codec_id == AV_CODEC_ID_DVVIDEO || +diff --git a/libavformat/mpegenc.c b/libavformat/mpegenc.c +index 789431a..7cbbbd5 100644 +--- a/libavformat/mpegenc.c ++++ b/libavformat/mpegenc.c +@@ -48,9 +48,9 @@ typedef struct StreamInfo { + uint8_t id; + int max_buffer_size; /* in bytes */ + int buffer_index; +- PacketDesc *predecode_packet; ++ PacketDesc *predecode_packet; /* start of packet queue */ ++ PacketDesc *last_packet; /* end of packet queue */ + PacketDesc *premux_packet; +- PacketDesc **next_packet; + int packet_number; + uint8_t lpcm_header[3]; + int lpcm_align; +@@ -986,6 +986,9 @@ static int remove_decoded_packets(AVFormatContext *ctx, int64_t scr) + } + stream->buffer_index -= pkt_desc->size; + stream->predecode_packet = pkt_desc->next; ++ if (!stream->predecode_packet) ++ stream->last_packet = NULL; ++ + av_freep(&pkt_desc); + } + } +@@ -1177,12 +1180,17 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) + av_log(ctx, AV_LOG_TRACE, "dts:%f pts:%f flags:%d stream:%d nopts:%d\n", + dts / 90000.0, pts / 90000.0, pkt->flags, + pkt->stream_index, pts != AV_NOPTS_VALUE); +- if (!stream->premux_packet) +- stream->next_packet = &stream->premux_packet; +- *stream->next_packet = + pkt_desc = av_mallocz(sizeof(PacketDesc)); + if (!pkt_desc) + return AVERROR(ENOMEM); ++ if (!stream->predecode_packet) { ++ stream->predecode_packet = pkt_desc; ++ } else ++ stream->last_packet->next = pkt_desc; ++ stream->last_packet = pkt_desc; ++ if (!stream->premux_packet) ++ stream->premux_packet = pkt_desc; ++ + pkt_desc->pts = pts; + pkt_desc->dts = dts; + +@@ -1200,9 +1208,6 @@ static int mpeg_mux_write_packet(AVFormatContext *ctx, AVPacket *pkt) + + pkt_desc->unwritten_size = + pkt_desc->size = size; +- if (!stream->predecode_packet) +- stream->predecode_packet = pkt_desc; +- stream->next_packet = &pkt_desc->next; + + if (av_fifo_realloc2(stream->fifo, av_fifo_size(stream->fifo) + size) < 0) + return -1; +-- +2.43.0 + -- Gitee