aboutsummaryrefslogtreecommitdiff
path: root/gnu/packages/patches/mupdf-CVE-2018-6544.patch
blob: b2c8f849f3ca61e4bd3aa7b9c2b453b2010e53d7 (plain)
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
Fix CVE-2018-6544:

https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2018-6544
https://bugs.ghostscript.com/show_bug.cgi?id=698830
https://bugs.ghostscript.com/show_bug.cgi?id=698965 

Patches copied from upstream source repository:

https://git.ghostscript.com/?p=mupdf.git;h=26527eef77b3e51c2258c8e40845bfbc015e405d
https://git.ghostscript.com/?p=mupdf.git;h=b03def134988da8c800adac1a38a41a1f09a1d89

From b03def134988da8c800adac1a38a41a1f09a1d89 Mon Sep 17 00:00:00 2001
From: Sebastian Rasmussen <sebras@gmail.com>
Date: Thu, 1 Feb 2018 16:36:14 +0100
Subject: [PATCH] Bug 698830: Avoid recursion when loading object streams
 objects.

If there were indirect references in the object stream dictionary and
one of those indirect references referred to an object inside the object
stream itself, mupdf would previously enter recursion only bounded by the
exception stack. After this commit the object stream is checked if it is
marked immediately after being loaded. If it is marked then we terminate
the recursion at this point, if it is not marked then mark it and
attempt to load the desired object within. We also take care to unmark
the stream object when done or upon exception.
---
 source/pdf/pdf-xref.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

diff --git a/source/pdf/pdf-xref.c b/source/pdf/pdf-xref.c
index 723b543c..ed09094c 100644
--- a/source/pdf/pdf-xref.c
+++ b/source/pdf/pdf-xref.c
@@ -1576,6 +1576,19 @@ pdf_load_obj_stm(fz_context *ctx, pdf_document *doc, int num, pdf_lexbuf *buf, i
 	{
 		objstm = pdf_load_object(ctx, doc, num);
 
+		if (pdf_obj_marked(ctx, objstm))
+			fz_throw(ctx, FZ_ERROR_GENERIC, "recursive object stream lookup");
+	}
+	fz_catch(ctx)
+	{
+		pdf_drop_obj(ctx, objstm);
+		fz_rethrow(ctx);
+	}
+
+	fz_try(ctx)
+	{
+		pdf_mark_obj(ctx, objstm);
+
 		count = pdf_to_int(ctx, pdf_dict_get(ctx, objstm, PDF_NAME_N));
 		first = pdf_to_int(ctx, pdf_dict_get(ctx, objstm, PDF_NAME_First));
 
@@ -1655,6 +1668,7 @@ pdf_load_obj_stm(fz_context *ctx, pdf_document *doc, int num, pdf_lexbuf *buf, i
 		fz_drop_stream(ctx, stm);
 		fz_free(ctx, ofsbuf);
 		fz_free(ctx, numbuf);
+		pdf_unmark_obj(ctx, objstm);
 		pdf_drop_obj(ctx, objstm);
 	}
 	fz_catch(ctx)
-- 
2.16.3

From 26527eef77b3e51c2258c8e40845bfbc015e405d Mon Sep 17 00:00:00 2001
From: Sebastian Rasmussen <sebras@gmail.com>
Date: Mon, 29 Jan 2018 02:00:48 +0100
Subject: [PATCH] Bug 698830: Don't drop unkept stream if running out of error
 stack.

Under normal conditions where fz_keep_stream() is called inside
fz_try() we may call fz_drop_stream() in fz_catch() upon exceptions.
The issue comes when fz_keep_stream() has not yet been called but is
dropped in fz_catch(). This happens in the PDF from the bug when
fz_try() runs out of exception stack, and next the code in fz_catch()
runs, dropping the caller's reference to the filter chain stream!

The simplest way of fixing this it to always keep the filter chain
stream before fz_try() is called. That way fz_catch() may drop the
stream whether an exception has occurred or if the fz_try() ran out of
exception stack.
---
 source/pdf/pdf-stream.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/source/pdf/pdf-stream.c b/source/pdf/pdf-stream.c
index c89da5c4..c6ba7ad3 100644
--- a/source/pdf/pdf-stream.c
+++ b/source/pdf/pdf-stream.c
@@ -303,14 +303,13 @@ pdf_open_raw_filter(fz_context *ctx, fz_stream *chain, pdf_document *doc, pdf_ob
 		*orig_gen = 0;
 	}
 
-	fz_var(chain);
+	chain = fz_keep_stream(ctx, chain);
 
 	fz_try(ctx)
 	{
 		len = pdf_to_int(ctx, pdf_dict_get(ctx, stmobj, PDF_NAME_Length));
 
-		/* don't close chain when we close this filter */
-		chain2 = fz_keep_stream(ctx, chain);
+		chain2 = chain;
 		chain = NULL;
 		chain = fz_open_null(ctx, chain2, len, offset);
 
-- 
2.16.3