diff options
author | Robin Watts <robin@peeved.(none)> | 2014-01-17 11:16:32 -0800 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2014-01-17 23:57:50 +0000 |
commit | 01f0a0db15faf4bffaa2556ced74868572dac7f5 (patch) | |
tree | 53c523d20be45db2edac3d96e50a8a5b1e4e4a77 | |
parent | 63869ca1b53eb485dc0c8b5e53679825826ec076 (diff) | |
download | mupdf-01f0a0db15faf4bffaa2556ced74868572dac7f5.tar.xz |
Bug 694899: Avoid using invalid gstate pointer.
When we call pdf_begin_group, this can go away and do lots of
drawing. This can result in the gstate stack growing, which can
involve a realloc. Any gstate pointer we are holding must therefore
be recalculated after such a call.
The neatest way to do this is to get pdf_begin_group to return
the gstate pointer, thus making it hard to forget to do.
This solves:
e2a1dda5393f4cb8a446fd8edd9d94f9_asan_heap-uaf_b938cf_2075_2393.pdf
Thanks to Mateusz Jurczyk and Gynvael Coldwind of the Google Security
Team for providing the example files.
-rw-r--r-- | source/pdf/pdf-interpret.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/source/pdf/pdf-interpret.c b/source/pdf/pdf-interpret.c index eeb2f371..52a3a61d 100644 --- a/source/pdf/pdf-interpret.c +++ b/source/pdf/pdf-interpret.c @@ -409,13 +409,15 @@ end_softmask(pdf_csi *csi, softmask_save *save) fz_pop_clip(csi->dev); } -static void +static pdf_gstate * pdf_begin_group(pdf_csi *csi, const fz_rect *bbox, softmask_save *softmask) { pdf_gstate *gstate = begin_softmask(csi, softmask); if (gstate->blendmode) fz_begin_group(csi->dev, bbox, 1, 0, gstate->blendmode, 1); + + return csi->gstate + csi->gtop; } static void @@ -442,7 +444,7 @@ pdf_show_shade(pdf_csi *csi, fz_shade *shd) fz_bound_shade(ctx, shd, &gstate->ctm, &bbox); - pdf_begin_group(csi, &bbox, &softmask); + gstate = pdf_begin_group(csi, &bbox, &softmask); /* FIXME: The gstate->ctm in the next line may be wrong; maybe * it should be the parent gstates ctm? */ @@ -477,7 +479,7 @@ pdf_show_image(pdf_csi *csi, fz_image *image) fz_clip_image_mask(csi->dev, image->mask, &bbox, &image_ctm); } else - pdf_begin_group(csi, &bbox, &softmask); + gstate = pdf_begin_group(csi, &bbox, &softmask); if (!image->colorspace) { @@ -567,7 +569,7 @@ pdf_show_path(pdf_csi *csi, int doclose, int dofill, int dostroke, int even_odd) dostroke = dofill = 0; if (dofill || dostroke) - pdf_begin_group(csi, &bbox, &softmask); + gstate = pdf_begin_group(csi, &bbox, &softmask); if (dofill && dostroke) { @@ -709,7 +711,7 @@ pdf_flush_text(pdf_csi *csi) if (text->len == 0) break; - pdf_begin_group(csi, &tb, &softmask); + gstate = pdf_begin_group(csi, &tb, &softmask); if (doinvisible) fz_ignore_text(csi->dev, text, &gstate->ctm); |