Commit 603f222365252f1a1e20303b3dbe52466be3053b

Authored by Jay Berkenbilt
1 parent bd6c8456

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.
ChangeLog
  1 +2017-07-26 Jay Berkenbilt <ejb@ql.org>
  2 +
  3 + * CVE-2017-9210: Fix infinite loop caused by attempting to unparse
  4 + an object for inclusion in the text of an exception.
  5 +
1 2015-11-10 Jay Berkenbilt <ejb@ql.org> 6 2015-11-10 Jay Berkenbilt <ejb@ql.org>
2 7
3 * 6.0.0: release 8 * 6.0.0: release
libqpdf/QPDFObjectHandle.cc
@@ -1076,8 +1076,7 @@ QPDFObjectHandle::parseInternal(PointerHolder&lt;InputSource&gt; input, @@ -1076,8 +1076,7 @@ QPDFObjectHandle::parseInternal(PointerHolder&lt;InputSource&gt; input,
1076 throw QPDFExc( 1076 throw QPDFExc(
1077 qpdf_e_damaged_pdf, 1077 qpdf_e_damaged_pdf,
1078 input->getName(), object_description, offset, 1078 input->getName(), object_description, offset,
1079 - std::string("dictionary key not name (") +  
1080 - key_obj.unparse() + ")"); 1079 + std::string("dictionary key is not not a name token"));
1081 } 1080 }
1082 dict[key_obj.getName()] = val; 1081 dict[key_obj.getName()] = val;
1083 } 1082 }
qpdf/qtest/qpdf.test
@@ -206,7 +206,7 @@ $td-&gt;runtest(&quot;remove page we don&#39;t have&quot;, @@ -206,7 +206,7 @@ $td-&gt;runtest(&quot;remove page we don&#39;t have&quot;,
206 show_ntests(); 206 show_ntests();
207 # ---------- 207 # ----------
208 $td->notify("--- Miscellaneous Tests ---"); 208 $td->notify("--- Miscellaneous Tests ---");
209 -$n_tests += 77; 209 +$n_tests += 78;
210 210
211 $td->runtest("qpdf version", 211 $td->runtest("qpdf version",
212 {$td->COMMAND => "qpdf --version"}, 212 {$td->COMMAND => "qpdf --version"},
@@ -218,6 +218,20 @@ $td-&gt;runtest(&quot;C API: qpdf version&quot;, @@ -218,6 +218,20 @@ $td-&gt;runtest(&quot;C API: qpdf version&quot;,
218 $td->EXIT_STATUS => 0}, 218 $td->EXIT_STATUS => 0},
219 $td->NORMALIZE_NEWLINES); 219 $td->NORMALIZE_NEWLINES);
220 220
  221 +# Files to reproduce various bugs
  222 +foreach my $d (
  223 + ["101", "resolve for exception text"],
  224 + )
  225 +{
  226 + my ($n, $description) = @$d;
  227 + $td->runtest($description,
  228 + {$td->COMMAND => "qpdf issue-$n.pdf a.pdf"},
  229 + {$td->FILE => "issue-$n.out",
  230 + $td->EXIT_STATUS => 2},
  231 + $td->NORMALIZE_NEWLINES);
  232 +}
  233 +
  234 +
221 foreach (my $i = 1; $i <= 3; ++$i) 235 foreach (my $i = 1; $i <= 3; ++$i)
222 { 236 {
223 $td->runtest("misc tests", 237 $td->runtest("misc tests",
qpdf/qtest/qpdf/issue-101.out 0 → 100644
  1 +WARNING: issue-101.pdf: file is damaged
  2 +WARNING: issue-101.pdf (file position 3526): xref not found
  3 +WARNING: issue-101.pdf: Attempting to reconstruct cross-reference table
  4 +WARNING: issue-101.pdf (object 5 0, file position 1509): attempting to recover stream length
  5 +WARNING: issue-101.pdf (object 5 0, file position 2097): attempting to recover stream length
  6 +issue-101.pdf (trailer, file position 2928): unknown token while reading object (ÿ)
qpdf/qtest/qpdf/issue-101.pdf 0 → 100644
No preview for this file type