Commit b4d6cf6836ce025ba1811b7bbec52680c7204223
1 parent
f8c8e4dc
Limit depth of nesting in direct objects (fixes #202)
This fixes CVE-2018-9918.
Showing
7 changed files
with
33 additions
and
9 deletions
ChangeLog
libqpdf/QPDFObjectHandle.cc
| @@ -1487,12 +1487,26 @@ QPDFObjectHandle::parseInternal(PointerHolder<InputSource> input, | @@ -1487,12 +1487,26 @@ QPDFObjectHandle::parseInternal(PointerHolder<InputSource> input, | ||
| 1487 | 1487 | ||
| 1488 | case QPDFTokenizer::tt_array_open: | 1488 | case QPDFTokenizer::tt_array_open: |
| 1489 | case QPDFTokenizer::tt_dict_open: | 1489 | case QPDFTokenizer::tt_dict_open: |
| 1490 | - olist_stack.push_back(std::vector<QPDFObjectHandle>()); | ||
| 1491 | - state = st_start; | ||
| 1492 | - offset_stack.push_back(input->tell()); | ||
| 1493 | - state_stack.push_back( | ||
| 1494 | - (token.getType() == QPDFTokenizer::tt_array_open) ? | ||
| 1495 | - st_array : st_dictionary); | 1490 | + if (olist_stack.size() > 500) |
| 1491 | + { | ||
| 1492 | + QTC::TC("qpdf", "QPDFObjectHandle too deep"); | ||
| 1493 | + warn(context, | ||
| 1494 | + QPDFExc(qpdf_e_damaged_pdf, input->getName(), | ||
| 1495 | + object_description, | ||
| 1496 | + input->getLastOffset(), | ||
| 1497 | + "ignoring excessively deeply nested data structure")); | ||
| 1498 | + object = newNull(); | ||
| 1499 | + state = st_top; | ||
| 1500 | + } | ||
| 1501 | + else | ||
| 1502 | + { | ||
| 1503 | + olist_stack.push_back(std::vector<QPDFObjectHandle>()); | ||
| 1504 | + state = st_start; | ||
| 1505 | + offset_stack.push_back(input->tell()); | ||
| 1506 | + state_stack.push_back( | ||
| 1507 | + (token.getType() == QPDFTokenizer::tt_array_open) ? | ||
| 1508 | + st_array : st_dictionary); | ||
| 1509 | + } | ||
| 1496 | break; | 1510 | break; |
| 1497 | 1511 | ||
| 1498 | case QPDFTokenizer::tt_bool: | 1512 | case QPDFTokenizer::tt_bool: |
qpdf/qpdf.testcov
| @@ -335,3 +335,4 @@ QPDFObjectHandle numeric non-numeric 0 | @@ -335,3 +335,4 @@ QPDFObjectHandle numeric non-numeric 0 | ||
| 335 | QPDFObjectHandle erase array bounds 0 | 335 | QPDFObjectHandle erase array bounds 0 |
| 336 | qpdf-c called qpdf_check_pdf 0 | 336 | qpdf-c called qpdf_check_pdf 0 |
| 337 | QPDF xref loop 0 | 337 | QPDF xref loop 0 |
| 338 | +QPDFObjectHandle too deep 0 |
qpdf/qtest/qpdf.test
| @@ -236,6 +236,7 @@ my @bug_tests = ( | @@ -236,6 +236,7 @@ my @bug_tests = ( | ||
| 236 | ["148", "free memory on bad flate", 2], | 236 | ["148", "free memory on bad flate", 2], |
| 237 | ["149", "xref prev pointer loop", 3], | 237 | ["149", "xref prev pointer loop", 3], |
| 238 | ["150", "integer overflow", 2], | 238 | ["150", "integer overflow", 2], |
| 239 | + ["202", "even more deeply nested dictionary", 2], | ||
| 239 | ); | 240 | ); |
| 240 | $n_tests += scalar(@bug_tests); | 241 | $n_tests += scalar(@bug_tests); |
| 241 | foreach my $d (@bug_tests) | 242 | foreach my $d (@bug_tests) |
qpdf/qtest/qpdf/issue-146.out
| 1 | WARNING: issue-146.pdf: file is damaged | 1 | WARNING: issue-146.pdf: file is damaged |
| 2 | WARNING: issue-146.pdf: can't find startxref | 2 | WARNING: issue-146.pdf: can't find startxref |
| 3 | WARNING: issue-146.pdf: Attempting to reconstruct cross-reference table | 3 | WARNING: issue-146.pdf: Attempting to reconstruct cross-reference table |
| 4 | -WARNING: issue-146.pdf (trailer, offset 20728): unknown token while reading object; treating as string | ||
| 5 | -WARNING: issue-146.pdf (trailer, offset 20732): unexpected EOF | ||
| 6 | -WARNING: issue-146.pdf (trailer, offset 20732): parse error while reading object | 4 | +WARNING: issue-146.pdf (trailer, offset 695): ignoring excessively deeply nested data structure |
| 7 | issue-146.pdf: unable to find trailer dictionary while recovering damaged file | 5 | issue-146.pdf: unable to find trailer dictionary while recovering damaged file |
qpdf/qtest/qpdf/issue-202.out
0 → 100644
| 1 | +WARNING: issue-202.pdf (trailer, offset 55770): ignoring excessively deeply nested data structure | ||
| 2 | +WARNING: issue-202.pdf: file is damaged | ||
| 3 | +WARNING: issue-202.pdf (offset 54769): expected trailer dictionary | ||
| 4 | +WARNING: issue-202.pdf: Attempting to reconstruct cross-reference table | ||
| 5 | +issue-202.pdf: unable to find trailer dictionary while recovering damaged file |
qpdf/qtest/qpdf/issue-202.pdf
0 → 100644
No preview for this file type