diff --git a/CVE-2024-5197.patch b/CVE-2024-5197.patch new file mode 100644 index 0000000000000000000000000000000000000000..0bd31a10a3fcbc1cb619a25622ad1f2b09f7c175 --- /dev/null +++ b/CVE-2024-5197.patch @@ -0,0 +1,249 @@ +From 6ba689e5f906b0038b0e4af3947f21bfc21edbf5 Mon Sep 17 00:00:00 2001 +From: pangqing +Date: Fri, 20 Sep 2024 14:53:59 +0800 +Subject: [PATCH] CVE-2024-5197 + +--- + test/test.mk | 1 + + test/vpx_image_test.cc | 72 ++++++++++++++++++++++++++++++++++++++++++ + vpx/src/vpx_image.c | 43 ++++++++++++++++++------- + vpx/vpx_image.h | 16 +++++++--- + 4 files changed, 115 insertions(+), 17 deletions(-) + create mode 100644 test/vpx_image_test.cc + +diff --git a/test/test.mk b/test/test.mk +index 6df4572..f2566dd 100644 +--- a/test/test.mk ++++ b/test/test.mk +@@ -19,6 +19,7 @@ LIBVPX_TEST_SRCS-yes += video_source.h + ## Black box tests only use the public API. + ## + LIBVPX_TEST_SRCS-yes += ../md5_utils.h ../md5_utils.c ++LIBVPX_TEST_SRCS-yes += vpx_image_test.cc + LIBVPX_TEST_SRCS-$(CONFIG_DECODERS) += ivf_video_source.h + LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += ../y4minput.h ../y4minput.c + LIBVPX_TEST_SRCS-$(CONFIG_ENCODERS) += altref_test.cc +diff --git a/test/vpx_image_test.cc b/test/vpx_image_test.cc +new file mode 100644 +index 0000000..113353c +--- /dev/null ++++ b/test/vpx_image_test.cc +@@ -0,0 +1,72 @@ ++/* ++ * Copyright (c) 2024 The WebM project authors. All Rights Reserved. ++ * ++ * Use of this source code is governed by a BSD-style license ++ * that can be found in the LICENSE file in the root of the source ++ * tree. An additional intellectual property rights grant can be found ++ * in the file PATENTS. All contributing project authors may ++ * be found in the AUTHORS file in the root of the source tree. ++ */ ++ ++#include "vpx/vpx_image.h" ++#include "third_party/googletest/src/include/gtest/gtest.h" ++ ++TEST(VpxImageTest, VpxImgWrapInvalidAlign) { ++ const int kWidth = 128; ++ const int kHeight = 128; ++ unsigned char buf[kWidth * kHeight * 3]; ++ ++ vpx_image_t img; ++ // Set img_data and img_data_owner to junk values. vpx_img_wrap() should ++ // not read these values on failure. ++ unsigned char empty[] = ""; ++ img.img_data = empty; ++ img.img_data_owner = 1; ++ ++ vpx_img_fmt_t format = VPX_IMG_FMT_I444; ++ // 'align' must be a power of 2 but is not. This causes the vpx_img_wrap() ++ // call to fail. The test verifies we do not read the junk values in 'img'. ++ unsigned int align = 31; ++ EXPECT_EQ(vpx_img_wrap(&img, format, kWidth, kHeight, align, buf), nullptr); ++} ++ ++TEST(VpxImageTest, VpxImgSetRectOverflow) { ++ const int kWidth = 128; ++ const int kHeight = 128; ++ unsigned char buf[kWidth * kHeight * 3]; ++ ++ vpx_image_t img; ++ vpx_img_fmt_t format = VPX_IMG_FMT_I444; ++ unsigned int align = 32; ++ EXPECT_EQ(vpx_img_wrap(&img, format, kWidth, kHeight, align, buf), &img); ++ ++ EXPECT_EQ(vpx_img_set_rect(&img, 0, 0, kWidth, kHeight), 0); ++ // This would result in overflow because -1 is cast to UINT_MAX. ++ EXPECT_NE(vpx_img_set_rect(&img, static_cast(-1), ++ static_cast(-1), kWidth, kHeight), ++ 0); ++} ++ ++TEST(VpxImageTest, VpxImgAllocNone) { ++ const int kWidth = 128; ++ const int kHeight = 128; ++ ++ vpx_image_t img; ++ vpx_img_fmt_t format = VPX_IMG_FMT_NONE; ++ unsigned int align = 32; ++ ASSERT_EQ(vpx_img_alloc(&img, format, kWidth, kHeight, align), nullptr); ++} ++ ++TEST(VpxImageTest, VpxImgAllocNv12) { ++ const int kWidth = 128; ++ const int kHeight = 128; ++ ++ vpx_image_t img; ++ vpx_img_fmt_t format = VPX_IMG_FMT_NV12; ++ unsigned int align = 32; ++ EXPECT_EQ(vpx_img_alloc(&img, format, kWidth, kHeight, align), &img); ++ EXPECT_EQ(img.stride[VPX_PLANE_U], img.stride[VPX_PLANE_Y]); ++ EXPECT_EQ(img.stride[VPX_PLANE_V], img.stride[VPX_PLANE_U]); ++ EXPECT_EQ(img.planes[VPX_PLANE_V], img.planes[VPX_PLANE_U] + 1); ++ vpx_img_free(&img); ++} +diff --git a/vpx/src/vpx_image.c b/vpx/src/vpx_image.c +index f9f0dd6..fc6ff72 100644 +--- a/vpx/src/vpx_image.c ++++ b/vpx/src/vpx_image.c +@@ -8,6 +8,7 @@ + * be found in the AUTHORS file in the root of the source tree. + */ + ++#include + #include + #include + #include +@@ -21,12 +22,21 @@ static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt, + unsigned int buf_align, + unsigned int stride_align, + unsigned char *img_data) { +- unsigned int h, w, s, xcs, ycs, bps; +- unsigned int stride_in_bytes; ++ unsigned int h, w, xcs, ycs, bps; ++ uint64_t s; ++ int stride_in_bytes; + unsigned int align; + + if (img != NULL) memset(img, 0, sizeof(vpx_image_t)); + ++ /* Impose maximum values on input parameters so that this function can ++ * perform arithmetic operations without worrying about overflows. ++ */ ++ if (d_w > 0x08000000 || d_h > 0x08000000 || buf_align > 65536 || ++ stride_align > 65536) { ++ goto fail; ++ } ++ + /* Treat align==0 like align==1 */ + if (!buf_align) buf_align = 1; + +@@ -80,9 +90,12 @@ static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt, + * and height shouldn't be adjusted. */ + w = d_w; + h = d_h; +- s = (fmt & VPX_IMG_FMT_PLANAR) ? w : bps * w / 8; +- s = (s + stride_align - 1) & ~(stride_align - 1); +- stride_in_bytes = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s * 2 : s; ++ s = (fmt & VPX_IMG_FMT_PLANAR) ? w : (uint64_t)bps * w / 8; ++ s = (s + stride_align - 1) & ~((uint64_t)stride_align - 1); ++ s = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s * 2 : s; ++ if (s > INT_MAX) goto fail; ++ stride_in_bytes = (int)s; ++ s = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s / 2 : s; + + /* Allocate the new image */ + if (!img) { +@@ -100,12 +113,16 @@ static vpx_image_t *img_alloc_helper(vpx_image_t *img, vpx_img_fmt_t fmt, + /* Calculate storage sizes given the chroma subsampling */ + align = (1 << xcs) - 1; + w = (d_w + align) & ~align; ++ assert(d_w <= w); + align = (1 << ycs) - 1; + h = (d_h + align) & ~align; ++ assert(d_h <= h); + +- s = (fmt & VPX_IMG_FMT_PLANAR) ? w : bps * w / 8; +- s = (s + stride_align - 1) & ~(stride_align - 1); +- stride_in_bytes = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s * 2 : s; ++ s = (fmt & VPX_IMG_FMT_PLANAR) ? w : (uint64_t)bps * w / 8; ++ s = (s + stride_align - 1) & ~((uint64_t)stride_align - 1); ++ s = (fmt & VPX_IMG_FMT_HIGHBITDEPTH) ? s * 2 : s; ++ if (s > INT_MAX) goto fail; ++ stride_in_bytes = (int)s; + alloc_size = (fmt & VPX_IMG_FMT_PLANAR) ? (uint64_t)h * s * bps / 8 + : (uint64_t)h * s; + +@@ -170,12 +187,12 @@ int vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y, + if (img->fmt & VPX_IMG_FMT_HAS_ALPHA) { + img->planes[VPX_PLANE_ALPHA] = + data + x * bytes_per_sample + y * img->stride[VPX_PLANE_ALPHA]; +- data += img->h * img->stride[VPX_PLANE_ALPHA]; ++ data += (size_t)img->h * img->stride[VPX_PLANE_ALPHA]; + } + + img->planes[VPX_PLANE_Y] = + data + x * bytes_per_sample + y * img->stride[VPX_PLANE_Y]; +- data += img->h * img->stride[VPX_PLANE_Y]; ++ data += (size_t)img->h * img->stride[VPX_PLANE_Y]; + + if (img->fmt == VPX_IMG_FMT_NV12) { + img->planes[VPX_PLANE_U] = +@@ -186,7 +203,8 @@ int vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y, + img->planes[VPX_PLANE_U] = + data + (x >> img->x_chroma_shift) * bytes_per_sample + + (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U]; +- data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_U]; ++ data += ++ (size_t)(img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_U]; + img->planes[VPX_PLANE_V] = + data + (x >> img->x_chroma_shift) * bytes_per_sample + + (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V]; +@@ -194,7 +212,8 @@ int vpx_img_set_rect(vpx_image_t *img, unsigned int x, unsigned int y, + img->planes[VPX_PLANE_V] = + data + (x >> img->x_chroma_shift) * bytes_per_sample + + (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_V]; +- data += (img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_V]; ++ data += ++ (size_t)(img->h >> img->y_chroma_shift) * img->stride[VPX_PLANE_V]; + img->planes[VPX_PLANE_U] = + data + (x >> img->x_chroma_shift) * bytes_per_sample + + (y >> img->y_chroma_shift) * img->stride[VPX_PLANE_U]; +diff --git a/vpx/vpx_image.h b/vpx/vpx_image.h +index 1adc9b9..2c30a89 100644 +--- a/vpx/vpx_image.h ++++ b/vpx/vpx_image.h +@@ -132,10 +132,13 @@ typedef struct vpx_image_rect { + * is NULL, the storage for the descriptor will be + * allocated on the heap. + * \param[in] fmt Format for the image +- * \param[in] d_w Width of the image +- * \param[in] d_h Height of the image ++ * \param[in] d_w Width of the image. Must not exceed 0x08000000 ++ * (2^27). ++ * \param[in] d_h Height of the image. Must not exceed 0x08000000 ++ * (2^27). + * \param[in] align Alignment, in bytes, of the image buffer and +- * each row in the image(stride). ++ * each row in the image (stride). Must not exceed ++ * 65536. + * + * \return Returns a pointer to the initialized image descriptor. If the img + * parameter is non-null, the value of the img parameter will be +@@ -155,9 +158,12 @@ vpx_image_t *vpx_img_alloc(vpx_image_t *img, vpx_img_fmt_t fmt, + * parameter is NULL, the storage for the descriptor + * will be allocated on the heap. + * \param[in] fmt Format for the image +- * \param[in] d_w Width of the image +- * \param[in] d_h Height of the image ++ * \param[in] d_w Width of the image. Must not exceed 0x08000000 ++ * (2^27). ++ * \param[in] d_h Height of the image. Must not exceed 0x08000000 ++ * (2^27). + * \param[in] stride_align Alignment, in bytes, of each row in the image. ++ * Must not exceed 65536. + * \param[in] img_data Storage to use for the image + * + * \return Returns a pointer to the initialized image descriptor. If the img +-- +2.39.3 + diff --git a/libvpx.spec b/libvpx.spec index c3cf1e16eb168e74365bf5ac4acb20a9508e5b48..7629f55e11775b6e9d4169f20a55536d19235924 100644 --- a/libvpx.spec +++ b/libvpx.spec @@ -1,4 +1,4 @@ -%define anolis_release 3 +%define anolis_release 4 %global somajor 7 %global sominor 0 %global sotiny 0 @@ -25,6 +25,7 @@ Source1: vpx_config.h Source2: libvpx.ver Patch0: CVE-2023-5217.patch Patch1: CVE-2023-44488.patch +Patch2: CVE-2024-5197.patch BuildRequires: make gcc gcc-c++ yasm doxygen php-cli perl(Getopt::Long) @@ -127,6 +128,9 @@ rm -rf %{buildroot}%{_prefix}/src %doc AUTHORS CHANGELOG README %changelog +* Fri Sep 20 2024 pangqing - 1.12.0-4 +- Fix CVE-2024-5197 + * Fri Sep 29 2023 Funda Wang - 1.12.0-3 - Fix CVE-2023-5217 & CVE-2023-44488