Fix Pixmap overflow. Bug 36621442

Fixes a problem when reading malformed image files.
The PoC is specific to ETC and KTX files, but might
affect other image formats since a fix was
made in the code that clears a Pixmap.

Test: PoC
Bug: 36621442
Change-Id: Iba6664b3e72876b70f36ea0a4627996dcfc619ae
(cherry picked from commit 394ac762bbcedaca292d3ccdef74ac49f42a28b2)
diff --git a/gdx/jni/com.badlogic.gdx.graphics.glutils.ETC1.cpp b/gdx/jni/com.badlogic.gdx.graphics.glutils.ETC1.cpp
index 94dc321..0c6eabd 100644
--- a/gdx/jni/com.badlogic.gdx.graphics.glutils.ETC1.cpp
+++ b/gdx/jni/com.badlogic.gdx.graphics.glutils.ETC1.cpp
@@ -1,4 +1,7 @@
 #include <com.badlogic.gdx.graphics.glutils.ETC1.h>
+#include <android/log.h>
+
+#define APP_LOG "GDX"
 
 //@line:196
 
@@ -86,9 +89,29 @@
 
 //@line:249
 

-		etc1_decode_image((etc1_byte*)compressedData + offset, (etc1_byte*)decodedData + offsetDec, width, height, pixelSize, width * pixelSize);

-	
+	// Nothing to decode, or no target
+	if (compressedData == 0 || decodedData == 0) {
+		__android_log_print(ANDROID_LOG_VERBOSE, APP_LOG, "Invalid buffers, null pointer.");
+		return;
+	}
 
+	/// Verify if requested bounds are valid
+	jlong compressedLength = env->GetDirectBufferCapacity(obj_compressedData);
+	jlong decodedLength = env->GetDirectBufferCapacity(obj_decodedData);
+	if (offset < 0 || compressedLength - offset > decodedLength - offsetDec) {
+		__android_log_print(ANDROID_LOG_VERBOSE,
+			APP_LOG, "Invalid buffers, would cause heap overflow. %lu > %lu",
+			compressedLength - offset,
+			decodedLength - offsetDec);
+		return;
+	}
+
+	etc1_decode_image((etc1_byte*)compressedData + offset,
+		(etc1_byte*)decodedData + offsetDec,
+		width,
+		height,
+		pixelSize,
+		width * pixelSize);
 }
 
 static inline jobject wrapped_Java_com_badlogic_gdx_graphics_glutils_ETC1_encodeImage
diff --git a/gdx/jni/gdx2d/gdx2d.c b/gdx/jni/gdx2d/gdx2d.c
index 13ceba2..70cfc7d 100644
--- a/gdx/jni/gdx2d/gdx2d.c
+++ b/gdx/jni/gdx2d/gdx2d.c
@@ -17,6 +17,9 @@
 #include "stb_image.h"

 #include "jpgd_c.h"

 

+#include <android/log.h>

+#define APP_LOG "GDX"

+

 static uint32_t gdx2d_blend = GDX2D_BLEND_NONE;

 static uint32_t gdx2d_scale = GDX2D_SCALE_NEAREST;

 

@@ -358,9 +361,25 @@
 	}

 }

 

-void gdx2d_clear(const gdx2d_pixmap* pixmap, uint32_t col) {	

+void gdx2d_clear(const gdx2d_pixmap* pixmap, uint32_t col) {

+	if (pixmap == 0)

+		return;

+

 	col = to_format(pixmap->format, col);

 

+	// Check for malformed Pixmap

+	size_t requestedSize = pixmap->width * pixmap->height * sizeof(col);

+	size_t pixelsSize = sizeof(pixmap->pixels);

+	if (requestedSize > pixelsSize) {

+		__android_log_print(ANDROID_LOG_VERBOSE,

+		APP_LOG, "Invalid pixmap. %ix%i - Size should be %u but found %u",

+		pixmap->width,

+		pixmap->height,

+		requestedSize,

+		pixelsSize);

+		return;

+	}

+

 	switch(pixmap->format) {

 		case GDX2D_FORMAT_ALPHA:

 			clear_alpha(pixmap, col);