rev |
line source |
pascal@24695
|
1 commit 7894a6e684ce68ddff9f4f4919ab8e3911ac8040
|
pascal@24695
|
2 Author: Andrea Mazzoleni <amadvance@gmail.com>
|
pascal@24695
|
3 Date: Fri Jan 4 20:49:48 2019 +0100
|
pascal@24695
|
4
|
pascal@24695
|
5 Fix a buffer overflow caused by invalid chunks
|
pascal@24695
|
6
|
pascal@24695
|
7 diff --git a/pngex.cc b/pngex.cc
|
pascal@24695
|
8 index 55d16f5..3f5b49f 100644
|
pascal@24695
|
9 --- a/pngex.cc
|
pascal@24695
|
10 +++ b/pngex.cc
|
pascal@24695
|
11 @@ -163,6 +163,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
pascal@24695
|
12
|
pascal@24695
|
13 switch (type) {
|
pascal@24695
|
14 case ADV_MNG_CN_MHDR :
|
pascal@24695
|
15 + if (size < 28) {
|
pascal@24695
|
16 + cout << " invalid chunk size";
|
pascal@24695
|
17 + break;
|
pascal@24695
|
18 + }
|
pascal@24695
|
19 cout << " width:" << be_uint32_read(data+0) << " height:" << be_uint32_read(data+4) << " frequency:" << be_uint32_read(data+8);
|
pascal@24695
|
20 cout << " simplicity:" << be_uint32_read(data+24);
|
pascal@24695
|
21 cout << "(bit";
|
pascal@24695
|
22 @@ -174,6 +178,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
pascal@24695
|
23 cout << ")";
|
pascal@24695
|
24 break;
|
pascal@24695
|
25 case ADV_MNG_CN_DHDR :
|
pascal@24695
|
26 + if (size < 4) {
|
pascal@24695
|
27 + cout << " invalid chunk size";
|
pascal@24695
|
28 + break;
|
pascal@24695
|
29 + }
|
pascal@24695
|
30 cout << " id:" << be_uint16_read(data+0);
|
pascal@24695
|
31 switch (data[2]) {
|
pascal@24695
|
32 case 0 : cout << " img:unspecified"; break;
|
pascal@24695
|
33 @@ -243,6 +251,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
pascal@24695
|
34 }
|
pascal@24695
|
35 break;
|
pascal@24695
|
36 case ADV_MNG_CN_DEFI :
|
pascal@24695
|
37 + if (size < 2) {
|
pascal@24695
|
38 + cout << " invalid chunk size";
|
pascal@24695
|
39 + break;
|
pascal@24695
|
40 + }
|
pascal@24695
|
41 cout << " id:" << be_uint16_read(data+0);
|
pascal@24695
|
42 if (size >= 3) {
|
pascal@24695
|
43 switch (data[2]) {
|
pascal@24695
|
44 @@ -266,6 +278,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
pascal@24695
|
45 }
|
pascal@24695
|
46 break;
|
pascal@24695
|
47 case ADV_MNG_CN_MOVE :
|
pascal@24695
|
48 + if (size < 13) {
|
pascal@24695
|
49 + cout << " invalid chunk size";
|
pascal@24695
|
50 + break;
|
pascal@24695
|
51 + }
|
pascal@24695
|
52 cout << " id_from:" << be_uint16_read(data+0) << " id_to:" << be_uint16_read(data+2);
|
pascal@24695
|
53 switch (data[4]) {
|
pascal@24695
|
54 case 0 : cout << " type:replace"; break;
|
pascal@24695
|
55 @@ -275,6 +291,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
pascal@24695
|
56 cout << " x:" << (int)be_uint32_read(data + 5) << " y:" << (int)be_uint32_read(data + 9);
|
pascal@24695
|
57 break;
|
pascal@24695
|
58 case ADV_MNG_CN_PPLT :
|
pascal@24695
|
59 + if (size < 1) {
|
pascal@24695
|
60 + cout << " invalid chunk size";
|
pascal@24695
|
61 + break;
|
pascal@24695
|
62 + }
|
pascal@24695
|
63 switch (data[0]) {
|
pascal@24695
|
64 case 0 : cout << " type:replacement_rgb"; break;
|
pascal@24695
|
65 case 1 : cout << " type:delta_rgb"; break;
|
pascal@24695
|
66 @@ -285,7 +305,7 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
pascal@24695
|
67 default : cout << " type:?"; break;
|
pascal@24695
|
68 }
|
pascal@24695
|
69 i = 1;
|
pascal@24695
|
70 - while (i<size) {
|
pascal@24695
|
71 + while (i + 1 < size) {
|
pascal@24695
|
72 unsigned ssize;
|
pascal@24695
|
73 cout << " " << (unsigned)data[i] << ":" << (unsigned)data[i+1];
|
pascal@24695
|
74 if (data[0] == 0 || data[1] == 1)
|
pascal@24695
|
75 @@ -298,6 +318,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
|
pascal@24695
|
76 }
|
pascal@24695
|
77 break;
|
pascal@24695
|
78 case ADV_PNG_CN_IHDR :
|
pascal@24695
|
79 + if (size < 13) {
|
pascal@24695
|
80 + cout << " invalid chunk size";
|
pascal@24695
|
81 + break;
|
pascal@24695
|
82 + }
|
pascal@24695
|
83 cout << " width:" << be_uint32_read(data) << " height:" << be_uint32_read(data + 4);
|
pascal@24695
|
84 cout << " depth:" << (unsigned)data[8];
|
pascal@24695
|
85 cout << " color_type:" << (unsigned)data[9];
|
pascal@24695
|
86 diff -up advancecomp-2.1/lib/png.c.me advancecomp-2.1/lib/png.c
|
pascal@24695
|
87 --- advancecomp-2.1/lib/png.c.me 2019-03-06 21:38:19.099210846 +0100
|
pascal@24695
|
88 +++ advancecomp-2.1/lib/png.c 2019-03-06 21:38:49.193040592 +0100
|
pascal@24695
|
89 @@ -655,6 +655,11 @@ adv_error adv_png_read_ihdr(
|
pascal@24695
|
90 }
|
pascal@24695
|
91 *pix_pixel = pixel;
|
pascal@24695
|
92
|
pascal@24695
|
93 + if (width_align < width) {
|
pascal@24695
|
94 + error_unsupported_set("Invalid image size");
|
pascal@24695
|
95 + goto err;
|
pascal@24695
|
96 + }
|
pascal@24695
|
97 +
|
pascal@24695
|
98 if (data[10] != 0) { /* compression */
|
pascal@24695
|
99 error_unsupported_set("Unsupported compression, %d instead of 0", (unsigned)data[10]);
|
pascal@24695
|
100 goto err;
|