From 6fa1cb4d25d8298d123d6a2448723185487608e6 Mon Sep 17 00:00:00 2001 From: jinzhimin369 Date: Sat, 23 Jan 2021 17:00:02 +0800 Subject: [PATCH] fix CVE-2018-16646 CVE-2018-18897 CVE-2018-19060 CVE-2018-20481 CVE-2019-14494 CVE-2019-7310 (cherry picked from commit b401fd8d9b1be3d77fd272151cc405a179f81497) --- backport-CVE-2018-16646.patch | 61 ++++++++++++++++++++++++++++++++ backport-CVE-2018-18897.patch | 63 +++++++++++++++++++++++++++++++++ backport-CVE-2018-19060.patch | 66 +++++++++++++++++++++++++++++++++++ backport-CVE-2018-20481.patch | 49 ++++++++++++++++++++++++++ backport-CVE-2019-14494.patch | 28 +++++++++++++++ backport-CVE-2019-7310.patch | 15 ++++++++ poppler.spec | 22 ++++++++++-- 7 files changed, 302 insertions(+), 2 deletions(-) create mode 100644 backport-CVE-2018-16646.patch create mode 100644 backport-CVE-2018-18897.patch create mode 100644 backport-CVE-2018-19060.patch create mode 100644 backport-CVE-2018-20481.patch create mode 100644 backport-CVE-2019-14494.patch create mode 100644 backport-CVE-2019-7310.patch diff --git a/backport-CVE-2018-16646.patch b/backport-CVE-2018-16646.patch new file mode 100644 index 0000000..067871a --- /dev/null +++ b/backport-CVE-2018-16646.patch @@ -0,0 +1,61 @@ +From 3d35d209c19c1d3b09b794a0c863ba5de44a9c0a Mon Sep 17 00:00:00 2001 +From: Marek Kasik +Date: Mon, 29 Oct 2018 17:44:47 +0100 +Subject: [PATCH] Avoid cycles in PDF parsing + +Mark objects being processed in Parser::makeStream() as being processed +and check the mark when entering this method to avoid processing +of the same object recursively. +--- + poppler/Parser.cc | 15 +++++++++++++++ + poppler/XRef.h | 1 + + 2 files changed, 16 insertions(+) + +diff --git a/poppler/Parser.cc b/poppler/Parser.cc +index bd4845ab6..8f48efbe3 100644 +--- a/poppler/Parser.cc ++++ b/poppler/Parser.cc +@@ -197,6 +197,18 @@ Stream *Parser::makeStream(Object &&dict, Guchar *fileKey, + Stream *str; + Goffset length; + Goffset pos, endPos; ++ XRefEntry *entry; ++ ++ if (xref && (entry = xref->getEntry(objNum, false))) { ++ if (!entry->getFlag(XRefEntry::Parsing) || ++ (objNum == 0 && objGen == 0)) { ++ entry->setFlag(XRefEntry::Parsing, true); ++ } else { ++ error(errSyntaxError, getPos(), ++ "Object '{0:d} {1:d} obj' is being already parsed", objNum, objGen); ++ return nullptr; ++ } ++ } + + // get stream start position + lexer->skipToNextLine(); +@@ -278,6 +290,9 @@ Stream *Parser::makeStream(Object &&dict, Guchar *fileKey, + // get filters + str = str->addFilters(str->getDict(), recursion); + ++ if (entry) ++ entry->setFlag(XRefEntry::Parsing, false); ++ + return str; + } + +diff --git a/poppler/XRef.h b/poppler/XRef.h +index 11ee5e033..2eb2f9fdc 100644 +--- a/poppler/XRef.h ++++ b/poppler/XRef.h +@@ -65,6 +65,7 @@ struct XRefEntry { + enum Flag { + // Regular flags + Updated, // Entry was modified ++ Parsing, // Entry is currently being parsed + + // Special flags -- available only after xref->scanSpecialFlags() is run + Unencrypted, // Entry is stored in unencrypted form (meaningless in unencrypted documents) +-- +GitLab + diff --git a/backport-CVE-2018-18897.patch b/backport-CVE-2018-18897.patch new file mode 100644 index 0000000..a92ac43 --- /dev/null +++ b/backport-CVE-2018-18897.patch @@ -0,0 +1,63 @@ +From e07c8b4784234383cb5ddcf1133ea91a772506e2 Mon Sep 17 00:00:00 2001 +From: Adam Reichold +Date: Tue, 1 Jan 2019 10:54:40 +0100 +Subject: [PATCH] Avoid global display profile state becoming an uncontrolled + memory leak by enforcing single initialization. Closes #654 + +--- + poppler/GfxState.cc | 9 +++++++++ + qt5/src/poppler-qt5.h | 4 ++++ + 2 files changed, 13 insertions(+) + +diff --git a/poppler/GfxState.cc b/poppler/GfxState.cc +index 87b7ce03d..4e3ccbfda 100644 +--- a/poppler/GfxState.cc ++++ b/poppler/GfxState.cc +@@ -226,6 +226,10 @@ static unsigned int getCMSNChannels(cmsColorSpaceSignature cs); + static cmsHPROFILE loadColorProfile(const char *fileName); + + void GfxColorSpace::setDisplayProfile(void *displayProfileA) { ++ if (displayProfile != nullptr) { ++ error(errInternal, -1, "The display color profile can only be set once before any rendering is done."); ++ return; ++ } + displayProfile = displayProfileA; + if (displayProfile != nullptr) { + cmsHTRANSFORM transform; +@@ -249,6 +253,11 @@ void GfxColorSpace::setDisplayProfile(void *displayProfileA) { + } + + void GfxColorSpace::setDisplayProfileName(GooString *name) { ++ if (displayProfile != nullptr) { ++ error(errInternal, -1, "The display color profile can only be set before any rendering is done."); ++ return; ++ } ++ delete displayProfileName; + displayProfileName = name->copy(); + } + +diff --git a/qt5/src/poppler-qt5.h b/qt5/src/poppler-qt5.h +index 4f06c47e2..ddac7dfb7 100644 +--- a/qt5/src/poppler-qt5.h ++++ b/qt5/src/poppler-qt5.h +@@ -1102,6 +1102,8 @@ delete it; + + \param outputProfileA is a \c cmsHPROFILE of the LCMS library. + ++ \note This should be called before any rendering happens and only once during the lifetime of the current process. ++ + \since 0.12 + */ + void setColorDisplayProfile(void *outputProfileA); +@@ -1110,6 +1112,8 @@ delete it; + + \param name is the name of the display profile to set. + ++ \note This should be called before any rendering happens. ++ + \since 0.12 + */ + void setColorDisplayProfileName(const QString &name); +-- +GitLab + diff --git a/backport-CVE-2018-19060.patch b/backport-CVE-2018-19060.patch new file mode 100644 index 0000000..e7d516a --- /dev/null +++ b/backport-CVE-2018-19060.patch @@ -0,0 +1,66 @@ +diff -Nuar poppler-0.67.0/utils/pdfdetach.cc poppler-0.67.0-old/utils/pdfdetach.cc +--- poppler-0.67.0/utils/pdfdetach.cc 2021-01-18 15:08:35.960000000 +0800 ++++ poppler-0.67.0-old/utils/pdfdetach.cc 2021-01-18 15:29:05.580000000 +0800 +@@ -190,14 +190,18 @@ + fileSpec = static_cast(embeddedFiles->get(i)); + printf("%d: ", i+1); + s1 = fileSpec->getFileName(); +- if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getChar(1) & 0xff) == 0xff) { ++ if (!s1) { ++ exitCode = 3; ++ goto err2; ++ } ++ if (s1->hasUnicodeMarker()) { + isUnicode = gTrue; + j = 2; + } else { + isUnicode = gFalse; + j = 0; + } +- while (j < fileSpec->getFileName()->getLength()) { ++ while (j < s1->getLength()) { + if (isUnicode) { + u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j+1) & 0xff); + j += 2; +@@ -227,14 +231,18 @@ + p = path; + } + s1 = fileSpec->getFileName(); +- if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getChar(1) & 0xff) == 0xff) { ++ if (!s1) { ++ exitCode = 3; ++ goto err2; ++ } ++ if (s1->hasUnicodeMarker()) { + isUnicode = gTrue; + j = 2; + } else { + isUnicode = gFalse; + j = 0; + } +- while (j < fileSpec->getFileName()->getLength()) { ++ while (j < s1->getLength()) { + if (isUnicode) { + u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j+1) & 0xff); + j += 2; +@@ -275,14 +283,18 @@ + } else { + p = path; + s1 = fileSpec->getFileName(); +- if ((s1->getChar(0) & 0xff) == 0xfe && (s1->getChar(1) & 0xff) == 0xff) { ++ if (!s1) { ++ exitCode = 3; ++ goto err2; ++ } ++ if (s1->hasUnicodeMarker()) { + isUnicode = gTrue; + j = 2; + } else { + isUnicode = gFalse; + j = 0; + } +- while (j < fileSpec->getFileName()->getLength()) { ++ while (j < s1->getLength()) { + if (isUnicode) { + u = ((s1->getChar(j) & 0xff) << 8) | (s1->getChar(j+1) & 0xff); + j += 2; diff --git a/backport-CVE-2018-20481.patch b/backport-CVE-2018-20481.patch new file mode 100644 index 0000000..5b5bb15 --- /dev/null +++ b/backport-CVE-2018-20481.patch @@ -0,0 +1,49 @@ +diff -Nuar poppler-0.67.0/poppler/XRef.cc poppler-0.67.0-old/poppler/XRef.cc +--- poppler-0.67.0/poppler/XRef.cc 2018-07-20 05:20:03.000000000 +0800 ++++ poppler-0.67.0-old/poppler/XRef.cc 2021-01-18 15:56:14.964000000 +0800 +@@ -1611,11 +1611,31 @@ + } + } + ++namespace { ++ ++struct DummyXRefEntry : XRefEntry { ++ DummyXRefEntry() { ++ offset = 0; ++ gen = -1; ++ type = xrefEntryNone; ++ flags = 0; ++ } ++}; ++ ++DummyXRefEntry dummyXRefEntry; ++ ++} ++ + XRefEntry *XRef::getEntry(int i, GBool complainIfMissing) + { + if (i >= size || entries[i].type == xrefEntryNone) { + + if ((!xRefStream) && mainXRefEntriesOffset) { ++ if (unlikely(i >= capacity)) { ++ error(errInternal, -1, "Request for out-of-bounds XRef entry [{0:d}]", i); ++ return &dummyXRefEntry; ++ } ++ + if (!parseEntry(mainXRefEntriesOffset + 20*i, &entries[i])) { + error(errSyntaxError, -1, "Failed to parse XRef entry [{0:d}].", i); + } +@@ -1626,12 +1646,7 @@ + // We might have reconstructed the xref + // Check again i is in bounds + if (unlikely(i >= size)) { +- static XRefEntry dummy; +- dummy.offset = 0; +- dummy.gen = -1; +- dummy.type = xrefEntryNone; +- dummy.flags = 0; +- return &dummy; ++ return &dummyXRefEntry; + } + + if (entries[i].type == xrefEntryNone) { diff --git a/backport-CVE-2019-14494.patch b/backport-CVE-2019-14494.patch new file mode 100644 index 0000000..5234508 --- /dev/null +++ b/backport-CVE-2019-14494.patch @@ -0,0 +1,28 @@ +From b224e2f5739fe61de9fa69955d016725b2a4b78d Mon Sep 17 00:00:00 2001 +From: Albert Astals Cid +Date: Mon, 15 Jul 2019 22:11:09 +0200 +Subject: [PATCH] SplashOutputDev::tilingPatternFill: Fix crash on broken file + +Issue #802 +--- + poppler/SplashOutputDev.cc | 4 ++++ + 1 file changed, 4 insertions(+) + +diff --git a/poppler/SplashOutputDev.cc b/poppler/SplashOutputDev.cc +index 544f132da..3d2befc28 100644 +--- a/poppler/SplashOutputDev.cc ++++ b/poppler/SplashOutputDev.cc +@@ -4581,6 +4581,10 @@ bool SplashOutputDev::tilingPatternFill(GfxState *state, Gfx *gfxA, Catalog *cat + surface_width = (int) ceil (fabs(kx)); + surface_height = (int) ceil (fabs(ky)); + // adjust repeat values to completely fill region ++ if (unlikely(surface_width == 0 || surface_height == 0)) { ++ state->setCTM(savedCTM[0], savedCTM[1], savedCTM[2], savedCTM[3], savedCTM[4], savedCTM[5]); ++ return false; ++ } + repeatX = result_width / surface_width; + repeatY = result_height / surface_height; + if (surface_width * repeatX < result_width) +-- +GitLab + diff --git a/backport-CVE-2019-7310.patch b/backport-CVE-2019-7310.patch new file mode 100644 index 0000000..b5631ab --- /dev/null +++ b/backport-CVE-2019-7310.patch @@ -0,0 +1,15 @@ +diff -Nuar poppler-0.67.0/poppler/XRef.cc poppler-0.67.0-old/poppler/XRef.cc +--- poppler-0.67.0/poppler/XRef.cc 2021-01-18 16:24:55.368000000 +0800 ++++ poppler-0.67.0-old/poppler/XRef.cc 2021-01-18 16:29:29.936000000 +0800 +@@ -1628,6 +1628,11 @@ + + XRefEntry *XRef::getEntry(int i, GBool complainIfMissing) + { ++ if (unlikely(i < 0)) { ++ error(errInternal, -1, "Request for invalid XRef entry [{0:d}]", i); ++ return &dummyXRefEntry; ++ } ++ + if (i >= size || entries[i].type == xrefEntryNone) { + + if ((!xRefStream) && mainXRefEntriesOffset) { diff --git a/poppler.spec b/poppler.spec index d5eaf1f..f8ec59d 100644 --- a/poppler.spec +++ b/poppler.spec @@ -3,7 +3,7 @@ Name: poppler Version: 0.67.0 -Release: 5 +Release: 7 Summary: Poppler is a PDF rendering library based on the xpdf-3.0 code base License: (GPLv2 or GPLv3) and GPLv2+ and LGPLv2+ and MIT URL: https://poppler.freedesktop.org/ @@ -29,7 +29,13 @@ Patch6008: CVE-2019-11026.patch Patch6009: CVE-2018-19058.patch Patch6010: CVE-2018-19059.patch Patch6011: CVE-2018-20650.patch - +Patch6012: CVE-2019-10872.patch +Patch6013: backport-CVE-2018-16646.patch +Patch6014: backport-CVE-2018-18897.patch +Patch6015: backport-CVE-2018-19060.patch +Patch6016: backport-CVE-2018-20481.patch +Patch6017: backport-CVE-2019-14494.patch +Patch6018: backport-CVE-2019-7310.patch BuildRequires: cmake gcc-c++ gettext-devel qt5-qtbase-devel qt-devel cairo-devel fontconfig-devel BuildRequires: freetype-devel gdk-pixbuf2-devel glib2-devel gobject-introspection-devel gtk3-devel @@ -238,6 +244,18 @@ test "$(pkg-config --modversion poppler-splash)" = "%{version}" %{_mandir}/man1/* %changelog +* Sat Jan 23 2021 wangye - 0.67.0-7 +- Type:cves +- Id:NA +- SUG:NA +- DESC:fix CVE-2018-16646 CVE-2018-18897 CVE-2018-19060 CVE-2018-20481 CVE-2019-14494 CVE-2019-7310 + +* Thu Oct 29 2020 yanan - 0.67.0-6 +- Type:cves +- Id:NA +- SUG:NA +- DESC:fix CVE-2019-10872 + * Mon Jan 20 2020 openEuler Buildteam - 0.67.0-5 - Type:bugfix - Id:NA -- Gitee