summaryrefslogtreecommitdiff
path: root/source/pdf/pdf-xref.c
diff options
context:
space:
mode:
authorRobin Watts <robin.watts@artifex.com>2014-01-17 13:40:17 +0000
committerRobin Watts <robin.watts@artifex.com>2014-01-17 13:48:01 +0000
commit776ee05584156f6737ec7603b2f2f68d3a301bab (patch)
tree458ddbbc304f320034459da14f77f1f1472bd3e0 /source/pdf/pdf-xref.c
parent207c58162fe0bece0412325d3dfefe3bd12528ba (diff)
downloadmupdf-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/pdf/pdf-xref.c')
-rw-r--r--source/pdf/pdf-xref.c9
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;
}