Skip to content

Commit

Permalink
xbm: avoid stack overflow (read) with large names #211
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
vapier committed May 14, 2016
1 parent b083ec1 commit 4dc1a2d
Showing 1 changed file with 27 additions and 7 deletions.
34 changes: 27 additions & 7 deletions src/gd_xbm.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand All @@ -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)
{
Expand All @@ -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);

Expand All @@ -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;
}
}
Expand All @@ -248,6 +268,6 @@ BGD_DECLARE(void) gdImageXbmCtx(gdImagePtr image, char* file_name, int fg, gdIOC
}
}
}
gdCtxPrintf(out, "};\n");
gdCtxPuts(out, "};\n");
}
/* }}} */

0 comments on commit 4dc1a2d

Please sign in to comment.