aboutsummaryrefslogtreecommitdiffstats
path: root/meta-oe/recipes-support/gd/gd/CVE-2016-6906-1.patch
blob: 97b7f72498b9ef55ae79efb5041e5cc04f3dee20 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
From fb0e0cce0b9f25389ab56604c3547351617e1415 Mon Sep 17 00:00:00 2001
From: "Christoph M. Becker" <cmbecker69@gmx.de>
Date: Tue, 16 Aug 2016 16:26:19 +0200
Subject: [PATCH] Fix OOB reads of the TGA decompression buffer

It is possible to craft TGA files which will overflow the decompression
buffer, but not the image's bitmap. Therefore we augment the check for the
bitmap's overflow with a check for the buffer's overflow.

This issue had been reported by Ibrahim El-Sayed to security@libgd.org.

CVE-2016-6906

Upstream-Status: Backport
CVE: CVE-2016-6906

Signed-off-by: Catalin Enache <catalin.enache@windriver.com>
---
 src/gd_tga.c                |   6 ++++--
 tests/tga/.gitignore        |   1 +
 tests/tga/CMakeLists.txt    |   1 +
 tests/tga/Makemodule.am     |   2 ++
 tests/tga/heap_overflow.c   |  51 ++++++++++++++++++++++++++++++++++++++++++++
 tests/tga/heap_overflow.tga | Bin 0 -> 605 bytes
 6 files changed, 59 insertions(+), 2 deletions(-)
 create mode 100644 tests/tga/heap_overflow.c
 create mode 100644 tests/tga/heap_overflow.tga

diff --git a/src/gd_tga.c b/src/gd_tga.c
index 8737b04..68e4b17 100644
--- a/src/gd_tga.c
+++ b/src/gd_tga.c
@@ -300,7 +300,8 @@ int read_image_tga( gdIOCtx *ctx, oTga *tga )
 				encoded_pixels = ( ( decompression_buffer[ buffer_caret ] & ~TGA_RLE_FLAG ) + 1 );
 				buffer_caret++;
 
-				if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size) {
+				if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size
+						|| buffer_caret + pixel_block_size > rle_size) {
 					gdFree( decompression_buffer );
 					gdFree( conversion_buffer );
 					return -1;
@@ -316,7 +317,8 @@ int read_image_tga( gdIOCtx *ctx, oTga *tga )
 				encoded_pixels = decompression_buffer[ buffer_caret ] + 1;
 				buffer_caret++;
 
-				if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size) {
+				if ((bitmap_caret + (encoded_pixels * pixel_block_size)) > image_block_size
+						|| buffer_caret + (encoded_pixels * pixel_block_size) > rle_size) {
 					gdFree( decompression_buffer );
 					gdFree( conversion_buffer );
 					return -1;
diff --git a/tests/tga/.gitignore b/tests/tga/.gitignore
index 7a659b1..cf0556b 100644
--- a/tests/tga/.gitignore
+++ b/tests/tga/.gitignore
@@ -3,5 +3,6 @@
 /bug00247a
 /bug00248
 /bug00248a
+/heap_overflow
 /tga_null
 /tga_read
diff --git a/tests/tga/CMakeLists.txt b/tests/tga/CMakeLists.txt
index 789fb14..11542a0 100644
--- a/tests/tga/CMakeLists.txt
+++ b/tests/tga/CMakeLists.txt
@@ -5,6 +5,7 @@ LIST(APPEND TESTS_FILES
 	bug00247a
 	bug00248
 	bug00248a
+	heap_overflow
 	tga_read
 )
 
diff --git a/tests/tga/Makemodule.am b/tests/tga/Makemodule.am
index a1e6af6..916d707 100644
--- a/tests/tga/Makemodule.am
+++ b/tests/tga/Makemodule.am
@@ -4,6 +4,7 @@ libgd_test_programs += \
 	tga/bug00247a \
 	tga/bug00248 \
 	tga/bug00248a \
+	tga/heap_overflow \
 	tga/tga_null \
 	tga/tga_read
 
@@ -14,6 +15,7 @@ EXTRA_DIST += \
 	tga/bug00247a.tga \
 	tga/bug00248.tga \
 	tga/bug00248a.tga \
+	tga/heap_overflow.tga \
 	tga/tga_read_rgb.png \
 	tga/tga_read_rgb.tga \
 	tga/tga_read_rgb_rle.tga
diff --git a/tests/tga/heap_overflow.c b/tests/tga/heap_overflow.c
new file mode 100644
index 0000000..0e9a2d0
--- /dev/null
+++ b/tests/tga/heap_overflow.c
@@ -0,0 +1,51 @@
+/**
+ * Test that the crafted TGA file doesn't trigger OOB reads.
+ */
+
+
+#include "gd.h"
+#include "gdtest.h"
+
+
+static size_t read_test_file(char **buffer, char *basename);
+
+
+int main()
+{
+    gdImagePtr im;
+    char *buffer;
+    size_t size;
+
+    size = read_test_file(&buffer, "heap_overflow.tga");
+    im = gdImageCreateFromTgaPtr(size, (void *) buffer);
+    gdTestAssert(im == NULL);
+    free(buffer);
+
+    return gdNumFailures();
+}
+
+
+static size_t read_test_file(char **buffer, char *basename)
+{
+    char *filename;
+    FILE *fp;
+    size_t exp_size, act_size;
+
+    filename = gdTestFilePath2("tga", basename);
+    fp = fopen(filename, "rb");
+    gdTestAssert(fp != NULL);
+
+	fseek(fp, 0, SEEK_END);
+	exp_size = ftell(fp);
+	fseek(fp, 0, SEEK_SET);
+
+    *buffer = malloc(exp_size);
+    gdTestAssert(*buffer != NULL);
+    act_size = fread(*buffer, sizeof(**buffer), exp_size, fp);
+    gdTestAssert(act_size == exp_size);
+
+    fclose(fp);
+    free(filename);
+
+    return act_size;
+}
diff --git a/tests/tga/heap_overflow.tga b/tests/tga/heap_overflow.tga
new file mode 100644
index 0000000000000000000000000000000000000000..e9bc0ecb2a847ac6edba92dd0ff61167b49002cd
GIT binary patch
literal 605
zcmZQz;9`IQ9tIu;g&7<$F3o7Yg1qzyh6tefy9wZAs2d<Uh*yuz=?XwW4Qvuv#g2nS
zp93+mT0rVR>T&8(2TGy=f_l)@gSap~$FayUFu(!|SyJIFga^{8fGj~vwq8kkVgvv>
Cavop+

literal 0
HcmV?d00001

-- 
2.10.2