Marek Skalický e34347
From 4dc1a2d7931017d3625f2d7cff70a17ce58b53b4 Mon Sep 17 00:00:00 2001
Marek Skalický e34347
From: Mike Frysinger <vapier@gentoo.org>
Marek Skalický e34347
Date: Sat, 14 May 2016 01:38:18 -0400
Marek Skalický e34347
Subject: [PATCH] xbm: avoid stack overflow (read) with large names #211
Marek Skalický e34347
Marek Skalický e34347
We use the name passed in to printf into a local stack buffer which is
Marek Skalický e34347
limited to 4000 bytes.  So given a large enough value, lots of stack
Marek Skalický e34347
data is leaked.  Rewrite the code to do simple memory copies with most
Marek Skalický e34347
of the strings to avoid that issue, and only use stack buffer for small
Marek Skalický e34347
numbers of constant size.
Marek Skalický e34347
Marek Skalický e34347
This closes #211.
Marek Skalický e34347
---
Marek Skalický e34347
 src/gd_xbm.c | 34 +++++++++++++++++++++++++++-------
Marek Skalický e34347
 1 file changed, 27 insertions(+), 7 deletions(-)
Marek Skalický e34347
Marek Skalický e34347
diff --git a/src/gd_xbm.c b/src/gd_xbm.c
Marek Skalický e34347
index 74d839b..d28fdfc 100644
Marek Skalický e34347
--- a/src/gd_xbm.c
Marek Skalický e34347
+++ b/src/gd_xbm.c
Marek Skalický e34347
@@ -180,7 +180,7 @@ BGD_DECLARE(gdImagePtr) gdImageCreateFromXbm(FILE * fd)
Marek Skalický e34347
 /* {{{ gdCtxPrintf */
Marek Skalický e34347
 static void gdCtxPrintf(gdIOCtx * out, const char *format, ...)
Marek Skalický e34347
 {
Marek Skalický e34347
-	char buf[4096];
Marek Skalický e34347
+	char buf[1024];
Marek Skalický e34347
 	int len;
Marek Skalický e34347
 	va_list args;
Marek Skalický e34347
 
Marek Skalický e34347
@@ -191,6 +191,9 @@ static void gdCtxPrintf(gdIOCtx * out, const char *format, ...)
Marek Skalický e34347
 }
Marek Skalický e34347
 /* }}} */
Marek Skalický e34347
 
Marek Skalický e34347
+/* The compiler will optimize strlen(constant) to a constant number. */
Marek Skalický e34347
+#define gdCtxPuts(out, s) out->putBuf(out, s, strlen(s))
Marek Skalický e34347
+
Marek Skalický e34347
 /* {{{ gdImageXbmCtx */
Marek Skalický e34347
 BGD_DECLARE(void) gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOCtx * out)
Marek Skalický e34347
 {
Marek Skalický e34347
@@ -215,9 +218,26 @@ BGD_DECLARE(void) gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOC
Marek Skalický e34347
 		}
Marek Skalický e34347
 	}
Marek Skalický e34347
 
Marek Skalický e34347
-	gdCtxPrintf(out, "#define %s_width %d\n", name, gdImageSX(image));
Marek Skalický e34347
-	gdCtxPrintf(out, "#define %s_height %d\n", name, gdImageSY(image));
Marek Skalický e34347
-	gdCtxPrintf(out, "static unsigned char %s_bits[] = {\n  ", name);
Marek Skalický e34347
+	/* Since "name" comes from the user, run it through a direct puts.
Marek Skalický e34347
+	 * Trying to printf it into a local buffer means we'd need a large
Marek Skalický e34347
+	 * or dynamic buffer to hold it all. */
Marek Skalický e34347
+
Marek Skalický e34347
+	/* #define <name>_width 1234 */
Marek Skalický e34347
+	gdCtxPuts(out, "#define ");
Marek Skalický e34347
+	gdCtxPuts(out, name);
Marek Skalický e34347
+	gdCtxPuts(out, "_width ");
Marek Skalický e34347
+	gdCtxPrintf(out, "%d\n", gdImageSX(image));
Marek Skalický e34347
+
Marek Skalický e34347
+	/* #define <name>_height 1234 */
Marek Skalický e34347
+	gdCtxPuts(out, "#define ");
Marek Skalický e34347
+	gdCtxPuts(out, name);
Marek Skalický e34347
+	gdCtxPuts(out, "_height ");
Marek Skalický e34347
+	gdCtxPrintf(out, "%d\n", gdImageSY(image));
Marek Skalický e34347
+
Marek Skalický e34347
+	/* static unsigned char <name>_bits[] = {\n */
Marek Skalický e34347
+	gdCtxPuts(out, "static unsigned char ");
Marek Skalický e34347
+	gdCtxPuts(out, name);
Marek Skalický e34347
+	gdCtxPuts(out, "_bits[] = {\n  ");
Marek Skalický e34347
 
Marek Skalický e34347
 	free(name);
Marek Skalický e34347
 
Marek Skalický e34347
@@ -234,9 +254,9 @@ BGD_DECLARE(void) gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOC
Marek Skalický e34347
 			if ((b == 128) || (x == sx && y == sy)) {
Marek Skalický e34347
 				b = 1;
Marek Skalický e34347
 				if (p) {
Marek Skalický e34347
-					gdCtxPrintf(out, ", ");
Marek Skalický e34347
+					gdCtxPuts(out, ", ");
Marek Skalický e34347
 					if (!(p%12)) {
Marek Skalický e34347
-						gdCtxPrintf(out, "\n  ");
Marek Skalický e34347
+						gdCtxPuts(out, "\n  ");
Marek Skalický e34347
 						p = 12;
Marek Skalický e34347
 					}
Marek Skalický e34347
 				}
Marek Skalický e34347
@@ -248,6 +268,6 @@ BGD_DECLARE(void) gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOC
Marek Skalický e34347
 			}
Marek Skalický e34347
 		}
Marek Skalický e34347
 	}
Marek Skalický e34347
-	gdCtxPrintf(out, "};\n");
Marek Skalický e34347
+	gdCtxPuts(out, "};\n");
Marek Skalický e34347
 }
Marek Skalický e34347
 /* }}} */