Commit 1db68172d53deef88826e5564f5b1c44f46890dc

Authored by m-holger
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
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") {