Fix out of bounds read when encoding gif from malformed input with gd2togif

(CVE-2016-6161)
This commit is contained in:
Marek Skalický 2016-09-19 12:24:58 +02:00
parent da9eaac8b5
commit 91f922d872
3 changed files with 133 additions and 2 deletions

BIN
bug00209.gd2 Normal file

Binary file not shown.

View File

@ -0,0 +1,119 @@
From 82b80dcb70a7ca8986125ff412bceddafc896842 Mon Sep 17 00:00:00 2001
From: Mike Frysinger <vapier@gentoo.org>
Date: Sat, 14 May 2016 02:13:15 -0400
Subject: [PATCH] gif: avoid out-of-bound reads of masks array #209
When given invalid inputs, we might be fed the EOF marker before it is
actually the EOF. The gif logic assumes once it sees the EOF marker,
there won't be any more data, so it leaves the cur_bits index possibly
negative. So when we get more data, we underflow the masks array.
Flag it so we don't try to output anything more. The image is invalid,
so we shouldn't be truncating any valid inputs.
This fixes #209.
---
src/gd_gif_out.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
From 315dbfb0e75895e3ba84f649c491956e75f1106c Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
Date: Tue, 19 Jul 2016 10:43:55 +0200
Subject: [PATCH] Add test case for issue #209
---
tests/gif/.gitignore | 1 +
tests/gif/CMakeLists.txt | 1 +
tests/gif/Makemodule.am | 4 +++-
tests/gif/bug00209.c | 29 +++++++++++++++++++++++++++++
tests/gif/bug00209.gd2 | Bin 0 -> 1050 bytes
5 files changed, 34 insertions(+), 1 deletion(-)
create mode 100644 tests/gif/bug00209.c
create mode 100644 tests/gif/bug00209.gd2
diff --git a/src/gd_gif_out.c b/src/gd_gif_out.c
index 51ceb75..3099d49 100644
--- a/src/gd_gif_out.c
+++ b/src/gd_gif_out.c
@@ -1442,15 +1442,23 @@ static void compress(int init_bits, gdIOCtxPtr outfile, gdImagePtr im, GifCtx *c
* code in turn. When the buffer fills up empty it and start over.
*/
-static unsigned long masks[] = {
+static const unsigned long masks[] = {
0x0000, 0x0001, 0x0003, 0x0007, 0x000F,
0x001F, 0x003F, 0x007F, 0x00FF,
0x01FF, 0x03FF, 0x07FF, 0x0FFF,
0x1FFF, 0x3FFF, 0x7FFF, 0xFFFF
};
+/* Arbitrary value to mark output is done. When we see EOFCode, then we don't
+ * expect to see any more data. If we do (e.g. corrupt image inputs), cur_bits
+ * might be negative, so flag it to return early.
+ */
+#define CUR_BITS_FINISHED -1000
+
static void output(code_int code, GifCtx *ctx)
{
+ if (ctx->cur_bits == CUR_BITS_FINISHED)
+ return;
ctx->cur_accum &= masks[ctx->cur_bits];
if(ctx->cur_bits > 0) {
@@ -1492,6 +1500,8 @@ static void output(code_int code, GifCtx *ctx)
ctx->cur_accum >>= 8;
ctx->cur_bits -= 8;
}
+ /* Flag that it's done to prevent re-entry. */
+ ctx->cur_bits = CUR_BITS_FINISHED;
flush_char(ctx);
}
diff --git a/tests/gif/CMakeLists.txt b/tests/gif/CMakeLists.txt
index 92010c3..d26b1fe 100644
--- a/tests/gif/CMakeLists.txt
+++ b/tests/gif/CMakeLists.txt
@@ -7,6 +7,7 @@ LIST(APPEND TESTS_FILES
bug00060
bug00066
bug00181
+ bug00209
bug00227
)
diff --git a/tests/gif/bug00209.c b/tests/gif/bug00209.c
new file mode 100644
index 0000000..6eafc32
--- /dev/null
+++ b/tests/gif/bug00209.c
@@ -0,0 +1,29 @@
+/* Test case for <https://github.com/libgd/libgd/issues/209>. */
+
+#include "gd.h"
+#include "gdtest.h"
+
+int main()
+{
+ gdImagePtr im;
+ FILE *fp;
+
+ /* printf("start\n"); */
+
+ fp = gdTestFileOpen("gif/bug00209.gd2");
+ gdTestAssert(fp != NULL);
+ im = gdImageCreateFromGd2(fp);
+ gdTestAssert(im != NULL);
+ fclose(fp);
+ /* printf("loaded\n"); */
+
+ fp = gdTestTempFp();
+ gdTestAssert(fp != NULL);
+ gdImageGif(im, fp);
+ fclose(fp);
+ /* printf("saved\n"); */
+
+ gdImageDestroy(im);
+
+ return gdNumFailures();
+}

16
gd.spec
View File

@ -5,7 +5,7 @@
Summary: A graphics library for quick creation of PNG or JPEG images
Name: gd
Version: 2.1.1
Release: 8%{?prever}%{?short}%{?dist}
Release: 9%{?prever}%{?short}%{?dist}
Group: System Environment/Libraries
License: MIT
URL: http://libgd.bitbucket.org/
@ -20,6 +20,8 @@ Source0: https://bitbucket.org/libgd/gd-libgd/downloads/libgd-%{version}%{
Source2: getver.pl
# Test data for CVE-2016-3074 test
Source3: invalid_neg_size.gd2
# Test data for CVE-2016-6161 test
Source4: bug00209.gd2
Patch1: gd-2.1.0-multilib.patch
Patch2: gd-2.1.1-libvpx.patch
@ -33,6 +35,9 @@ Patch5: gd-2.1.1-xbm-large-names-overflow.patch
Patch6: gd-2.1.1-CVE-2015-8874.patch
# CVE-2016-5766
Patch7: gd-2.1.1-CVE-2016-5766.patch
# CVE-2016-6161
Patch8: gd-2.2.3-CVE-2016-6161.patch
BuildRequires: freetype-devel
BuildRequires: fontconfig-devel
@ -96,10 +101,12 @@ files for gd, a graphics library for creating PNG and JPEG graphics.
%patch5 -p1 -b .xbm-overflow
%patch6 -p1 -b .cve-2015-8874
%patch7 -p1 -b .cve-2016-5766
%patch8 -p1 -b .cve-2016-6161
# Workaround for missing file
cp %{SOURCE2} config/getver.pl
: $(perl config/getver.pl)
: regenerate autotool stuff
@ -135,6 +142,7 @@ rm -f $RPM_BUILD_ROOT/%{_libdir}/libgd.a
%check
cp %SOURCE3 tests/gd2/
cp %SOURCE4 tests/gif/
: Upstream test suite
make check
@ -166,13 +174,17 @@ grep %{version} $RPM_BUILD_ROOT%{_libdir}/pkgconfig/gdlib.pc
%changelog
* Mon Sep 19 2016 Marek Skalický <mskalick@redhat.com> - 2.1.1-9
- Fix out of bounds read when encoding gif from malformed input with gd2togif
(CVE-2016-6161)
* Tue Jun 28 2016 Remi Collet <remi@fedoraproject.org> - 2.1.1-8
- fix integer Overflow in _gd2GetHeader() (CVE-2016-5766)
* Fri Jun 24 2016 Remi Collet <remi@fedoraproject.org> - 2.1.1-7
- fix for stack overflow with gdImageFillToBorder (CVE-2015-8874)
* Thu May 31 2016 Marek Skalicky <mskalick@redhat.com> - 2.1.1-6
* Tue May 31 2016 Marek Skalicky <mskalick@redhat.com> - 2.1.1-6
- Backported fixes of two memory leaks (CVE-2015-8877, CVE-2016-5116)
* Thu Apr 28 2016 Marek Skalicky <mskalick@redhat.com> - 2.1.1-5