summary refs log tree commit diff
path: root/gnu/packages/patches/mupdf-CVE-2016-8674.patch
diff options
context:
space:
mode:
authorKei Kebreau <kei@openmailbox.org>2016-10-25 12:49:52 -0400
committerKei Kebreau <kei@openmailbox.org>2016-10-25 12:50:50 -0400
commit47a04fca999b91309d196afc9ebf4d8ac6f2083f (patch)
tree1ce9d8388097122e844816073fc914b7238b61ca /gnu/packages/patches/mupdf-CVE-2016-8674.patch
parent4b12fe5caba259bbf32865001c94a1de14965c66 (diff)
downloadguix-47a04fca999b91309d196afc9ebf4d8ac6f2083f.tar.gz
gnu: mupdf: Fix CVE-2016-8674.
* gnu/packages/patches/mupdf-CVE-2016-8674.patch: New file.
* gnu/local.mk (dist_patch_DATA): Add it.
* gnu/packages/pdf.scm (mupdf): Use it.
Diffstat (limited to 'gnu/packages/patches/mupdf-CVE-2016-8674.patch')
-rw-r--r--gnu/packages/patches/mupdf-CVE-2016-8674.patch166
1 files changed, 166 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..62e4a0237a
--- /dev/null
+++ b/gnu/packages/patches/mupdf-CVE-2016-8674.patch
@@ -0,0 +1,166 @@
+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 copied 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 aabf05f..0078c4a 100644
+--- a/include/mupdf/pdf/document.h
++++ b/include/mupdf/pdf/document.h
+@@ -269,6 +269,10 @@ struct pdf_document_s
+ 		fz_hash_table *images;
+ 		fz_hash_table *fonts;
+ 	} 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 5bc3dca..bf57455 100644
+--- a/include/mupdf/pdf/object.h
++++ b/include/mupdf/pdf/object.h
+@@ -110,6 +110,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 b4e33f3..1c19ba4 100644
+--- a/source/pdf/pdf-object.c
++++ b/source/pdf/pdf-object.c
+@@ -1265,11 +1265,14 @@ 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)
+ {
+ 	int i;
+ 
++	if (old_val)
++		*old_val = NULL;
++
+ 	RESOLVE(obj);
+ 	if (!OBJ_IS_DICT(obj))
+ 		fz_throw(ctx, FZ_ERROR_GENERIC, "not a dict (%s)", pdf_objkindstr(obj));
+@@ -1295,7 +1298,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
+@@ -1316,10 +1322,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 690bf15..167f609 100644
+--- a/source/pdf/pdf-repair.c
++++ b/source/pdf/pdf-repair.c
+@@ -260,6 +260,27 @@ pdf_repair_obj_stm(fz_context *ctx, pdf_document *doc, int stm_num)
+ 	}
+ }
+ 
++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)
+ {
+@@ -528,12 +549,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);
+ 
+ 				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 7d21775..0cf20d4 100644
+--- a/source/pdf/pdf-xref.c
++++ b/source/pdf/pdf-xref.c
+@@ -1620,6 +1620,12 @@ pdf_drop_document_imp(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);
+ 	}
+ 	fz_always(ctx)
+-- 
+2.9.1
+