diff --git a/ffmpeg.spec b/ffmpeg.spec index f277d8c..33b017d 100644 --- a/ffmpeg.spec +++ b/ffmpeg.spec @@ -61,7 +61,7 @@ ExclusiveArch: armv7hnl Summary: Digital VCR and streaming server Name: ffmpeg%{?flavor} Version: 4.2.4 -Release: 12 +Release: 13 License: %{ffmpeg_license} URL: http://ffmpeg.org/ %if 0%{?date} @@ -83,6 +83,7 @@ Patch10: CVE-2022-3109.patch Patch11: fix-CVE-2023-51793.patch Patch12: fix-CVE-2023-50010.patch Patch13: CVE-2021-38171.patch +Patch14: fix-CVE-2024-31585.patch Requires: %{name}-libs%{?_isa} = %{version}-%{release} %{?_with_cuda:BuildRequires: cuda-minimal-build-%{_cuda_version_rpm} cuda-drivers-devel} %{?_with_libnpp:BuildRequires: pkgconfig(nppc-%{_cuda_version})} @@ -415,6 +416,9 @@ install -pm755 tools/qt-faststart %{buildroot}%{_bindir} %changelog +* Thu Jul 3 2024 happyworker <208suo@208suo.com> - 4.2.4-13 +- Fix CVE-2024-31585 + * Tue Jul 2 2024 happyworker <208suo@208suo.com> - 4.2.4-12 - Fix CVE-2021-38171 diff --git a/fix-CVE-2024-31585.patch b/fix-CVE-2024-31585.patch new file mode 100644 index 0000000..8e6d172 --- /dev/null +++ b/fix-CVE-2024-31585.patch @@ -0,0 +1,362 @@ +From 16c21017a90ff2874eb3fbeb1a4d2263f5eac601 Mon Sep 17 00:00:00 2001 +From: Michael Niedermayer +Date: Mon, 1 Jul 2024 16:59:03 +0800 +Subject: [PATCH] fix CVE-2024-31585 + +--- + libavfilter/avf_showspectrum.c | 201 +++++++++++++++++++-------------- + 1 file changed, 116 insertions(+), 85 deletions(-) + +diff --git a/libavfilter/avf_showspectrum.c b/libavfilter/avf_showspectrum.c +index f175bf1..5db5535 100644 +--- a/libavfilter/avf_showspectrum.c ++++ b/libavfilter/avf_showspectrum.c +@@ -29,7 +29,6 @@ + #include + + #include "libavcodec/avfft.h" +-#include "libavutil/audio_fifo.h" + #include "libavutil/avassert.h" + #include "libavutil/avstring.h" + #include "libavutil/channel_layout.h" +@@ -51,6 +50,8 @@ enum ColorMode { CHANNEL, INTENSITY, RAINBOW, MORELAND, NEBULAE, FIRE, FIERY, + enum SlideMode { REPLACE, SCROLL, FULLFRAME, RSCROLL, NB_SLIDES }; + enum Orientation { VERTICAL, HORIZONTAL, NB_ORIENTATIONS }; + ++#define DEFAULT_LENGTH 300 ++ + typedef struct ShowSpectrumContext { + const AVClass *class; + int w, h; +@@ -58,6 +59,7 @@ typedef struct ShowSpectrumContext { + AVRational auto_frame_rate; + AVRational frame_rate; + AVFrame *outpicref; ++ AVFrame *in_frame; + int nb_display_channels; + int orientation; + int channel_width; +@@ -90,14 +92,17 @@ typedef struct ShowSpectrumContext { + int hop_size; + float *combine_buffer; ///< color combining buffer (3 * h items) + float **color_buffer; ///< color buffer (3 * h * ch items) +- AVAudioFifo *fifo; + int64_t pts; + int64_t old_pts; + int old_len; + int single_pic; + int legend; + int start_x, start_y; ++ uint64_t samples; + int (*plot_channel)(AVFilterContext *ctx, void *arg, int jobnr, int nb_jobs); ++ AVFrame **frames; ++ unsigned int nb_frames; ++ unsigned int frames_size; + } ShowSpectrumContext; + + #define OFFSET(x) offsetof(ShowSpectrumContext, x) +@@ -335,12 +340,19 @@ static av_cold void uninit(AVFilterContext *ctx) + } + av_freep(&s->magnitudes); + av_frame_free(&s->outpicref); +- av_audio_fifo_free(s->fifo); ++ av_frame_free(&s->in_frame); + if (s->phases) { + for (i = 0; i < s->nb_display_channels; i++) + av_freep(&s->phases[i]); + } + av_freep(&s->phases); ++ ++ while (s->nb_frames > 0) { ++ av_frame_free(&s->frames[s->nb_frames - 1]); ++ s->nb_frames--; ++ } ++ ++ av_freep(&s->frames); + } + + static int query_formats(AVFilterContext *ctx) +@@ -385,10 +397,18 @@ static int run_channel_fft(AVFilterContext *ctx, void *arg, int jobnr, int nb_jo + + /* fill FFT input with the number of samples available */ + const float *p = (float *)fin->extended_data[ch]; ++ ++ float *in_frame = (float *)s->in_frame->extended_data[ch]; ++ ++ memmove(in_frame, in_frame + s->hop_size, (s->fft_size - s->hop_size) * sizeof(float)); ++ memcpy(in_frame + s->fft_size - s->hop_size, p, fin->nb_samples * sizeof(float)); ++ ++ for (int i = fin->nb_samples; i < s->hop_size; i++) ++ in_frame[i + s->fft_size - s->hop_size] = 0.f; + + for (n = 0; n < s->win_size; n++) { +- s->fft_data[ch][n].re = p[n] * window_func_lut[n]; +- s->fft_data[ch][n].im = 0; ++ s->fft_data[ch][n].re = in_frame[n] * window_func_lut[n]; ++ s->fft_data[ch][n].im = 0; + } + + if (s->stop) { +@@ -679,7 +699,7 @@ static float bin_pos(const int bin, const int num_bins, const float sample_rate) + return num_bins * scaled_freq / max_freq; + } + +-static int draw_legend(AVFilterContext *ctx, int samples) ++static int draw_legend(AVFilterContext *ctx, uint64_t samples) + { + ShowSpectrumContext *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; +@@ -1188,10 +1208,14 @@ static int config_output(AVFilterLink *outlink) + + av_log(ctx, AV_LOG_VERBOSE, "s:%dx%d FFT window size:%d\n", + s->w, s->h, s->win_size); ++ ++ s->in_frame = ff_get_audio_buffer(inlink, s->win_size); ++ if (!s->in_frame) ++ return AVERROR(ENOMEM); + +- av_audio_fifo_free(s->fifo); +- s->fifo = av_audio_fifo_alloc(inlink->format, inlink->channels, s->win_size); +- if (!s->fifo) ++ s->frames = av_fast_realloc(NULL, &s->frames_size, ++ DEFAULT_LENGTH * sizeof(*(s->frames))); ++ if (!s->frames) + return AVERROR(ENOMEM); + return 0; + } +@@ -1349,8 +1373,7 @@ static int plot_spectrum_column(AVFilterLink *inlink, AVFrame *insamples) + } + + if (s->sliding != FULLFRAME || s->xpos == 0) +- outpicref->pts = av_rescale_q(insamples->pts, inlink->time_base, outlink->time_base); +- ++ s->pts = outpicref->pts = av_rescale_q(insamples->pts, inlink->time_base, outlink->time_base); + s->xpos++; + if (s->orientation == VERTICAL && s->xpos >= s->w) + s->xpos = 0; +@@ -1401,61 +1424,43 @@ static int activate(AVFilterContext *ctx) + AVFilterLink *inlink = ctx->inputs[0]; + AVFilterLink *outlink = ctx->outputs[0]; + ShowSpectrumContext *s = ctx->priv; +- int ret; ++ int ret, status; ++ int64_t pts; ++ + + FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); + +- if (av_audio_fifo_size(s->fifo) < s->win_size) { +- AVFrame *frame = NULL; ++ if (s->outpicref) { ++ AVFrame *fin; ++ + +- ret = ff_inlink_consume_frame(inlink, &frame); ++ ret = ff_inlink_consume_samples(inlink, s->hop_size, s->hop_size, &fin); + if (ret < 0) + return ret; + if (ret > 0) { +- s->pts = frame->pts; +- s->consumed = 0; +- +- av_audio_fifo_write(s->fifo, (void **)frame->extended_data, frame->nb_samples); +- av_frame_free(&frame); +- } +- } +- +- if (s->outpicref && av_audio_fifo_size(s->fifo) >= s->win_size) { +- AVFrame *fin = ff_get_audio_buffer(inlink, s->win_size); +- if (!fin) +- return AVERROR(ENOMEM); +- +- fin->pts = s->pts + s->consumed; +- s->consumed += s->hop_size; +- ret = av_audio_fifo_peek(s->fifo, (void **)fin->extended_data, +- FFMIN(s->win_size, av_audio_fifo_size(s->fifo))); +- if (ret < 0) { +- av_frame_free(&fin); +- return ret; ++ s->consumed += fin->nb_samples; ++ ff_filter_execute(ctx, run_channel_fft, fin, NULL, s->nb_display_channels); ++ ++ if (s->data == D_MAGNITUDE) ++ ff_filter_execute(ctx, calc_channel_magnitudes, NULL, NULL, s->nb_display_channels); ++ ++ if (s->data == D_PHASE) ++ ff_filter_execute(ctx, calc_channel_phases, NULL, NULL, s->nb_display_channels); ++ ++ if (s->data == D_UPHASE) ++ ff_filter_execute(ctx, calc_channel_uphases, NULL, NULL, s->nb_display_channels); ++ ++ ret = plot_spectrum_column(inlink, fin); ++ av_frame_free(&fin); ++ if (ret <= 0) ++ return ret; + } + +- av_assert0(fin->nb_samples == s->win_size); +- +- ctx->internal->execute(ctx, run_channel_fft, fin, NULL, s->nb_display_channels); +- +- if (s->data == D_MAGNITUDE) +- ctx->internal->execute(ctx, calc_channel_magnitudes, NULL, NULL, s->nb_display_channels); +- +- if (s->data == D_PHASE) +- ctx->internal->execute(ctx, calc_channel_phases, NULL, NULL, s->nb_display_channels); +- +- ret = plot_spectrum_column(inlink, fin); +- +- av_frame_free(&fin); +- av_audio_fifo_drain(s->fifo, s->hop_size); +- if (ret <= 0) +- return ret; + } + + if (ff_outlink_get_status(inlink) == AVERROR_EOF && + s->sliding == FULLFRAME && + s->xpos > 0 && s->outpicref) { +- int64_t pts; + + if (s->orientation == VERTICAL) { + for (int i = 0; i < outlink->h; i++) { +@@ -1478,17 +1483,20 @@ static int activate(AVFilterContext *ctx) + return 0; + } + +- FF_FILTER_FORWARD_STATUS(inlink, outlink); +- if (ff_outlink_frame_wanted(outlink) && av_audio_fifo_size(s->fifo) < s->win_size) { +- ff_inlink_request_frame(inlink); +- return 0; ++ if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { ++ if (status == AVERROR_EOF) { ++ ff_outlink_set_status(outlink, status, s->pts); ++ return 0; ++ } + } + +- if (av_audio_fifo_size(s->fifo) >= s->win_size) { +- ff_filter_set_ready(ctx, 10); ++ if (ff_inlink_queued_samples(inlink) >= s->hop_size) { ++ ff_filter_set_ready(ctx, 10); + return 0; + } +- return FFERROR_NOT_READY; ++ if (ff_outlink_frame_wanted(outlink)) { ++ ff_inlink_request_frame(inlink); ++ return 0; + } + + static const AVFilterPad showspectrum_inputs[] = { +@@ -1597,40 +1605,54 @@ static int showspectrumpic_request_frame(AVFilterLink *outlink) + AVFilterContext *ctx = outlink->src; + ShowSpectrumContext *s = ctx->priv; + AVFilterLink *inlink = ctx->inputs[0]; +- int ret, samples; ++ int ret; + + ret = ff_request_frame(inlink); +- samples = av_audio_fifo_size(s->fifo); +- if (ret == AVERROR_EOF && s->outpicref && samples > 0) { +- int consumed = 0; ++ if (ret == AVERROR_EOF && s->outpicref && s->samples > 0) { ++ int consumed = 0; + int x = 0, sz = s->orientation == VERTICAL ? s->w : s->h; ++ unsigned int nb_frame = 0; + int ch, spf, spb; ++ int src_offset = 0; + AVFrame *fin; + +- spf = s->win_size * (samples / ((s->win_size * sz) * ceil(samples / (float)(s->win_size * sz)))); +- spf = FFMAX(1, spf); +- +- spb = (samples / (spf * sz)) * spf; ++ spf = s->win_size * (s->samples / ((s->win_size * sz) * ceil(s->samples / (float)(s->win_size * sz)))); ++ spf = FFMAX(1, spf); + +- fin = ff_get_audio_buffer(inlink, s->win_size); +- if (!fin) ++ spb = (s->samples / (spf * sz)) * spf; ++ ++ fin = ff_get_audio_buffer(inlink, spf); ++ if (!fin) + return AVERROR(ENOMEM); + + while (x < sz) { +- ret = av_audio_fifo_peek(s->fifo, (void **)fin->extended_data, s->win_size); +- if (ret < 0) { +- av_frame_free(&fin); +- return ret; +- } + +- av_audio_fifo_drain(s->fifo, spf); ++ int acc_samples = 0; ++ int dst_offset = 0; ++ ++ while (nb_frame < s->nb_frames) { ++ AVFrame *cur_frame = s->frames[nb_frame]; ++ int cur_frame_samples = cur_frame->nb_samples; ++ int nb_samples = 0; + +- if (ret < s->win_size) { +- for (ch = 0; ch < s->nb_display_channels; ch++) { +- memset(fin->extended_data[ch] + ret * sizeof(float), 0, +- (s->win_size - ret) * sizeof(float)); ++ if (acc_samples < spf) { ++ nb_samples = FFMIN(spf - acc_samples, cur_frame_samples - src_offset); ++ acc_samples += nb_samples; ++ av_samples_copy(fin->extended_data, cur_frame->extended_data, ++ dst_offset, src_offset, nb_samples, ++ cur_frame->channels, AV_SAMPLE_FMT_FLTP); + } +- } ++ src_offset += nb_samples; ++ dst_offset += nb_samples; ++ if (cur_frame_samples <= src_offset) { ++ av_frame_free(&s->frames[nb_frame]); ++ nb_frame++; ++ src_offset = 0; ++ } ++ if (acc_samples == spf) ++ break; ++ ++ } + + ctx->internal->execute(ctx, run_channel_fft, fin, NULL, s->nb_display_channels); + acalc_magnitudes(s); +@@ -1652,7 +1674,7 @@ static int showspectrumpic_request_frame(AVFilterLink *outlink) + s->outpicref->pts = 0; + + if (s->legend) +- draw_legend(ctx, samples); ++ draw_legend(ctx, s->samples); + + ret = ff_filter_frame(outlink, s->outpicref); + s->outpicref = NULL; +@@ -1665,11 +1687,20 @@ static int showspectrumpic_filter_frame(AVFilterLink *inlink, AVFrame *insamples + { + AVFilterContext *ctx = inlink->dst; + ShowSpectrumContext *s = ctx->priv; +- int ret; ++ void *ptr; + +- ret = av_audio_fifo_write(s->fifo, (void **)insamples->extended_data, insamples->nb_samples); +- av_frame_free(&insamples); +- return ret; ++ if (s->nb_frames + 1ULL > s->frames_size / sizeof(*(s->frames))) { ++ ptr = av_fast_realloc(s->frames, &s->frames_size, s->frames_size * 2); ++ if (!ptr) ++ return AVERROR(ENOMEM); ++ s->frames = ptr; ++ } ++ ++ s->frames[s->nb_frames] = insamples; ++ s->samples += insamples->nb_samples; ++ s->nb_frames++; ++ ++ return 0; + } + + static const AVFilterPad showspectrumpic_inputs[] = { +-- +2.43.0 +