2016-10-25 18:49:52 +02:00
|
|
|
Fix CVE-2016-8674 (use-after-free in pdf_to_num()).
|
|
|
|
|
|
|
|
https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2016-8674
|
|
|
|
https://security-tracker.debian.org/tracker/CVE-2016-8674
|
|
|
|
|
2016-10-26 07:39:34 +02:00
|
|
|
Patch adapted from upstream source repository:
|
2016-10-25 18:49:52 +02:00
|
|
|
http://git.ghostscript.com/?p=mupdf.git;h=1e03c06456d997435019fb3526fa2d4be7dbc6ec
|
|
|
|
|
|
|
|
diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h
|
2016-10-26 07:39:34 +02:00
|
|
|
index f8ef0cd..e8345b7 100644
|
2016-10-25 18:49:52 +02:00
|
|
|
--- a/include/mupdf/pdf/document.h
|
|
|
|
+++ b/include/mupdf/pdf/document.h
|
2016-10-26 07:39:34 +02:00
|
|
|
@@ -258,6 +258,10 @@ struct pdf_document_s
|
|
|
|
fz_font **type3_fonts;
|
|
|
|
|
|
|
|
pdf_resource_tables *resources;
|
2016-10-25 18:49:52 +02:00
|
|
|
+
|
|
|
|
+ int orphans_max;
|
|
|
|
+ int orphans_count;
|
|
|
|
+ pdf_obj **orphans;
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
diff --git a/include/mupdf/pdf/object.h b/include/mupdf/pdf/object.h
|
2016-10-26 07:39:34 +02:00
|
|
|
index 346a2f1..02d4119 100644
|
2016-10-25 18:49:52 +02:00
|
|
|
--- a/include/mupdf/pdf/object.h
|
|
|
|
+++ b/include/mupdf/pdf/object.h
|
2016-10-26 07:39:34 +02:00
|
|
|
@@ -109,6 +109,7 @@ pdf_obj *pdf_dict_gets(fz_context *ctx, pdf_obj *dict, const char *key);
|
2016-10-25 18:49:52 +02:00
|
|
|
pdf_obj *pdf_dict_getsa(fz_context *ctx, pdf_obj *dict, const char *key, const char *abbrev);
|
|
|
|
void pdf_dict_put(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val);
|
|
|
|
void pdf_dict_put_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val);
|
|
|
|
+void pdf_dict_get_put_drop(fz_context *ctx, pdf_obj *dict, pdf_obj *key, pdf_obj *val, pdf_obj **old_val);
|
|
|
|
void pdf_dict_puts(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val);
|
|
|
|
void pdf_dict_puts_drop(fz_context *ctx, pdf_obj *dict, const char *key, pdf_obj *val);
|
|
|
|
void pdf_dict_putp(fz_context *ctx, pdf_obj *dict, const char *path, pdf_obj *val);
|
|
|
|
diff --git a/source/pdf/pdf-object.c b/source/pdf/pdf-object.c
|
2016-10-26 07:39:34 +02:00
|
|
|
index f2e4551..a0d0d8e 100644
|
2016-10-25 18:49:52 +02:00
|
|
|
--- a/source/pdf/pdf-object.c
|
|
|
|
+++ b/source/pdf/pdf-object.c
|
2016-10-26 07:39:34 +02:00
|
|
|
@@ -1240,9 +1240,13 @@ pdf_dict_geta(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *abbrev)
|
2016-10-25 18:49:52 +02:00
|
|
|
return pdf_dict_get(ctx, obj, abbrev);
|
|
|
|
}
|
|
|
|
|
|
|
|
-void
|
|
|
|
-pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
|
|
|
|
+static void
|
|
|
|
+pdf_dict_get_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val, pdf_obj **old_val)
|
|
|
|
{
|
2016-10-26 07:39:34 +02:00
|
|
|
+
|
2016-10-25 18:49:52 +02:00
|
|
|
+ if (old_val)
|
|
|
|
+ *old_val = NULL;
|
|
|
|
+
|
|
|
|
RESOLVE(obj);
|
2016-10-26 07:39:34 +02:00
|
|
|
if (obj >= PDF_OBJ__LIMIT)
|
|
|
|
{
|
|
|
|
@@ -1282,7 +1286,10 @@ pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
|
|
|
|
{
|
|
|
|
pdf_obj *d = DICT(obj)->items[i].v;
|
|
|
|
DICT(obj)->items[i].v = pdf_keep_obj(ctx, val);
|
|
|
|
- pdf_drop_obj(ctx, d);
|
|
|
|
+ if (old_val)
|
|
|
|
+ *old_val = d;
|
|
|
|
+ else
|
|
|
|
+ pdf_drop_obj(ctx, d);
|
|
|
|
}
|
2016-10-25 18:49:52 +02:00
|
|
|
}
|
2016-10-26 07:39:34 +02:00
|
|
|
else
|
|
|
|
@@ -1305,10 +1312,27 @@ pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
|
2016-10-25 18:49:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
+pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
|
|
|
|
+{
|
|
|
|
+ pdf_dict_get_put(ctx, obj, key, val, NULL);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
pdf_dict_put_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val)
|
|
|
|
{
|
|
|
|
fz_try(ctx)
|
|
|
|
- pdf_dict_put(ctx, obj, key, val);
|
|
|
|
+ pdf_dict_get_put(ctx, obj, key, val, NULL);
|
|
|
|
+ fz_always(ctx)
|
|
|
|
+ pdf_drop_obj(ctx, val);
|
|
|
|
+ fz_catch(ctx)
|
|
|
|
+ fz_rethrow(ctx);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+void
|
|
|
|
+pdf_dict_get_put_drop(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val, pdf_obj **old_val)
|
|
|
|
+{
|
|
|
|
+ fz_try(ctx)
|
|
|
|
+ pdf_dict_get_put(ctx, obj, key, val, old_val);
|
|
|
|
fz_always(ctx)
|
|
|
|
pdf_drop_obj(ctx, val);
|
|
|
|
fz_catch(ctx)
|
|
|
|
diff --git a/source/pdf/pdf-repair.c b/source/pdf/pdf-repair.c
|
2016-10-26 07:39:34 +02:00
|
|
|
index fdd4648..212c8b7 100644
|
2016-10-25 18:49:52 +02:00
|
|
|
--- a/source/pdf/pdf-repair.c
|
|
|
|
+++ b/source/pdf/pdf-repair.c
|
2016-10-26 07:39:34 +02:00
|
|
|
@@ -259,6 +259,27 @@ pdf_repair_obj_stm(fz_context *ctx, pdf_document *doc, int num, int gen)
|
2016-10-25 18:49:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
+static void
|
|
|
|
+orphan_object(fz_context *ctx, pdf_document *doc, pdf_obj *obj)
|
|
|
|
+{
|
|
|
|
+ if (doc->orphans_count == doc->orphans_max)
|
|
|
|
+ {
|
|
|
|
+ int new_max = (doc->orphans_max ? doc->orphans_max*2 : 32);
|
|
|
|
+
|
|
|
|
+ fz_try(ctx)
|
|
|
|
+ {
|
|
|
|
+ doc->orphans = fz_resize_array(ctx, doc->orphans, new_max, sizeof(*doc->orphans));
|
|
|
|
+ doc->orphans_max = new_max;
|
|
|
|
+ }
|
|
|
|
+ fz_catch(ctx)
|
|
|
|
+ {
|
|
|
|
+ pdf_drop_obj(ctx, obj);
|
|
|
|
+ fz_rethrow(ctx);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ doc->orphans[doc->orphans_count++] = obj;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
void
|
|
|
|
pdf_repair_xref(fz_context *ctx, pdf_document *doc)
|
|
|
|
{
|
2016-10-26 07:39:34 +02:00
|
|
|
@@ -520,12 +541,13 @@ pdf_repair_xref(fz_context *ctx, pdf_document *doc)
|
2016-10-25 18:49:52 +02:00
|
|
|
/* correct stream length for unencrypted documents */
|
|
|
|
if (!encrypt && list[i].stm_len >= 0)
|
|
|
|
{
|
|
|
|
+ pdf_obj *old_obj = NULL;
|
2016-10-26 07:39:34 +02:00
|
|
|
dict = pdf_load_object(ctx, doc, list[i].num, list[i].gen);
|
2016-10-25 18:49:52 +02:00
|
|
|
|
|
|
|
length = pdf_new_int(ctx, doc, list[i].stm_len);
|
|
|
|
- pdf_dict_put(ctx, dict, PDF_NAME_Length, length);
|
|
|
|
- pdf_drop_obj(ctx, length);
|
|
|
|
-
|
|
|
|
+ pdf_dict_get_put_drop(ctx, dict, PDF_NAME_Length, length, &old_obj);
|
|
|
|
+ if (old_obj)
|
|
|
|
+ orphan_object(ctx, doc, old_obj);
|
|
|
|
pdf_drop_obj(ctx, dict);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c
|
2016-10-26 07:39:34 +02:00
|
|
|
index 3de1cd2..6682741 100644
|
2016-10-25 18:49:52 +02:00
|
|
|
--- a/source/pdf/pdf-xref.c
|
|
|
|
+++ b/source/pdf/pdf-xref.c
|
2016-10-26 07:39:34 +02:00
|
|
|
@@ -1626,6 +1626,12 @@ pdf_close_document(fz_context *ctx, pdf_document *doc)
|
2016-10-25 18:49:52 +02:00
|
|
|
|
2016-10-26 07:39:34 +02:00
|
|
|
pdf_drop_resource_tables(ctx, doc);
|
2016-10-25 18:49:52 +02:00
|
|
|
|
2016-10-26 07:39:34 +02:00
|
|
|
+ for (i = 0; i < doc->orphans_count; i++)
|
|
|
|
+ {
|
|
|
|
+ pdf_drop_obj(ctx, doc->orphans[i]);
|
|
|
|
+ }
|
|
|
|
+ fz_free(ctx, doc->orphans);
|
2016-10-25 18:49:52 +02:00
|
|
|
+
|
2016-10-26 07:39:34 +02:00
|
|
|
fz_free(ctx, doc);
|
|
|
|
}
|
|
|
|
|
2016-10-25 18:49:52 +02:00
|
|
|
--
|
2016-10-26 07:39:34 +02:00
|
|
|
2.10.1
|
2016-10-25 18:49:52 +02:00
|
|
|
|