36220a6
commit 7894a6e684ce68ddff9f4f4919ab8e3911ac8040
36220a6
Author: Andrea Mazzoleni <amadvance@gmail.com>
36220a6
Date:   Fri Jan 4 20:49:48 2019 +0100
36220a6
36220a6
    Fix a buffer overflow caused by invalid chunks
36220a6
36220a6
diff --git a/pngex.cc b/pngex.cc
36220a6
index 55d16f5..3f5b49f 100644
36220a6
--- a/pngex.cc
36220a6
+++ b/pngex.cc
36220a6
@@ -163,6 +163,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
36220a6
 
36220a6
 	switch (type) {
36220a6
 		case ADV_MNG_CN_MHDR :
36220a6
+			if (size < 28) {
36220a6
+				cout << " invalid chunk size";
36220a6
+				break;
36220a6
+			}
36220a6
 			cout << " width:" << be_uint32_read(data+0) << " height:" << be_uint32_read(data+4) << " frequency:" << be_uint32_read(data+8);
36220a6
 			cout << " simplicity:" << be_uint32_read(data+24);
36220a6
 			cout << "(bit";
36220a6
@@ -174,6 +178,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
36220a6
 			cout << ")";
36220a6
 		break;
36220a6
 		case ADV_MNG_CN_DHDR :
36220a6
+			if (size < 4) {
36220a6
+				cout << " invalid chunk size";
36220a6
+				break;
36220a6
+			}
36220a6
 			cout << " id:" << be_uint16_read(data+0);
36220a6
 			switch (data[2]) {
36220a6
 				case 0 : cout << " img:unspecified"; break;
36220a6
@@ -243,6 +251,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
36220a6
 			}
36220a6
 			break;
36220a6
 		case ADV_MNG_CN_DEFI :
36220a6
+			if (size < 2) {
36220a6
+				cout << " invalid chunk size";
36220a6
+				break;
36220a6
+			}
36220a6
 			cout << " id:" << be_uint16_read(data+0);
36220a6
 			if (size >= 3) {
36220a6
 				switch (data[2]) {
36220a6
@@ -266,6 +278,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
36220a6
 			}
36220a6
 		break;
36220a6
 		case ADV_MNG_CN_MOVE :
36220a6
+			if (size < 13) {
36220a6
+				cout << " invalid chunk size";
36220a6
+				break;
36220a6
+			}
36220a6
 			cout << " id_from:" << be_uint16_read(data+0) << " id_to:" << be_uint16_read(data+2);
36220a6
 			switch (data[4]) {
36220a6
 				case 0 : cout << " type:replace"; break;
36220a6
@@ -275,6 +291,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
36220a6
 			cout << " x:" << (int)be_uint32_read(data + 5) << " y:" << (int)be_uint32_read(data + 9);
36220a6
 			break;
36220a6
 		case ADV_MNG_CN_PPLT :
36220a6
+			if (size < 1) {
36220a6
+				cout << " invalid chunk size";
36220a6
+				break;
36220a6
+			}
36220a6
 			switch (data[0]) {
36220a6
 				case 0 : cout << " type:replacement_rgb"; break;
36220a6
 				case 1 : cout << " type:delta_rgb"; break;
36220a6
@@ -285,7 +305,7 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
36220a6
 				default : cout << " type:?"; break;
36220a6
 			}
36220a6
 			i = 1;
36220a6
-			while (i
36220a6
+			while (i + 1 < size) {
36220a6
 				unsigned ssize;
36220a6
 				cout << " " << (unsigned)data[i] << ":" << (unsigned)data[i+1];
36220a6
 				if (data[0] == 0 || data[1] == 1)
36220a6
@@ -298,6 +318,10 @@ void png_print_chunk(unsigned type, unsigned char* data, unsigned size)
36220a6
 			}
36220a6
 			break;
36220a6
 		case ADV_PNG_CN_IHDR :
36220a6
+			if (size < 13) {
36220a6
+				cout << " invalid chunk size";
36220a6
+				break;
36220a6
+			}
36220a6
 			cout << " width:" << be_uint32_read(data) << " height:" << be_uint32_read(data + 4);
36220a6
 			cout << " depth:" << (unsigned)data[8];
36220a6
 			cout << " color_type:" << (unsigned)data[9];
712227b
diff -up advancecomp-2.1/lib/png.c.me advancecomp-2.1/lib/png.c
712227b
--- advancecomp-2.1/lib/png.c.me	2019-03-06 21:38:19.099210846 +0100
712227b
+++ advancecomp-2.1/lib/png.c	2019-03-06 21:38:49.193040592 +0100
712227b
@@ -655,6 +655,11 @@ adv_error adv_png_read_ihdr(
712227b
 	}
712227b
 	*pix_pixel = pixel;
712227b
 
712227b
+	if (width_align < width) {
712227b
+		error_unsupported_set("Invalid image size");
712227b
+		goto err;
712227b
+	}
712227b
+
712227b
 	if (data[10] != 0) { /* compression */
712227b
 		error_unsupported_set("Unsupported compression, %d instead of 0", (unsigned)data[10]);
712227b
 		goto err;