diff options
author | Robin Watts <robin.watts@artifex.com> | 2014-01-17 13:40:17 +0000 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2014-01-17 13:48:01 +0000 |
commit | 776ee05584156f6737ec7603b2f2f68d3a301bab (patch) | |
tree | 458ddbbc304f320034459da14f77f1f1472bd3e0 /source | |
parent | 207c58162fe0bece0412325d3dfefe3bd12528ba (diff) | |
download | mupdf-776ee05584156f6737ec7603b2f2f68d3a301bab.tar.xz |
Bug 694896: Ensure that repairs don't lose trailer dict.
When we find certain classes of flaw in the file while attempting to
read an object, we trigger an automatic repair of the file. This
leaves almost all objects unchanged; the sole exception is that of
the trailer object (and its sub objects) which can get dropped and
recreated.
To avoid leaving people holding handles to objects within the trailer
dict high and dry, we introduce a 'pre_repair_trailer' object to
each xref entry. On a repair, we copy the existing trailer object to
this. As we only ever repair once, this is safe.
The only known place where this is a problem is when setting up the
pdf_crypt for a document; we adapt the code here to allow for
potential problems.
The example file that shows this up is:
048d14d2f5f0ae31e9a2cde0be66f16a_asan_heap-uaf_86d4ed_3961_3661.pdf
Thanks to Mateusz Jurczyk and Gynvael Coldwind of the Google Security
Team for providing the fuzzing files.
Diffstat (limited to 'source')
-rw-r--r-- | source/pdf/pdf-xref.c | 9 |
1 files changed, 8 insertions, 1 deletions
diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c index 735f2e2e..881826b9 100644 --- a/source/pdf/pdf-xref.c +++ b/source/pdf/pdf-xref.c @@ -41,6 +41,7 @@ static void pdf_free_xref_sections(pdf_document *doc) } fz_free(ctx, xref->table); + pdf_drop_obj(xref->pre_repair_trailer); pdf_drop_obj(xref->trailer); } @@ -76,6 +77,7 @@ static void pdf_populate_next_xref_level(pdf_document *doc) xref->len = 0; xref->table = NULL; xref->trailer = NULL; + xref->pre_repair_trailer = NULL; } pdf_obj *pdf_trailer(pdf_document *doc) @@ -90,7 +92,11 @@ void pdf_set_populating_xref_trailer(pdf_document *doc, pdf_obj *trailer) { /* Update the trailer of the xref section being populated */ pdf_xref *xref = &doc->xref_sections[doc->num_xref_sections - 1]; - pdf_drop_obj(xref->trailer); + if (xref->trailer) + { + pdf_drop_obj(xref->pre_repair_trailer); + xref->pre_repair_trailer = xref->trailer; + } xref->trailer = pdf_keep_obj(trailer); } @@ -186,6 +192,7 @@ static void ensure_incremental_xref(pdf_document *doc) /* xref->len is already correct */ xref->table = new_table; xref->trailer = trailer; + xref->pre_repair_trailer = NULL; doc->num_xref_sections++; doc->xref_altered = 1; } |