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