From 01f0a0db15faf4bffaa2556ced74868572dac7f5 Mon Sep 17 00:00:00 2001 From: Robin Watts Date: Fri, 17 Jan 2014 11:16:32 -0800 Subject: 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. --- source/pdf/pdf-interpret.c | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) (limited to 'source') 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); -- cgit v1.2.3