From 7aa94778c0bb43ef4c266e715a5a795e3ed00329 Mon Sep 17 00:00:00 2001 From: Sandro Mani Date: Sat, 29 Oct 2016 10:57:58 +0200 Subject: [PATCH] Backport e2affacc35f1df6cc3b1a9fa0ceff5ce2d0cce83 (CVE-2016-9085, rhbz#1389338) --- ...facc35f1df6cc3b1a9fa0ceff5ce2d0cce83.patch | 115 ++++++++++++++++++ libwebp.spec | 10 +- 2 files changed, 123 insertions(+), 2 deletions(-) create mode 100644 e2affacc35f1df6cc3b1a9fa0ceff5ce2d0cce83.patch diff --git a/e2affacc35f1df6cc3b1a9fa0ceff5ce2d0cce83.patch b/e2affacc35f1df6cc3b1a9fa0ceff5ce2d0cce83.patch new file mode 100644 index 0000000..69f271d --- /dev/null +++ b/e2affacc35f1df6cc3b1a9fa0ceff5ce2d0cce83.patch @@ -0,0 +1,115 @@ +diff -rupN libwebp-0.5.1/examples/gifdec.c libwebp-0.5.1-new/examples/gifdec.c +--- libwebp-0.5.1/examples/gifdec.c 2016-07-07 03:00:16.000000000 +0200 ++++ libwebp-0.5.1-new/examples/gifdec.c 2016-10-29 10:51:46.618791501 +0200 +@@ -20,6 +20,7 @@ + + #include "webp/encode.h" + #include "webp/mux_types.h" ++#include "webp/format_constants.h" + + #define GIF_TRANSPARENT_COLOR 0x00ffffff + #define GIF_WHITE_COLOR 0xffffffff +@@ -103,12 +104,19 @@ int GIFReadFrame(GifFileType* const gif, + const GifImageDesc* const image_desc = &gif->Image; + uint32_t* dst = NULL; + uint8_t* tmp = NULL; +- int ok = 0; +- GIFFrameRect rect = { ++ const GIFFrameRect rect = { + image_desc->Left, image_desc->Top, image_desc->Width, image_desc->Height + }; ++ const uint64_t memory_needed = 4 * rect.width * (uint64_t)rect.height; ++ int ok = 0; + *gif_rect = rect; + ++ if (memory_needed != (size_t)memory_needed || ++ memory_needed > 4 * MAX_IMAGE_AREA) { ++ fprintf(stderr, "Image is too large (%d x %d).", rect.width, rect.height); ++ return 0; ++ } ++ + // Use a view for the sub-picture: + if (!WebPPictureView(picture, rect.x_offset, rect.y_offset, + rect.width, rect.height, &sub_image)) { +@@ -132,15 +140,15 @@ int GIFReadFrame(GifFileType* const gif, + y += interlace_jumps[pass]) { + if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End; + Remap(gif, tmp, rect.width, transparent_index, +- dst + y * sub_image.argb_stride); ++ dst + y * (size_t)sub_image.argb_stride); + } + } + } else { // Non-interlaced image. + int y; +- for (y = 0; y < rect.height; ++y) { ++ uint32_t* ptr = dst; ++ for (y = 0; y < rect.height; ++y, ptr += sub_image.argb_stride) { + if (DGifGetLine(gif, tmp, rect.width) == GIF_ERROR) goto End; +- Remap(gif, tmp, rect.width, transparent_index, +- dst + y * sub_image.argb_stride); ++ Remap(gif, tmp, rect.width, transparent_index, ptr); + } + } + ok = 1; +@@ -216,13 +224,11 @@ int GIFReadMetadata(GifFileType* const g + + static void ClearRectangle(WebPPicture* const picture, + int left, int top, int width, int height) { +- int j; +- for (j = top; j < top + height; ++j) { +- uint32_t* const dst = picture->argb + j * picture->argb_stride; +- int i; +- for (i = left; i < left + width; ++i) { +- dst[i] = GIF_TRANSPARENT_COLOR; +- } ++ int i, j; ++ const size_t stride = picture->argb_stride; ++ uint32_t* dst = picture->argb + top * stride + left; ++ for (j = 0; j < height; ++j, dst += stride) { ++ for (i = 0; i < width; ++i) dst[i] = GIF_TRANSPARENT_COLOR; + } + } + +@@ -246,29 +252,31 @@ void GIFDisposeFrame(GIFDisposeMethod di + if (dispose == GIF_DISPOSE_BACKGROUND) { + GIFClearPic(curr_canvas, rect); + } else if (dispose == GIF_DISPOSE_RESTORE_PREVIOUS) { +- const int src_stride = prev_canvas->argb_stride; +- const uint32_t* const src = +- prev_canvas->argb + rect->x_offset + rect->y_offset * src_stride; +- const int dst_stride = curr_canvas->argb_stride; +- uint32_t* const dst = +- curr_canvas->argb + rect->x_offset + rect->y_offset * dst_stride; ++ const size_t src_stride = prev_canvas->argb_stride; ++ const uint32_t* const src = prev_canvas->argb + rect->x_offset ++ + rect->y_offset * src_stride; ++ const size_t dst_stride = curr_canvas->argb_stride; ++ uint32_t* const dst = curr_canvas->argb + rect->x_offset ++ + rect->y_offset * dst_stride; + assert(prev_canvas != NULL); +- WebPCopyPlane((uint8_t*)src, 4 * src_stride, (uint8_t*)dst, 4 * dst_stride, ++ WebPCopyPlane((uint8_t*)src, (int)(4 * src_stride), ++ (uint8_t*)dst, (int)(4 * dst_stride), + 4 * rect->width, rect->height); + } + } + + void GIFBlendFrames(const WebPPicture* const src, + const GIFFrameRect* const rect, WebPPicture* const dst) { +- int j; ++ int i, j; ++ const size_t src_stride = src->argb_stride; ++ const size_t dst_stride = dst->argb_stride; + assert(src->width == dst->width && src->height == dst->height); + for (j = rect->y_offset; j < rect->y_offset + rect->height; ++j) { +- int i; + for (i = rect->x_offset; i < rect->x_offset + rect->width; ++i) { +- const uint32_t src_pixel = src->argb[j * src->argb_stride + i]; ++ const uint32_t src_pixel = src->argb[j * src_stride + i]; + const int src_alpha = src_pixel >> 24; + if (src_alpha != 0) { +- dst->argb[j * dst->argb_stride + i] = src_pixel; ++ dst->argb[j * dst_stride + i] = src_pixel; + } + } + } diff --git a/libwebp.spec b/libwebp.spec index eab92d0..db46b2b 100644 --- a/libwebp.spec +++ b/libwebp.spec @@ -2,7 +2,7 @@ Name: libwebp Version: 0.5.1 -Release: 1%{?dist} +Release: 2%{?dist} URL: http://webmproject.org/ Summary: Library and tools for the WebP graphics format # Additional IPR is licensed as well. See PATENTS file for details @@ -10,6 +10,9 @@ License: BSD Source0: http://downloads.webmproject.org/releases/webp/%{name}-%{version}.tar.gz Source1: libwebp_jni_example.java +# Backport e2affacc35f1df6cc3b1a9fa0ceff5ce2d0cce83 (CVE-2016-9085, rhbz#1389338) +Patch0: e2affacc35f1df6cc3b1a9fa0ceff5ce2d0cce83.patch + BuildRequires: libjpeg-devel BuildRequires: libpng-devel BuildRequires: giflib-devel @@ -62,7 +65,7 @@ Java bindings for libwebp. %prep -%autosetup +%autosetup -p1 %build @@ -140,6 +143,9 @@ cp swig/*.jar swig/*.so %{buildroot}/%{_libdir}/%{name}-java/ %changelog +* Sat Oct 29 2016 Sandro Mani - 0.5.1-2 +- Backport e2affacc35f1df6cc3b1a9fa0ceff5ce2d0cce83 (CVE-2016-9085, rhbz#1389338) + * Fri Aug 12 2016 Sandro Mani - 0.5.1-1 - upstream release 0.5.1