1 |
From 7894a6e684ce68ddff9f4f4919ab8e3911ac8040 Mon Sep 17 00:00:00 2001 |
2 |
From: Andrea Mazzoleni <amadvance@gmail.com> |
3 |
Date: Fri, 4 Jan 2019 20:49:48 +0100 |
4 |
Subject: [PATCH] Fix a buffer overflow caused by invalid chunks |
5 |
|
6 |
--- |
7 |
pngex.cc | 26 +++++++++++++++++++++++++- |
8 |
1 file changed, 25 insertions(+), 1 deletion(-) |
9 |
|
10 |
diff --git a/pngex.cc b/pngex.cc |
11 |
index 55d16f5..3f5b49f 100644 |
12 |
--- a/pngex.cc |
13 |
+++ b/pngex.cc |
14 |
@@ -163,6 +163,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size) |
15 |
|
16 |
switch (type) { |
17 |
case ADV_MNG_CN_MHDR : |
18 |
+ if (size < 28) { |
19 |
+ cout << " invalid chunk size"; |
20 |
+ break; |
21 |
+ } |
22 |
cout << " width:" << be_uint32_read(data+0) << " height:" << be_uint32_read(data+4) << " frequency:" << be_uint32_read(data+8); |
23 |
cout << " simplicity:" << be_uint32_read(data+24); |
24 |
cout << "(bit"; |
25 |
@@ -174,6 +178,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size) |
26 |
cout << ")"; |
27 |
break; |
28 |
case ADV_MNG_CN_DHDR : |
29 |
+ if (size < 4) { |
30 |
+ cout << " invalid chunk size"; |
31 |
+ break; |
32 |
+ } |
33 |
cout << " id:" << be_uint16_read(data+0); |
34 |
switch (data[2]) { |
35 |
case 0 : cout << " img:unspecified"; break; |
36 |
@@ -243,6 +251,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size) |
37 |
} |
38 |
break; |
39 |
case ADV_MNG_CN_DEFI : |
40 |
+ if (size < 2) { |
41 |
+ cout << " invalid chunk size"; |
42 |
+ break; |
43 |
+ } |
44 |
cout << " id:" << be_uint16_read(data+0); |
45 |
if (size >= 3) { |
46 |
switch (data[2]) { |
47 |
@@ -266,6 +278,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size) |
48 |
} |
49 |
break; |
50 |
case ADV_MNG_CN_MOVE : |
51 |
+ if (size < 13) { |
52 |
+ cout << " invalid chunk size"; |
53 |
+ break; |
54 |
+ } |
55 |
cout << " id_from:" << be_uint16_read(data+0) << " id_to:" << be_uint16_read(data+2); |
56 |
switch (data[4]) { |
57 |
case 0 : cout << " type:replace"; break; |
58 |
@@ -275,6 +291,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size) |
59 |
cout << " x:" << (int)be_uint32_read(data + 5) << " y:" << (int)be_uint32_read(data + 9); |
60 |
break; |
61 |
case ADV_MNG_CN_PPLT : |
62 |
+ if (size < 1) { |
63 |
+ cout << " invalid chunk size"; |
64 |
+ break; |
65 |
+ } |
66 |
switch (data[0]) { |
67 |
case 0 : cout << " type:replacement_rgb"; break; |
68 |
case 1 : cout << " type:delta_rgb"; break; |
69 |
@@ -285,7 +305,7 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size) |
70 |
default : cout << " type:?"; break; |
71 |
} |
72 |
i = 1; |
73 |
- while (i<size) { |
74 |
+ while (i + 1 < size) { |
75 |
unsigned ssize; |
76 |
cout << " " << (unsigned)data[i] << ":" << (unsigned)data[i+1]; |
77 |
if (data[0] == 0 || data[1] == 1) |
78 |
@@ -298,6 +318,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size) |
79 |
} |
80 |
break; |
81 |
case ADV_PNG_CN_IHDR : |
82 |
+ if (size < 13) { |
83 |
+ cout << " invalid chunk size"; |
84 |
+ break; |
85 |
+ } |
86 |
cout << " width:" << be_uint32_read(data) << " height:" << be_uint32_read(data + 4); |
87 |
cout << " depth:" << (unsigned)data[8]; |
88 |
cout << " color_type:" << (unsigned)data[9]; |