diff options
author | Simon Bünzli <zeniko@gmail.com> | 2014-01-16 22:04:51 +0100 |
---|---|---|
committer | Simon Bünzli <zeniko@gmail.com> | 2014-01-16 22:09:13 +0100 |
commit | 60dabde18d7fe12b19da8b509bdfee9cc886aafc (patch) | |
tree | da0f1f2ace0fdd9c153e12dcf20075e2674117fa /source/xps/xps-common.c | |
parent | 5106b010ec248bf254effcb3445a16dc7c4b015b (diff) | |
download | mupdf-60dabde18d7fe12b19da8b509bdfee9cc886aafc.tar.xz |
Bug 694957: fix stack buffer overflow in xps_parse_color
xps_parse_color happily reads more than FZ_MAX_COLORS values out of a
ContextColor array which overflows the passed in samples array.
Limiting the number of allowed samples to FZ_MAX_COLORS and make sure
to use that constant for all callers fixes the problem.
Thanks to Jean-Jamil Khalifé for reporting and investigating the issue
and providing a sample exploit file.
Diffstat (limited to 'source/xps/xps-common.c')
-rw-r--r-- | source/xps/xps-common.c | 22 |
1 files changed, 14 insertions, 8 deletions
diff --git a/source/xps/xps-common.c b/source/xps/xps-common.c index b780f428..32a30baa 100644 --- a/source/xps/xps-common.c +++ b/source/xps/xps-common.c @@ -89,7 +89,7 @@ xps_begin_opacity(xps_document *doc, const fz_matrix *ctm, const fz_rect *area, if (scb_color_att) { fz_colorspace *colorspace; - float samples[32]; + float samples[FZ_MAX_COLORS]; xps_parse_color(doc, base_uri, scb_color_att, &colorspace, samples); opacity = opacity * samples[0]; } @@ -208,12 +208,13 @@ void xps_parse_color(xps_document *doc, char *base_uri, char *string, fz_colorspace **csp, float *samples) { + fz_context *ctx = doc->ctx; char *p; int i, n; char buf[1024]; char *profile; - *csp = fz_device_rgb(doc->ctx); + *csp = fz_device_rgb(ctx); samples[0] = 1; samples[1] = 0; @@ -259,7 +260,7 @@ xps_parse_color(xps_document *doc, char *base_uri, char *string, profile = strchr(buf, ' '); if (!profile) { - fz_warn(doc->ctx, "cannot find icc profile uri in '%s'", string); + fz_warn(ctx, "cannot find icc profile uri in '%s'", string); return; } @@ -267,12 +268,17 @@ xps_parse_color(xps_document *doc, char *base_uri, char *string, p = strchr(profile, ' '); if (!p) { - fz_warn(doc->ctx, "cannot find component values in '%s'", profile); + fz_warn(ctx, "cannot find component values in '%s'", profile); return; } *p++ = 0; n = count_commas(p) + 1; + if (n > FZ_MAX_COLORS) + { + fz_warn(ctx, "ignoring %d color components (max %d allowed)", n - FZ_MAX_COLORS, FZ_MAX_COLORS); + n = FZ_MAX_COLORS; + } i = 0; while (i < n) { @@ -292,10 +298,10 @@ xps_parse_color(xps_document *doc, char *base_uri, char *string, /* TODO: load ICC profile */ switch (n) { - case 2: *csp = fz_device_gray(doc->ctx); break; - case 4: *csp = fz_device_rgb(doc->ctx); break; - case 5: *csp = fz_device_cmyk(doc->ctx); break; - default: *csp = fz_device_gray(doc->ctx); break; + case 2: *csp = fz_device_gray(ctx); break; + case 4: *csp = fz_device_rgb(ctx); break; + case 5: *csp = fz_device_cmyk(ctx); break; + default: *csp = fz_device_gray(ctx); break; } } } |