Fix for 
https://blogs.gentoo.org/ago/2016/09/22/mupdf-use-after-free-in-pdf_to_num-pdf-object-c/.
From 97312c3c9e13688081aa513d1c94a9fff1274f75 Mon Sep 17 00:00:00 2001
From: Kei Kebreau <k...@openmailbox.org>
Date: Tue, 25 Oct 2016 12:49:52 -0400
Subject: [PATCH] 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.
---
 gnu/local.mk                                   |   1 +
 gnu/packages/patches/mupdf-CVE-2016-8674.patch | 166 +++++++++++++++++++++++++
 gnu/packages/pdf.scm                           |   3 +-
 3 files changed, 169 insertions(+), 1 deletion(-)
 create mode 100644 gnu/packages/patches/mupdf-CVE-2016-8674.patch

diff --git a/gnu/local.mk b/gnu/local.mk
index 0d400e9..53c2bda 100644
--- a/gnu/local.mk
+++ b/gnu/local.mk
@@ -711,6 +711,7 @@ dist_patch_DATA =                                           
\
   %D%/packages/patches/mupdf-build-with-openjpeg-2.1.patch     \
   %D%/packages/patches/mupdf-CVE-2016-6265.patch               \
   %D%/packages/patches/mupdf-CVE-2016-6525.patch               \
+  %D%/packages/patches/mupdf-CVE-2016-8674.patch               \
   %D%/packages/patches/mupen64plus-ui-console-notice.patch     \
   %D%/packages/patches/musl-CVE-2016-8859.patch                        \
   %D%/packages/patches/mutt-store-references.patch             \
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 0000000..62e4a02
--- /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
+
diff --git a/gnu/packages/pdf.scm b/gnu/packages/pdf.scm
index 461472a..42547df 100644
--- a/gnu/packages/pdf.scm
+++ b/gnu/packages/pdf.scm
@@ -489,7 +489,8 @@ extracting content or merging files.")
           "1k64pdapyj8a336jw3j61fhn0rp4q6az7d0dqp9r5n3d9rgwa5c0"))
         (patches (search-patches "mupdf-build-with-openjpeg-2.1.patch"
                                  "mupdf-CVE-2016-6265.patch"
-                                 "mupdf-CVE-2016-6525.patch"))
+                                 "mupdf-CVE-2016-6525.patch"
+                                 "mupdf-CVE-2016-8674.patch"))
         (modules '((guix build utils)))
         (snippet
             ;; Delete all the bundled libraries except for mujs, which is
-- 
2.10.1

Attachment: signature.asc
Description: PGP signature

Reply via email to