aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonardo Arena <rnalrd@alpinelinux.org>2019-09-16 10:18:32 +0000
committerLeonardo Arena <rnalrd@alpinelinux.org>2019-09-16 10:18:41 +0000
commit98ae0e5badc623bf92842b4d4c3c5692fd64c081 (patch)
treeeab1d05c610797e605fdc4584d392370eee75ebe
parent88439aa840343df3a5af208bea6ca325a1b1821a (diff)
downloadaports-98ae0e5badc623bf92842b4d4c3c5692fd64c081.tar.bz2
aports-98ae0e5badc623bf92842b4d4c3c5692fd64c081.tar.xz
main/ghostscript: security fix (CVE-2019-14817)
Ref #10776
-rw-r--r--main/ghostscript/0001-PDF-interpreter-Decode-ToUnicode-entries-of-the-form.patch265
-rw-r--r--main/ghostscript/APKBUILD10
-rw-r--r--main/ghostscript/CVE-2019-14817.patch231
3 files changed, 504 insertions, 2 deletions
diff --git a/main/ghostscript/0001-PDF-interpreter-Decode-ToUnicode-entries-of-the-form.patch b/main/ghostscript/0001-PDF-interpreter-Decode-ToUnicode-entries-of-the-form.patch
new file mode 100644
index 0000000000..df5500350d
--- /dev/null
+++ b/main/ghostscript/0001-PDF-interpreter-Decode-ToUnicode-entries-of-the-form.patch
@@ -0,0 +1,265 @@
+From 0bafbd9c1273fab0dc79fd20db0ffc4443683f96 Mon Sep 17 00:00:00 2001
+From: Ken Sharp <ken.sharp@artifex.com>
+Date: Mon, 29 Apr 2019 11:14:06 +0100
+Subject: [PATCH] PDF interpreter - Decode ToUnicode entries of the form
+ /Identity-H/V
+
+Bug #701003 "Text searchability broken due to omission of /ToUnicode /Identity-H"
+
+The PDF references from 1.2 too 2.0 all state that the value associated
+with a ToUnicode key in a FontDescriptor must be a stream object. However
+this file (and one case seen previously, bug 687351) have FontDescriptor
+dictionaries where the value associated with a /ToUnicode key is a
+name object, in both cases /Identity-H.
+
+Although this is clearly not legal, Acrobat not only tolerates it, it
+actually uses it for search/copy/paste (see bug 701003 for details).
+Without the key Acrobat is unable to successfully search the output file.
+
+We can't simply preserve the name object as a ToUnicode value; when
+handling ToUnicode we actually decode the CMap and build a
+GlyphNames2Unicode map (an internal representation of the G2U data
+produced by the Microsoft PostScript printer driver). When writing the
+output file we use that information to get a Unicode value for each
+character we write, and build a new ToUnicode CMap using that.
+
+This commit tackles the problem by pre-scanning for a name object and
+then checking to see if its Identity-H or Identity-V (although we have
+not seen an Identity-V, there seems no reason why it wouldn't be
+equally valid). If we find either of these then we construct a
+GlyphNames2Unicode table for all possible values (0 - 65535) and store
+that with the font as normal. When we write the output file we only
+write the required entries for the subset font, so we write a now
+completely legal ToUnicode CMap, and Acrobat is equally happy with that
+as the original name.
+
+If the ToUnicode value isn't a name object, or isn't one of the
+identities then we proceed as before. This means we will print a
+warning for non conforming ToUnicode entries and ignore them.
+---
+ Resource/Init/pdf_font.ps | 200 ++++++++++++++++++++++++--------------
+ 1 file changed, 129 insertions(+), 71 deletions(-)
+
+diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
+index 0e802d393..964d54c1e 100644
+--- a/Resource/Init/pdf_font.ps
++++ b/Resource/Init/pdf_font.ps
+@@ -621,86 +621,144 @@ currentdict end readonly def
+ PDFDEBUG {
+ (.processToUnicode beg) =
+ } if
+- 2 index /ToUnicode knownoget {
+- dup type /dicttype eq { dup /File known not } { //true } ifelse {
+- % We undefine wrong /Length and define /File in stream dictionaries.
+- % Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect.
+- ( **** Warning: Ignoring bad ToUnicode CMap.\n) pdfformatwarning
+- pop
++
++ 2 index /ToUnicode knownoget
++ {
++ dup type /nametype eq {
++ % This is contrary to the specification but it seems that Acrobat at least will accept
++ % a ToUnicode with a value of Identity-H *and* will use that for search, copy/paste.
++ % We can't pass through a name, so the best we can do is build a GlyphNames2Unicode
++ % map matching that which would have been generated by a full 16-bit Identity CMap
++ %
++ % See bug numbers 701003 and 687351
++ %
++ dup /Identity-H eq 1 index /Identity-V eq or{
++ pop
++ 1 index /FontInfo .knownget not {
++ currentglobal 2 index dup gcheck setglobal
++ /FontInfo 5 dict dup 5 1 roll .forceput
++ setglobal
++ } if
++ dup /GlyphNames2Unicode .knownget not {
++ //true % No existing G2U, make one
++ } {
++ dup wcheck {
++ //false % Existing, writeable G2U, don't make new one
++ } {
++ pop //true % Existing read only G2U, make new one
++ } ifelse
++ } ifelse
++ {
++ currentglobal exch dup gcheck setglobal
++ dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput
++ 3 2 roll setglobal
++ } if % font-res font-dict encoding|null font-info g2u
++
++ 0 1 65535{
++ % g2u index
++ dup dup 256 mod exch 256 idiv % g2u index lo-byte hi-byte
++ 2 string dup 0 4 -1 roll % g2u index lo-byte () () 0 hi-byte
++ put % g2u index lo-byte (x)
++ dup 1 % g2u index lo-byte (x) (x) 1
++ 4 -1 roll put % g2u index (x) (x) 1 lo-byte -> dict index (xx)
++ 2 index % g2u index (xx) dict
++ 3 1 roll % g2u g2u index (xx)
++ put % g2u
++ } for
++ pop % font-res font-dict encoding|null font-info
++ pop % font-res font-dict encoding|null
++ //false % We built a GlyphNames2Unicode table, don't need to process further
++ }{
++ //true % name is not Identity-V or H, fail by falling through
++ }ifelse
+ } {
+- /PDFScanRules .getuserparam dup //null eq {
+- pop //PDFScanRules_null
+- } {
+- 1 dict dup /PDFScanRules 4 -1 roll put
+- } ifelse
+- //PDFScanRules_true setuserparams
+- PDFfile fileposition
+- 3 -1 roll
+- count 1 sub
+- countdictstack
+- { //false resolvestream
+- % Following Acrobat we ignore everything outside
+- % begincodespacerange .. endcmap.
+- dup 0 (begincodespacerange) /SubFileDecode filter flushfile
+- /CIDInit /ProcSet findresource begin
+- //ToUnicodeCMapReader begin
+- 12 dict begin
+- /CMapType 2 def
+- mark exch % emulate 'begincodespacerange'
+- 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn
+- endcmap
+- userdict /.lastToUnicode currentdict put
+- end end end
+- }
++ //true
++ } ifelse % not a name, try as a dictionary (as specified)
+
+- PDFSTOPONERROR {
+- { exec } 0 get
+- //false
+- 5 -2 roll
+- 5
++ % If the ToUnicode isn't a name, or the name isn't Identity-V or -H then follow the specification
++ % If its not a dictionary type throw an error, otherwise decode it and build a GlyphNames2Unicode
++ %
++ {
++ dup type /dicttype eq { dup /File known not } { //true } ifelse {
++ % We undefine wrong /Length and define /File in stream dictionaries.
++ % Bug687351.pdf defines /ToUnicode /Identity-H, what is incorrect.
++ ( **** Warning: Ignoring bad ToUnicode CMap.\n) pdfformatwarning
++ pop
+ } {
+- { stopped } 0 get
+- 4 2 roll
+- 4
+- } ifelse
+- array astore cvx exec
++ /PDFScanRules .getuserparam dup //null eq {
++ pop //PDFScanRules_null
++ } {
++ 1 dict dup /PDFScanRules 4 -1 roll put
++ } ifelse
++ //PDFScanRules_true setuserparams
++ PDFfile fileposition
++ 3 -1 roll
++ count 1 sub
++ countdictstack
++ { //false resolvestream
++ % Following Acrobat we ignore everything outside
++ % begincodespacerange .. endcmap.
++ dup 0 (begincodespacerange) /SubFileDecode filter flushfile
++ /CIDInit /ProcSet findresource begin
++ //ToUnicodeCMapReader begin
++ 12 dict begin
++ /CMapType 2 def
++ mark exch % emulate 'begincodespacerange'
++ 0 (endcmap) /SubFileDecode filter cvx /begincmap cvx exch 2 .execn
++ endcmap
++ userdict /.lastToUnicode currentdict put
++ end end end
++ }
+
+- countdictstack exch sub 0 .max { end } repeat
+- count exch sub 2 sub 0 .max { exch pop } repeat
+- 3 1 roll % Stach the stop flag.
+- PDFfile exch setfileposition
+- setuserparams
+- {
+- ( **** Warning: Failed to read ToUnicode CMap.\n) pdfformatwarning
+- } {
+- 1 index /FontInfo .knownget not {
+- currentglobal 2 index dup gcheck setglobal
+- /FontInfo 5 dict dup 5 1 roll .forceput
+- setglobal
+- } if
+- dup /GlyphNames2Unicode .knownget not {
+- //true % No existing G2U, make one
++ PDFSTOPONERROR {
++ { exec } 0 get
++ //false
++ 5 -2 roll
++ 5
++ } {
++ { stopped } 0 get
++ 4 2 roll
++ 4
++ } ifelse
++ array astore cvx exec
++
++ countdictstack exch sub 0 .max { end } repeat
++ count exch sub 2 sub 0 .max { exch pop } repeat
++ 3 1 roll % Stach the stop flag.
++ PDFfile exch setfileposition
++ setuserparams
++ {
++ ( **** Warning: Failed to read ToUnicode CMap.\n) pdfformatwarning
+ } {
+- dup wcheck {
+- //false % Existing, writeable G2U, don't make new one
++ 1 index /FontInfo .knownget not {
++ currentglobal 2 index dup gcheck setglobal
++ /FontInfo 5 dict dup 5 1 roll .forceput
++ setglobal
++ } if
++ dup /GlyphNames2Unicode .knownget not {
++ //true % No existing G2U, make one
+ } {
+- pop //true % Existing read only G2U, make new one
++ dup wcheck {
++ //false % Existing, writeable G2U, don't make new one
++ } {
++ pop //true % Existing read only G2U, make new one
++ } ifelse
+ } ifelse
++ {
++ currentglobal exch dup gcheck setglobal
++ dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput
++ 3 2 roll setglobal
++ } if % font-res font-dict encoding|null font-info g2u
++ exch pop exch % font-res font-dict g2u encoding|null
++ userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap
++ .convert_ToUnicode-into-g2u % font-res font-dict
++ //null % font-res font-dict //null
+ } ifelse
+- {
+- currentglobal exch dup gcheck setglobal
+- dup /GlyphNames2Unicode 100 dict dup 4 1 roll .forceput
+- 3 2 roll setglobal
+- } if % font-res font-dict encoding|null font-info g2u
+- exch pop exch % font-res font-dict g2u encoding|null
+- userdict /.lastToUnicode get % font-res font-dict g2u Encoding|null CMap
+- .convert_ToUnicode-into-g2u % font-res font-dict
+- //null % font-res font-dict //null
+ } ifelse
+- } ifelse
+- } if
+- PDFDEBUG {
+- (.processToUnicode end) =
++ } if
++ PDFDEBUG {
++ (.processToUnicode end) =
++ } if
+ } if
+ } if
+ } stopped
+--
+2.23.0
+
diff --git a/main/ghostscript/APKBUILD b/main/ghostscript/APKBUILD
index 26b4e9fc19..6d3dcdfb41 100644
--- a/main/ghostscript/APKBUILD
+++ b/main/ghostscript/APKBUILD
@@ -2,7 +2,7 @@
# Maintainer: Cameron Banta <cbanta@gmail.com>
pkgname=ghostscript
pkgver=9.27
-pkgrel=3
+pkgrel=4
pkgdesc="An interpreter for the PostScript language and for PDF"
url="https://ghostscript.com/"
arch="all"
@@ -18,9 +18,13 @@ source="https://github.com/ArtifexSoftware/ghostpdl-downloads/releases/download/
fix-sprintf.patch
CVE-2019-10216.patch
forceput-inaccessible.patch
+ 0001-PDF-interpreter-Decode-ToUnicode-entries-of-the-form.patch
+ CVE-2019-14817.patch
"
# secfixes:
+# 9.27-r4:
+# - CVE-2019-14817
# 9.27-r3:
# - CVE-2019-14811
# - CVE-2019-14812
@@ -136,4 +140,6 @@ sha512sums="9ad7bd24b6d9b7d258e943783817be036a2e0234517baffa1016804ef9b6f3062fb5
70721e3a335afa5e21d4e6cf919119010bd4544a03ab8f53f5325c173902221ad9b88c118b4bfeee80b3e1956bcdbaf4c53f64ae7fb81f5ba57dbc956750c482 ghostscript-system-zlib.patch
beefcf395f7f828e1b81c088022c08a506e218f27535b9de01e0f0edf7979b435316c318fa676771630f6ad16ff1ab059cd68aa128ed97e5a9f2f3fa840200c4 fix-sprintf.patch
f89744b17922b7d9c04c6de69ce35fa621732e4373eccc158b7ff6a9e56d2cf0bbea30c28119f4808864ca584e94342e5125d7bcc6195252455b5f223f379e3f CVE-2019-10216.patch
-d7045aa5a02a3fc882552da0b9a60ea565a36d5d038cdf576dc7188158dc05a470ce9fa40bdf1e1003a48995f6707431980910372da549918caf789eb3a2f81f forceput-inaccessible.patch"
+d7045aa5a02a3fc882552da0b9a60ea565a36d5d038cdf576dc7188158dc05a470ce9fa40bdf1e1003a48995f6707431980910372da549918caf789eb3a2f81f forceput-inaccessible.patch
+0ec65d29eb7ade7a8c02190fc5358faf257f63dc50b30d222b231aed496c8ac1fb7c0710e78117e10a16886dfcaccab610afb434efbbd557f63396c12ccd5d64 0001-PDF-interpreter-Decode-ToUnicode-entries-of-the-form.patch
+deed829b14223b2f99d49aea5575c9ad855f6815d238502d3109849acac239eb312fd89e802e12a85fe7e92375694c42422240a6e1759ecfd094762eccaed826 CVE-2019-14817.patch"
diff --git a/main/ghostscript/CVE-2019-14817.patch b/main/ghostscript/CVE-2019-14817.patch
new file mode 100644
index 0000000000..57db1edb11
--- /dev/null
+++ b/main/ghostscript/CVE-2019-14817.patch
@@ -0,0 +1,231 @@
+From cd1b1cacadac2479e291efe611979bdc1b3bdb19 Mon Sep 17 00:00:00 2001
+From: Ken Sharp <ken.sharp@artifex.com>
+Date: Wed, 21 Aug 2019 10:10:51 +0100
+Subject: [PATCH] PDF interpreter - review .forceput security
+
+Bug #701450 "Safer Mode Bypass by .forceput Exposure in .pdfexectoken"
+
+By abusing the error handler it was possible to get the PDFDEBUG portion
+of .pdfexectoken, which uses .forceput left readable.
+
+Add an executeonly appropriately to make sure that clause isn't readable
+no mstter what.
+
+Review all the uses of .forceput searching for similar cases, add
+executeonly as required to secure those. All cases in the PostScript
+support files seem to be covered already.
+---
+ Resource/Init/pdf_base.ps | 2 +-
+ Resource/Init/pdf_draw.ps | 14 +++++++-------
+ Resource/Init/pdf_font.ps | 29 ++++++++++++++++-------------
+ Resource/Init/pdf_main.ps | 6 +++---
+ Resource/Init/pdf_ops.ps | 11 ++++++-----
+ 5 files changed, 33 insertions(+), 29 deletions(-)
+
+diff --git a/Resource/Init/pdf_base.ps b/Resource/Init/pdf_base.ps
+index 2e28cdd..02503ee 100644
+--- a/Resource/Init/pdf_base.ps
++++ b/Resource/Init/pdf_base.ps
+@@ -157,7 +157,7 @@ currentdict /num-chars-dict .undef
+ {
+ dup ==only () = flush
+ } ifelse % PDFSTEP
+- } if % PDFDEBUG
++ } executeonly if % PDFDEBUG
+ 2 copy .knownget {
+ exch pop exch pop exch pop exec
+ } {
+diff --git a/Resource/Init/pdf_draw.ps b/Resource/Init/pdf_draw.ps
+index 11eb485..fe3fc56 100644
+--- a/Resource/Init/pdf_draw.ps
++++ b/Resource/Init/pdf_draw.ps
+@@ -501,8 +501,8 @@ end
+ ( Output may be incorrect.\n) pdfformaterror
+ //pdfdict /.gs_warning_issued //true .forceput
+ PDFSTOPONERROR { /gs /undefined signalerror } if
+- } if
+- }
++ } executeonly if
++ } executeonly
+ ifelse
+ } bind executeonly def
+
+@@ -1152,7 +1152,7 @@ currentdict end readonly def
+ .setglobal
+ pdfformaterror
+ } executeonly ifelse
+- }
++ } executeonly
+ {
+ currentglobal //pdfdict gcheck .setglobal
+ //pdfdict /.Qqwarning_issued //true .forceput
+@@ -1160,8 +1160,8 @@ currentdict end readonly def
+ pdfformaterror
+ } executeonly ifelse
+ end
+- } ifelse
+- } loop
++ } executeonly ifelse
++ } executeonly loop
+ {
+ (\n **** Error: File has unbalanced q/Q operators \(too many q's\)\n Output may be incorrect.\n)
+ //pdfdict /.Qqwarning_issued .knownget
+@@ -1175,14 +1175,14 @@ currentdict end readonly def
+ .setglobal
+ pdfformaterror
+ } executeonly ifelse
+- }
++ } executeonly
+ {
+ currentglobal //pdfdict gcheck .setglobal
+ //pdfdict /.Qqwarning_issued //true .forceput
+ .setglobal
+ pdfformaterror
+ } executeonly ifelse
+- } if
++ } executeonly if
+ pop
+
+ % restore pdfemptycount
+diff --git a/Resource/Init/pdf_font.ps b/Resource/Init/pdf_font.ps
+index da07da5..81b7af1 100644
+--- a/Resource/Init/pdf_font.ps
++++ b/Resource/Init/pdf_font.ps
+@@ -638,7 +638,7 @@ currentdict end readonly def
+ currentglobal 2 index dup gcheck setglobal
+ /FontInfo 5 dict dup 5 1 roll .forceput
+ setglobal
+- } if
++ } executeonly if
+ dup /GlyphNames2Unicode .knownget not {
+ //true % No existing G2U, make one
+ } {
+@@ -668,10 +668,12 @@ currentdict end readonly def
+ pop % font-res font-dict encoding|null font-info
+ pop % font-res font-dict encoding|null
+ //false % We built a GlyphNames2Unicode table, don't need to process further
+- }{
++ } executeonly
++ {
+ //true % name is not Identity-V or H, fail by falling through
+ }ifelse
+- } {
++ } executeonly
++ {
+ //true
+ } ifelse % not a name, try as a dictionary (as specified)
+
+@@ -759,9 +761,9 @@ currentdict end readonly def
+ PDFDEBUG {
+ (.processToUnicode end) =
+ } if
+- } if
+- } if
+- } stopped
++ } executeonly if
++ } executeonly if
++ } executeonly stopped
+ {
+ .dstackdepth 1 countdictstack 1 sub
+ {pop end} for
+@@ -1298,19 +1300,20 @@ currentdict /eexec_pdf_param_dict .undef
+ //pdfdict /.Qqwarning_issued //true .forceput
+ } executeonly if
+ Q
+- } repeat
++ } executeonly repeat
+ Q
+- } PDFfile fileposition 2 .execn % Keep pdfcount valid.
++ } executeonly PDFfile fileposition 2 .execn % Keep pdfcount valid.
+ PDFfile exch setfileposition
+- } ifelse
+- } {
++ } executeonly ifelse
++ } executeonly
++ {
+ % PDF Type 3 fonts don't use .notdef
+ % d1 implementation adjusts the width as needed
+ 0 0 0 0 0 0
+ pdfopdict /d1 get exec
+ } ifelse
+ end end
+- } bdef
++ } executeonly bdef
+ dup currentdict Encoding .processToUnicode
+ currentdict end .completefont exch pop
+ } bind executeonly odef
+@@ -2124,9 +2127,9 @@ currentdict /CMap_read_dict undef
+ (Will continue, but content may be missing.) = flush
+ } ifelse
+ } if
+- } if
++ } executeonly if
+ /findresource cvx /undefined signalerror
+- } loop
++ } executeonly loop
+ } bind executeonly odef
+
+ /buildCIDType0 { % <CIDFontType0-font-resource> buildCIDType0 <font>
+diff --git a/Resource/Init/pdf_main.ps b/Resource/Init/pdf_main.ps
+index 00d7e36..7690bae 100644
+--- a/Resource/Init/pdf_main.ps
++++ b/Resource/Init/pdf_main.ps
+@@ -2771,15 +2771,15 @@ currentdict /PDF2PS_matrix_key undef
+ .setglobal
+ pdfformaterror
+ } executeonly ifelse
+- }
++ } executeonly
+ {
+ currentglobal //pdfdict gcheck .setglobal
+ //pdfdict /.Qqwarning_issued //true .forceput
+ .setglobal
+ pdfformaterror
+ } executeonly ifelse
+- } if
+- } if
++ } executeonly if
++ } executeonly if
+ pop
+ count PDFexecstackcount sub { pop } repeat
+ (after exec) VMDEBUG
+diff --git a/Resource/Init/pdf_ops.ps b/Resource/Init/pdf_ops.ps
+index a15c8c6..d594035 100644
+--- a/Resource/Init/pdf_ops.ps
++++ b/Resource/Init/pdf_ops.ps
+@@ -192,14 +192,14 @@ currentdict /gput_always_allow .undef
+ .setglobal
+ pdfformaterror
+ } executeonly ifelse
+- }
++ } executeonly
+ {
+ currentglobal //pdfdict gcheck .setglobal
+ //pdfdict /.Qqwarning_issued //true .forceput
+ .setglobal
+ pdfformaterror
+ } executeonly ifelse
+- } if
++ } executeonly if
+ } bind executeonly odef
+
+ % Save PDF gstate
+@@ -446,11 +446,12 @@ currentdict /gput_always_allow .undef
+ dup type /booleantype eq {
+ .currentSMask type /dicttype eq {
+ .currentSMask /Processed 2 index .forceput
++ } executeonly
++ {
++ .setSMask
++ }ifelse
+ } executeonly
+ {
+- .setSMask
+- }ifelse
+- }{
+ .setSMask
+ }ifelse
+
+--
+2.9.1
+