aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJay Berkenbilt <ejb@ql.org>2017-07-25 16:13:30 +0200
committerJay Berkenbilt <ejb@ql.org>2017-07-26 12:24:07 +0200
commit603f222365252f1a1e20303b3dbe52466be3053b (patch)
tree7b3244c9282af1aa37f9c70905ab9b8a70f7ba94
parentbd6c8456190af148c9f40806f3a6f561a3c38a53 (diff)
downloadqpdf-603f222365252f1a1e20303b3dbe52466be3053b.tar.zst
Fix infinite loop while reporting an error (fixes #101)
This is CVE-2017-9210. The description string for an error message included unparsing an object, which is too complex of a thing to try to do while throwing an exception. There was only one example of this in the entire codebase, so it is not a pervasive problem. Fixing this eliminated one class of infinite loop errors.
-rw-r--r--ChangeLog5
-rw-r--r--libqpdf/QPDFObjectHandle.cc3
-rw-r--r--qpdf/qtest/qpdf.test16
-rw-r--r--qpdf/qtest/qpdf/issue-101.out6
-rw-r--r--qpdf/qtest/qpdf/issue-101.pdfbin0 -> 4613 bytes
5 files changed, 27 insertions, 3 deletions
diff --git a/ChangeLog b/ChangeLog
index 548106ee..32bafad6 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,8 @@
+2017-07-26 Jay Berkenbilt <ejb@ql.org>
+
+ * CVE-2017-9210: Fix infinite loop caused by attempting to unparse
+ an object for inclusion in the text of an exception.
+
2015-11-10 Jay Berkenbilt <ejb@ql.org>
* 6.0.0: release
diff --git a/libqpdf/QPDFObjectHandle.cc b/libqpdf/QPDFObjectHandle.cc
index 64a4e3c3..687ba439 100644
--- a/libqpdf/QPDFObjectHandle.cc
+++ b/libqpdf/QPDFObjectHandle.cc
@@ -1076,8 +1076,7 @@ QPDFObjectHandle::parseInternal(PointerHolder<InputSource> input,
throw QPDFExc(
qpdf_e_damaged_pdf,
input->getName(), object_description, offset,
- std::string("dictionary key not name (") +
- key_obj.unparse() + ")");
+ std::string("dictionary key is not not a name token"));
}
dict[key_obj.getName()] = val;
}
diff --git a/qpdf/qtest/qpdf.test b/qpdf/qtest/qpdf.test
index c17271d9..e0b2609a 100644
--- a/qpdf/qtest/qpdf.test
+++ b/qpdf/qtest/qpdf.test
@@ -206,7 +206,7 @@ $td->runtest("remove page we don't have",
show_ntests();
# ----------
$td->notify("--- Miscellaneous Tests ---");
-$n_tests += 77;
+$n_tests += 78;
$td->runtest("qpdf version",
{$td->COMMAND => "qpdf --version"},
@@ -218,6 +218,20 @@ $td->runtest("C API: qpdf version",
$td->EXIT_STATUS => 0},
$td->NORMALIZE_NEWLINES);
+# Files to reproduce various bugs
+foreach my $d (
+ ["101", "resolve for exception text"],
+ )
+{
+ my ($n, $description) = @$d;
+ $td->runtest($description,
+ {$td->COMMAND => "qpdf issue-$n.pdf a.pdf"},
+ {$td->FILE => "issue-$n.out",
+ $td->EXIT_STATUS => 2},
+ $td->NORMALIZE_NEWLINES);
+}
+
+
foreach (my $i = 1; $i <= 3; ++$i)
{
$td->runtest("misc tests",
diff --git a/qpdf/qtest/qpdf/issue-101.out b/qpdf/qtest/qpdf/issue-101.out
new file mode 100644
index 00000000..59bd8103
--- /dev/null
+++ b/qpdf/qtest/qpdf/issue-101.out
@@ -0,0 +1,6 @@
+WARNING: issue-101.pdf: file is damaged
+WARNING: issue-101.pdf (file position 3526): xref not found
+WARNING: issue-101.pdf: Attempting to reconstruct cross-reference table
+WARNING: issue-101.pdf (object 5 0, file position 1509): attempting to recover stream length
+WARNING: issue-101.pdf (object 5 0, file position 2097): attempting to recover stream length
+issue-101.pdf (trailer, file position 2928): unknown token while reading object (ÿ)
diff --git a/qpdf/qtest/qpdf/issue-101.pdf b/qpdf/qtest/qpdf/issue-101.pdf
new file mode 100644
index 00000000..801b7c3a
--- /dev/null
+++ b/qpdf/qtest/qpdf/issue-101.pdf
Binary files differ