unofficial mirror of guix-devel@gnu.org 
 help / color / mirror / code / Atom feed
blob 2a356197610926b7c4361af656d21e98caa2bd03 4961 bytes (raw)
name: gnu/packages/patches/mupdf-CVE-2016-8674.patch 	 # note: path name is non-authoritative(*)

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
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


debug log:

solving 2a35619 ...
found 2a35619 in https://git.savannah.gnu.org/cgit/guix.git

(*) Git path names are given by the tree(s) the blob belongs to.
    Blobs themselves have no identifier aside from the hash of its contents.^

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/guix.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).