From 651f9ba2ddc09d36861b9a213bc88f89a8ad19e5f5648d22fade1c5e4fc2416b Mon Sep 17 00:00:00 2001 From: Jan Engelhardt Date: Tue, 7 May 2024 14:51:08 +0000 Subject: [PATCH] Accepting request 1172423 from home:qzhao:branches:multimedia:libs Add ffmpeg-Templatify-ff_gaussian_blur-and-ff-function.patch ffmpeg-CVE-2023-50010.patch ffmpeg-CVE-2023-50009.patch to fix CVE bugs. OBS-URL: https://build.opensuse.org/request/show/1172423 OBS-URL: https://build.opensuse.org/package/show/multimedia:libs/ffmpeg-5?expand=0&rev=91 --- ffmpeg-5.changes | 23 ++ ffmpeg-5.spec | 3 + ffmpeg-CVE-2023-50009.patch | 72 ++++ ffmpeg-CVE-2023-50010.patch | 28 ++ ...ify-ff_gaussian_blur-and-ff-function.patch | 310 ++++++++++++++++++ 5 files changed, 436 insertions(+) create mode 100644 ffmpeg-CVE-2023-50009.patch create mode 100644 ffmpeg-CVE-2023-50010.patch create mode 100644 ffmpeg-Templatify-ff_gaussian_blur-and-ff-function.patch diff --git a/ffmpeg-5.changes b/ffmpeg-5.changes index adad674..67a2a9b 100644 --- a/ffmpeg-5.changes +++ b/ffmpeg-5.changes @@ -1,3 +1,26 @@ +------------------------------------------------------------------- +Tue Apr 27 11:38:35 UTC 2024 - Cliff Zhao + +- Add ffmpeg-CVE-2023-50010.patch: + Backporting e4d2666b from upstream, fixes the out of array access. + (CVE-2023-50010 bsc#1223256) + +------------------------------------------------------------------- +Tue Apr 26 12:18:26 UTC 2024 - Cliff Zhao + +- Add ffmpeg-CVE-2023-50009.patch: + Backporting c443658d from upstream, Fix small inputs with + gaussian_blur(). + (CVE-2023-50009 bsc#1223255) + +------------------------------------------------------------------- +Tue Apr 24 10:48:32 UTC 2024 - Cliff Zhao + +- Add ffmpeg-Templatify-ff_gaussian_blur-and-ff-function.patch: + Backporting cf1f5744 from upstream, Templatify function + ff_gaussian_blur and ff_sobel to prepare fix support for CVE-2023-50009. + (CVE-2023-50009 bsc#1223255) + ------------------------------------------------------------------- Thu Apr 23 16:14:18 UTC 2024 - Cliff Zhao diff --git a/ffmpeg-5.spec b/ffmpeg-5.spec index 2deeee9..4d250d1 100644 --- a/ffmpeg-5.spec +++ b/ffmpeg-5.spec @@ -125,6 +125,9 @@ Patch94: ffmpeg-CVE-2023-50007.patch Patch95: ffmpeg-CVE-2023-50008.patch Patch96: ffmpeg-CVE-2023-49502.patch Patch97: ffmpeg-CVE-2023-51793.patch +Patch98: ffmpeg-Templatify-ff_gaussian_blur-and-ff-function.patch +Patch99: ffmpeg-CVE-2023-50009.patch +Patch100: ffmpeg-CVE-2023-50010.patch %if %{with amf_sdk} BuildRequires: AMF-devel %endif diff --git a/ffmpeg-CVE-2023-50009.patch b/ffmpeg-CVE-2023-50009.patch new file mode 100644 index 0000000..9f0e7f0 --- /dev/null +++ b/ffmpeg-CVE-2023-50009.patch @@ -0,0 +1,72 @@ +commit c443658d26d2b8e19901f9507a890e0efca79056 (HEAD -> 20231222_CVE-2023-50009_c443658d26d2b8e19901f9507a890e0efca79056) +Author: Michael Niedermayer +Date: Fri Dec 22 11:54:24 2023 +0100 + + avfilter/edge_template: Fix small inputs with gaussian_blur() + + Fixes: out of array access + Fixes: Ticket10699 + Fixes: poc5ffmpeg + + Found-by: Zeng Yunxiang + Signed-off-by: Michael Niedermayer + +diff --git a/libavfilter/edge_template.c b/libavfilter/edge_template.c +index 14635c25af..ce45e579db 100644 +--- a/libavfilter/edge_template.c ++++ b/libavfilter/edge_template.c +@@ -74,6 +74,7 @@ void fn(gaussian_blur)(int w, int h, + uint8_t *dst, int dst_linesize, + const uint8_t *src, int src_linesize, int src_stride) + { ++ int j; + pixel *srcp = (pixel *)src; + pixel *dstp = (pixel *)dst; + +@@ -81,12 +82,17 @@ void fn(gaussian_blur)(int w, int h, + src_linesize /= sizeof(pixel); + dst_linesize /= sizeof(pixel); + +- memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize; +- memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize; +- for (int j = 2; j < h - 2; j++) { +- dstp[0] = srcp[(0)*src_stride]; +- dstp[1] = srcp[(1)*src_stride]; +- for (int i = 2; i < w - 2; i++) { ++ for (j = 0; j < FFMIN(h, 2); j++) { ++ memcpy(dstp, srcp, w*sizeof(pixel)); ++ dstp += dst_linesize; ++ srcp += src_linesize; ++ } ++ ++ for (; j < h - 2; j++) { ++ int i; ++ for (i = 0; i < FFMIN(w, 2); i++) ++ dstp[i] = srcp[i*src_stride]; ++ for (; i < w - 2; i++) { + /* Gaussian mask of size 5x5 with sigma = 1.4 */ + dstp[i] = ((srcp[-2*src_linesize + (i-2)*src_stride] + srcp[2*src_linesize + (i-2)*src_stride]) * 2 + + (srcp[-2*src_linesize + (i-1)*src_stride] + srcp[2*src_linesize + (i-1)*src_stride]) * 4 +@@ -106,12 +112,15 @@ void fn(gaussian_blur)(int w, int h, + + srcp[(i+1)*src_stride] * 12 + + srcp[(i+2)*src_stride] * 5) / 159; + } +- dstp[w - 2] = srcp[(w - 2)*src_stride]; +- dstp[w - 1] = srcp[(w - 1)*src_stride]; ++ for (; i < w; i++) ++ dstp[i] = srcp[i*src_stride]; + + dstp += dst_linesize; + srcp += src_linesize; + } +- memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize; +- memcpy(dstp, srcp, w*sizeof(pixel)); ++ for (; j < h; j++) { ++ memcpy(dstp, srcp, w*sizeof(pixel)); ++ dstp += dst_linesize; ++ srcp += src_linesize; ++ } + } +-- +2.41.0 + diff --git a/ffmpeg-CVE-2023-50010.patch b/ffmpeg-CVE-2023-50010.patch new file mode 100644 index 0000000..d5934fc --- /dev/null +++ b/ffmpeg-CVE-2023-50010.patch @@ -0,0 +1,28 @@ +commit e4d2666bdc3dbd177a81bbf428654a5f2fa3787a (20231224_CVE-2023-50010_e4d2666bdc3dbd177a81bbf428654a5f2fa3787a) +Author: Michael Niedermayer +Date: Sun Dec 24 20:50:51 2023 +0100 + + avfilter/vf_gradfun: Do not overread last line + + The code works in steps of 2 lines and lacks support for odd height + Implementing odd height support is better but for now this fixes the + out of array access + + Fixes: out of array access + Fixes: tickets/10702/poc6ffmpe + + Found-by: Zeng Yunxiang + Signed-off-by: Michael Niedermayer + +diff -Nura ffmpeg-5.1.4/libavfilter/vf_gradfun.c ffmpeg-5.1.4_new/libavfilter/vf_gradfun.c +--- ffmpeg-5.1.4/libavfilter/vf_gradfun.c 2023-11-10 07:38:51.000000000 +0800 ++++ ffmpeg-5.1.4_new/libavfilter/vf_gradfun.c 2024-05-07 19:36:59.563277057 +0800 +@@ -92,7 +92,7 @@ + for (y = 0; y < r; y++) + ctx->blur_line(dc, buf + y * bstride, buf + (y - 1) * bstride, src + 2 * y * src_linesize, src_linesize, width / 2); + for (;;) { +- if (y < height - r) { ++ if (y + 1 < height - r) { + int mod = ((y + r) / 2) % r; + uint16_t *buf0 = buf + mod * bstride; + uint16_t *buf1 = buf + (mod ? mod - 1 : r - 1) * bstride; diff --git a/ffmpeg-Templatify-ff_gaussian_blur-and-ff-function.patch b/ffmpeg-Templatify-ff_gaussian_blur-and-ff-function.patch new file mode 100644 index 0000000..8abd0f3 --- /dev/null +++ b/ffmpeg-Templatify-ff_gaussian_blur-and-ff-function.patch @@ -0,0 +1,310 @@ +commit cf1f57443158bcbe84a213e8dc631a302993f9a2 +Author: Thilo Borgmann +Date: Mon Jul 18 16:09:46 2022 +0200 + + lavfi/edge_common: Templatify ff_gaussian_blur and ff_sobel + +diff --git a/libavfilter/edge_common.c b/libavfilter/edge_common.c +index d72e8521cd..ebd47d7c53 100644 +--- a/libavfilter/edge_common.c ++++ b/libavfilter/edge_common.c +@@ -46,33 +46,13 @@ static int get_rounded_direction(int gx, int gy) + return DIRECTION_VERTICAL; + } + +-// Simple sobel operator to get rounded gradients +-void ff_sobel(int w, int h, +- uint16_t *dst, int dst_linesize, +- int8_t *dir, int dir_linesize, +- const uint8_t *src, int src_linesize) +-{ +- int i, j; +- +- for (j = 1; j < h - 1; j++) { +- dst += dst_linesize; +- dir += dir_linesize; +- src += src_linesize; +- for (i = 1; i < w - 1; i++) { +- const int gx = +- -1*src[-src_linesize + i-1] + 1*src[-src_linesize + i+1] +- -2*src[ i-1] + 2*src[ i+1] +- -1*src[ src_linesize + i-1] + 1*src[ src_linesize + i+1]; +- const int gy = +- -1*src[-src_linesize + i-1] + 1*src[ src_linesize + i-1] +- -2*src[-src_linesize + i ] + 2*src[ src_linesize + i ] +- -1*src[-src_linesize + i+1] + 1*src[ src_linesize + i+1]; ++#undef DEPTH ++#define DEPTH 8 ++#include "edge_template.c" + +- dst[i] = FFABS(gx) + FFABS(gy); +- dir[i] = get_rounded_direction(gx, gy); +- } +- } +-} ++#undef DEPTH ++#define DEPTH 16 ++#include "edge_template.c" + + // Filters rounded gradients to drop all non-maxima + // Expects gradients generated by ff_sobel() +@@ -137,45 +117,3 @@ void ff_double_threshold(int low, int high, int w, int h, + src += src_linesize; + } + } +- +-// Applies gaussian blur, using 5x5 kernels, sigma = 1.4 +-void ff_gaussian_blur(int w, int h, +- uint8_t *dst, int dst_linesize, +- const uint8_t *src, int src_linesize) +-{ +- int i, j; +- +- memcpy(dst, src, w); dst += dst_linesize; src += src_linesize; +- memcpy(dst, src, w); dst += dst_linesize; src += src_linesize; +- for (j = 2; j < h - 2; j++) { +- dst[0] = src[0]; +- dst[1] = src[1]; +- for (i = 2; i < w - 2; i++) { +- /* Gaussian mask of size 5x5 with sigma = 1.4 */ +- dst[i] = ((src[-2*src_linesize + i-2] + src[2*src_linesize + i-2]) * 2 +- + (src[-2*src_linesize + i-1] + src[2*src_linesize + i-1]) * 4 +- + (src[-2*src_linesize + i ] + src[2*src_linesize + i ]) * 5 +- + (src[-2*src_linesize + i+1] + src[2*src_linesize + i+1]) * 4 +- + (src[-2*src_linesize + i+2] + src[2*src_linesize + i+2]) * 2 +- +- + (src[ -src_linesize + i-2] + src[ src_linesize + i-2]) * 4 +- + (src[ -src_linesize + i-1] + src[ src_linesize + i-1]) * 9 +- + (src[ -src_linesize + i ] + src[ src_linesize + i ]) * 12 +- + (src[ -src_linesize + i+1] + src[ src_linesize + i+1]) * 9 +- + (src[ -src_linesize + i+2] + src[ src_linesize + i+2]) * 4 +- +- + src[i-2] * 5 +- + src[i-1] * 12 +- + src[i ] * 15 +- + src[i+1] * 12 +- + src[i+2] * 5) / 159; +- } +- dst[i ] = src[i ]; +- dst[i + 1] = src[i + 1]; +- +- dst += dst_linesize; +- src += src_linesize; +- } +- memcpy(dst, src, w); dst += dst_linesize; src += src_linesize; +- memcpy(dst, src, w); +-} +diff --git a/libavfilter/edge_common.h b/libavfilter/edge_common.h +index 87c143f2b8..cff4febd70 100644 +--- a/libavfilter/edge_common.h ++++ b/libavfilter/edge_common.h +@@ -48,10 +48,14 @@ enum AVRoundedDirection { + * @param src data pointers to source image + * @param src_linesize linesizes for the source image + */ +-void ff_sobel(int w, int h, +- uint16_t *dst, int dst_linesize, +- int8_t *dir, int dir_linesize, +- const uint8_t *src, int src_linesize); ++#define PROTO_SOBEL(depth) \ ++void ff_sobel_##depth(int w, int h, \ ++ uint16_t *dst, int dst_linesize, \ ++ int8_t *dir, int dir_linesize, \ ++ const uint8_t *src, int src_linesize, int src_stride); ++ ++PROTO_SOBEL(8) ++PROTO_SOBEL(16) + + /** + * Filters rounded gradients to drop all non-maxima pixels in the magnitude image +@@ -100,8 +104,12 @@ void ff_double_threshold(int low, int high, int w, int h, + * @param src data pointers to source image + * @param src_linesize linesizes for the source image + */ +-void ff_gaussian_blur(int w, int h, +- uint8_t *dst, int dst_linesize, +- const uint8_t *src, int src_linesize); ++#define PROTO_GAUSSIAN_BLUR(depth) \ ++void ff_gaussian_blur_##depth(int w, int h, \ ++ uint8_t *dst, int dst_linesize, \ ++ const uint8_t *src, int src_linesize, int src_stride); ++ ++PROTO_GAUSSIAN_BLUR(8) ++PROTO_GAUSSIAN_BLUR(16) + + #endif +diff --git a/libavfilter/edge_template.c b/libavfilter/edge_template.c +new file mode 100644 +index 0000000000..af33c178af +--- /dev/null ++++ b/libavfilter/edge_template.c +@@ -0,0 +1,118 @@ ++/* ++ * Copyright (c) 2022 Thilo Borgmann ++ * ++ * This file is part of FFmpeg. ++ * ++ * FFmpeg is free software; you can redistribute it and/or ++ * modify it under the terms of the GNU Lesser General Public ++ * License as published by the Free Software Foundation; either ++ * version 2.1 of the License, or (at your option) any later version. ++ * ++ * FFmpeg is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ++ * Lesser General Public License for more details. ++ * ++ * You should have received a copy of the GNU Lesser General Public ++ * License along with FFmpeg; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ * Redistribution and use in source and binary forms, with or without modification, ++ * are permitted provided that the following conditions are met: ++ */ ++ ++#include "libavutil/avassert.h" ++#include "avfilter.h" ++#include "formats.h" ++#include "internal.h" ++#include "video.h" ++ ++#undef pixel ++#if DEPTH == 8 ++#define pixel uint8_t ++#else ++#define pixel uint16_t ++#endif ++ ++#undef fn ++#undef fn2 ++#undef fn3 ++#define fn3(a,b) ff_##a##_##b ++#define fn2(a,b) fn3(a,b) ++#define fn(a) fn2(a, DEPTH) ++ ++void fn(sobel)(int w, int h, ++ uint16_t *dst, int dst_linesize, ++ int8_t *dir, int dir_linesize, ++ const uint8_t *src, int src_linesize, int src_stride) ++{ ++ pixel *srcp = (pixel *)src; ++ ++ src_stride /= sizeof(pixel); ++ src_linesize /= sizeof(pixel); ++ dst_linesize /= sizeof(pixel); ++ ++ for (int j = 1; j < h - 1; j++) { ++ dst += dst_linesize; ++ dir += dir_linesize; ++ srcp += src_linesize; ++ for (int i = 1; i < w - 1; i++) { ++ const int gx = ++ -1*srcp[-src_linesize + (i-1)*src_stride] + 1*srcp[-src_linesize + (i+1)*src_stride] ++ -2*srcp[ (i-1)*src_stride] + 2*srcp[ (i+1)*src_stride] ++ -1*srcp[ src_linesize + (i-1)*src_stride] + 1*srcp[ src_linesize + (i+1)*src_stride]; ++ const int gy = ++ -1*srcp[-src_linesize + (i-1)*src_stride] + 1*srcp[ src_linesize + (i-1)*src_stride] ++ -2*srcp[-src_linesize + (i )*src_stride] + 2*srcp[ src_linesize + (i )*src_stride] ++ -1*srcp[-src_linesize + (i+1)*src_stride] + 1*srcp[ src_linesize + (i+1)*src_stride]; ++ ++ dst[i] = FFABS(gx) + FFABS(gy); ++ dir[i] = get_rounded_direction(gx, gy); ++ } ++ } ++} ++ ++void fn(gaussian_blur)(int w, int h, ++ uint8_t *dst, int dst_linesize, ++ const uint8_t *src, int src_linesize, int src_stride) ++{ ++ pixel *srcp = (pixel *)src; ++ pixel *dstp = (pixel *)dst; ++ ++ src_stride /= sizeof(pixel); ++ src_linesize /= sizeof(pixel); ++ dst_linesize /= sizeof(pixel); ++ ++ memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize; ++ memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize; ++ for (int j = 2; j < h - 2; j++) { ++ dstp[0] = srcp[(0)*src_stride]; ++ dstp[1] = srcp[(1)*src_stride]; ++ for (int i = 2; i < w - 2; i++) { ++ /* Gaussian mask of size 5x5 with sigma = 1.4 */ ++ dstp[i] = ((srcp[-2*src_linesize + (i-2)*src_stride] + srcp[2*src_linesize + (i-2)*src_stride]) * 2 ++ + (srcp[-2*src_linesize + (i-1)*src_stride] + srcp[2*src_linesize + (i-1)*src_stride]) * 4 ++ + (srcp[-2*src_linesize + (i )*src_stride] + srcp[2*src_linesize + (i )*src_stride]) * 5 ++ + (srcp[-2*src_linesize + (i+1)*src_stride] + srcp[2*src_linesize + (i+1)*src_stride]) * 4 ++ + (srcp[-2*src_linesize + (i+2)*src_stride] + srcp[2*src_linesize + (i+2)*src_stride]) * 2 ++ ++ + (srcp[ -src_linesize + (i-2)*src_stride] + srcp[ src_linesize + (i-2)*src_stride]) * 4 ++ + (srcp[ -src_linesize + (i-1)*src_stride] + srcp[ src_linesize + (i-1)*src_stride]) * 9 ++ + (srcp[ -src_linesize + (i )*src_stride] + srcp[ src_linesize + (i )*src_stride]) * 12 ++ + (srcp[ -src_linesize + (i+1)*src_stride] + srcp[ src_linesize + (i+1)*src_stride]) * 9 ++ + (srcp[ -src_linesize + (i+2)*src_stride] + srcp[ src_linesize + (i+2)*src_stride]) * 4 ++ ++ + srcp[(i-2)*src_stride] * 5 ++ + srcp[(i-1)*src_stride] * 12 ++ + srcp[(i )*src_stride] * 15 ++ + srcp[(i+1)*src_stride] * 12 ++ + srcp[(i+2)*src_stride] * 5) / 159; ++ } ++ dstp[w - 2] = srcp[(w - 2)*src_stride]; ++ dstp[w - 1] = srcp[(w - 1)*src_stride]; ++ ++ dstp += dst_linesize; ++ srcp += src_linesize; ++ } ++ memcpy(dstp, srcp, w*sizeof(pixel)); dstp += dst_linesize; srcp += src_linesize; ++ memcpy(dstp, srcp, w*sizeof(pixel)); ++} +diff --git a/libavfilter/vf_blurdetect.c b/libavfilter/vf_blurdetect.c +index 0e08ba96de..db06efcce7 100644 +--- a/libavfilter/vf_blurdetect.c ++++ b/libavfilter/vf_blurdetect.c +@@ -283,12 +283,12 @@ static int blurdetect_filter_frame(AVFilterLink *inlink, AVFrame *in) + nplanes++; + + // gaussian filter to reduce noise +- ff_gaussian_blur(w, h, +- filterbuf, w, +- in->data[plane], in->linesize[plane]); ++ ff_gaussian_blur_8(w, h, ++ filterbuf, w, ++ in->data[plane], in->linesize[plane], 1); + + // compute the 16-bits gradients and directions for the next step +- ff_sobel(w, h, gradients, w, directions, w, filterbuf, w); ++ ff_sobel_8(w, h, gradients, w, directions, w, filterbuf, w, 1); + + // non_maximum_suppression() will actually keep & clip what's necessary and + // ignore the rest, so we need a clean output buffer +diff --git a/libavfilter/vf_edgedetect.c b/libavfilter/vf_edgedetect.c +index 90390ceb3e..603f06f141 100644 +--- a/libavfilter/vf_edgedetect.c ++++ b/libavfilter/vf_edgedetect.c +@@ -191,15 +191,15 @@ static int filter_frame(AVFilterLink *inlink, AVFrame *in) + } + + /* gaussian filter to reduce noise */ +- ff_gaussian_blur(width, height, +- tmpbuf, width, +- in->data[p], in->linesize[p]); ++ ff_gaussian_blur_8(width, height, ++ tmpbuf, width, ++ in->data[p], in->linesize[p], 1); + + /* compute the 16-bits gradients and directions for the next step */ +- ff_sobel(width, height, +- gradients, width, +- directions,width, +- tmpbuf, width); ++ ff_sobel_8(width, height, ++ gradients, width, ++ directions,width, ++ tmpbuf, width, 1); + + /* non_maximum_suppression() will actually keep & clip what's necessary and + * ignore the rest, so we need a clean output buffer */ +-- +2.41.0 +