diff options
Diffstat (limited to 'gnu/packages/patches/mupdf-CVE-2016-8674.patch')
-rw-r--r-- | gnu/packages/patches/mupdf-CVE-2016-8674.patch | 165 |
1 files changed, 165 insertions, 0 deletions
diff --git a/gnu/packages/patches/mupdf-CVE-2016-8674.patch b/gnu/packages/patches/mupdf-CVE-2016-8674.patch new file mode 100644 index 0000000000..2a35619761 --- /dev/null +++ b/gnu/packages/patches/mupdf-CVE-2016-8674.patch @@ -0,0 +1,165 @@ +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 + +Patch adapted from upstream source repository: +http://git.ghostscript.com/?p=mupdf.git;h=1e03c06456d997435019fb3526fa2d4be7dbc6ec + +diff --git a/include/mupdf/pdf/document.h b/include/mupdf/pdf/document.h +index f8ef0cd..e8345b7 100644 +--- a/include/mupdf/pdf/document.h ++++ b/include/mupdf/pdf/document.h +@@ -258,6 +258,10 @@ struct pdf_document_s + fz_font **type3_fonts; + + pdf_resource_tables *resources; ++ ++ int orphans_max; ++ int orphans_count; ++ pdf_obj **orphans; + }; + + /* +diff --git a/include/mupdf/pdf/object.h b/include/mupdf/pdf/object.h +index 346a2f1..02d4119 100644 +--- a/include/mupdf/pdf/object.h ++++ b/include/mupdf/pdf/object.h +@@ -109,6 +109,7 @@ pdf_obj *pdf_dict_gets(fz_context *ctx, pdf_obj *dict, const char *key); + 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 +index f2e4551..a0d0d8e 100644 +--- a/source/pdf/pdf-object.c ++++ b/source/pdf/pdf-object.c +@@ -1240,9 +1240,13 @@ pdf_dict_geta(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *abbrev) + 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) + { ++ ++ if (old_val) ++ *old_val = NULL; ++ + RESOLVE(obj); + 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); + } + } + else +@@ -1305,10 +1312,27 @@ pdf_dict_put(fz_context *ctx, pdf_obj *obj, pdf_obj *key, pdf_obj *val) + } + + 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 +index fdd4648..212c8b7 100644 +--- a/source/pdf/pdf-repair.c ++++ b/source/pdf/pdf-repair.c +@@ -259,6 +259,27 @@ pdf_repair_obj_stm(fz_context *ctx, pdf_document *doc, int num, int gen) + } + } + ++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) + { +@@ -520,12 +541,13 @@ pdf_repair_xref(fz_context *ctx, pdf_document *doc) + /* correct stream length for unencrypted documents */ + if (!encrypt && list[i].stm_len >= 0) + { ++ pdf_obj *old_obj = NULL; + dict = pdf_load_object(ctx, doc, list[i].num, list[i].gen); + + 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 +index 3de1cd2..6682741 100644 +--- a/source/pdf/pdf-xref.c ++++ b/source/pdf/pdf-xref.c +@@ -1626,6 +1626,12 @@ pdf_close_document(fz_context *ctx, pdf_document *doc) + + pdf_drop_resource_tables(ctx, doc); + ++ for (i = 0; i < doc->orphans_count; i++) ++ { ++ pdf_drop_obj(ctx, doc->orphans[i]); ++ } ++ fz_free(ctx, doc->orphans); ++ + fz_free(ctx, doc); + } + +-- +2.10.1 + |