Commit 1db68172d53deef88826e5564f5b1c44f46890dc
1 parent
b0e34486
Add sanity check for flate decode parameters
If a flate memory limit is set, reject decode parameters that would cause the limit to be exceeded and treat stream as unfilterable. Fixes oss-fuzz issue 394463491
Showing
4 changed files
with
9 additions
and
1 deletions
fuzz/CMakeLists.txt
| @@ -154,6 +154,7 @@ set(CORPUS_OTHER | @@ -154,6 +154,7 @@ set(CORPUS_OTHER | ||
| 154 | 389974979.fuzz | 154 | 389974979.fuzz |
| 155 | 391974927.fuzz | 155 | 391974927.fuzz |
| 156 | 394129398.fuzz | 156 | 394129398.fuzz |
| 157 | + 394463491.fuzz | ||
| 157 | ) | 158 | ) |
| 158 | 159 | ||
| 159 | set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus) | 160 | set(CORPUS_DIR ${CMAKE_CURRENT_BINARY_DIR}/qpdf_corpus) |
fuzz/qpdf_extra/394463491.fuzz
0 → 100644
No preview for this file type
fuzz/qtest/fuzz.test
| @@ -11,7 +11,7 @@ my $td = new TestDriver('fuzz'); | @@ -11,7 +11,7 @@ my $td = new TestDriver('fuzz'); | ||
| 11 | 11 | ||
| 12 | my $qpdf_corpus = $ENV{'QPDF_FUZZ_CORPUS'} || die "must set QPDF_FUZZ_CORPUS"; | 12 | my $qpdf_corpus = $ENV{'QPDF_FUZZ_CORPUS'} || die "must set QPDF_FUZZ_CORPUS"; |
| 13 | 13 | ||
| 14 | -my $n_qpdf_files = 91; # increment when adding new files | 14 | +my $n_qpdf_files = 92; # increment when adding new files |
| 15 | 15 | ||
| 16 | my @fuzzers = ( | 16 | my @fuzzers = ( |
| 17 | ['ascii85' => 1], | 17 | ['ascii85' => 1], |
libqpdf/SF_FlateLzwDecode.cc
| @@ -14,6 +14,8 @@ SF_FlateLzwDecode::setDecodeParms(QPDFObjectHandle decode_parms) | @@ -14,6 +14,8 @@ SF_FlateLzwDecode::setDecodeParms(QPDFObjectHandle decode_parms) | ||
| 14 | return true; | 14 | return true; |
| 15 | } | 15 | } |
| 16 | 16 | ||
| 17 | + auto memory_limit = Pl_Flate::memory_limit(); | ||
| 18 | + | ||
| 17 | std::set<std::string> keys = decode_parms.getKeys(); | 19 | std::set<std::string> keys = decode_parms.getKeys(); |
| 18 | for (auto const& key: keys) { | 20 | for (auto const& key: keys) { |
| 19 | QPDFObjectHandle value = decode_parms.getKey(key); | 21 | QPDFObjectHandle value = decode_parms.getKey(key); |
| @@ -29,6 +31,11 @@ SF_FlateLzwDecode::setDecodeParms(QPDFObjectHandle decode_parms) | @@ -29,6 +31,11 @@ SF_FlateLzwDecode::setDecodeParms(QPDFObjectHandle decode_parms) | ||
| 29 | } else if (key == "/Columns" || key == "/Colors" || key == "/BitsPerComponent") { | 31 | } else if (key == "/Columns" || key == "/Colors" || key == "/BitsPerComponent") { |
| 30 | if (value.isInteger()) { | 32 | if (value.isInteger()) { |
| 31 | int val = value.getIntValueAsInt(); | 33 | int val = value.getIntValueAsInt(); |
| 34 | + if (memory_limit && static_cast<unsigned int>(val) > memory_limit) { | ||
| 35 | + QPDFLogger::defaultLogger()->warn( | ||
| 36 | + "SF_FlateLzwDecode parameter exceeds PL_Flate memory limit\n"); | ||
| 37 | + return false; | ||
| 38 | + } | ||
| 32 | if (key == "/Columns") { | 39 | if (key == "/Columns") { |
| 33 | columns = val; | 40 | columns = val; |
| 34 | } else if (key == "/Colors") { | 41 | } else if (key == "/Colors") { |