summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLei Zhang <thestig@chromium.org>2023-01-12 20:24:54 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2023-02-27 18:32:59 +0000
commite48df7803c7c98b0b2471c94057d32e44a301ad5 (patch)
tree79525a985cfd4648f57249a62b78271ed86e3fe7
parent880556af08f63a1d5c5cbb8289a34be4c729ff28 (diff)
downloadqtwebengine-chromium-e48df7803c7c98b0b2471c94057d32e44a301ad5.tar.gz
[Backport] CVE-2023-0933: Integer overflow in PDF
Manual backport of patch originally reviewed on https://pdfium-review.googlesource.com/c/pdfium/+/103078: Validate the page count. In CountPages(), which recursively calls itself, validate the page count. When any part of the pages tree contains bad data, bail out. Bug: chromium:1404864 Change-Id: Ifdbc14213ec3f963b4b2cb5793b83c15d03336e8 Reviewed-on: https://pdfium-review.googlesource.com/c/pdfium/+/103078 Reviewed-by: Tom Sepez <tsepez@chromium.org> Commit-Queue: Lei Zhang <thestig@chromium.org> Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/462800 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_document.cpp17
1 files changed, 14 insertions, 3 deletions
diff --git a/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_document.cpp b/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_document.cpp
index 62106a7046a..74cf5724574 100644
--- a/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_document.cpp
+++ b/chromium/third_party/pdfium/core/fpdfapi/parser/cpdf_document.cpp
@@ -16,13 +16,16 @@
#include "core/fpdfapi/parser/cpdf_reference.h"
#include "core/fxcodec/jbig2/JBig2_DocumentContext.h"
#include "core/fxcrt/fx_codepage.h"
+#include "third_party/base/optional.h"
#include "third_party/base/stl_util.h"
namespace {
const int kMaxPageLevel = 1024;
-int CountPages(CPDF_Dictionary* pPages,
+// Returns a value in the range [0, `CPDF_Document::kPageMaxNum`), or nullopt on
+// error.
+pdfium::Optional<int> CountPages(CPDF_Dictionary* pPages,
std::set<CPDF_Dictionary*>* visited_pages) {
int count = pPages->GetIntegerFor("Count");
if (count > 0 && count < CPDF_Document::kPageMaxNum)
@@ -39,11 +42,19 @@ int CountPages(CPDF_Dictionary* pPages,
// Use |visited_pages| to help detect circular references of pages.
pdfium::ScopedSetInsertion<CPDF_Dictionary*> local_add(visited_pages,
pKid);
- count += CountPages(pKid, visited_pages);
+ pdfium::Optional<int> local_count =
+ CountPages(pKid, visited_pages);
+ if (!local_count.has_value()) {
+ return pdfium::nullopt; // Propagate error.
+ }
+ count += local_count.value();
} else {
// This page is a leaf node.
count++;
}
+ if (count >= CPDF_Document::kPageMaxNum) {
+ return pdfium::nullopt; // Error: too many pages.
+ }
}
pPages->SetNewFor<CPDF_Number>("Count", count);
return count;
@@ -346,7 +357,7 @@ int CPDF_Document::RetrievePageCount() {
std::set<CPDF_Dictionary*> visited_pages;
visited_pages.insert(pPages);
- return CountPages(pPages, &visited_pages);
+ return CountPages(pPages, &visited_pages).value_or(0);
}
uint32_t CPDF_Document::GetUserPermissions() const {