From c78042065812cb58ca51f331159d46415e66db8d Mon Sep 17 00:00:00 2001 From: mayp Date: Thu, 18 Aug 2022 16:49:57 +0800 Subject: [PATCH] Fix CVE-2021-20304 --- IlmImf/ImfHuf.cpp | 9 +++ IlmImfTest/testHuf.cpp | 141 +++++++++++++++++++++++------------------ 2 files changed, 89 insertions(+), 61 deletions(-) diff --git a/IlmImf/ImfHuf.cpp b/IlmImf/ImfHuf.cpp index aa708a8..82af799 100644 --- a/IlmImf/ImfHuf.cpp +++ b/IlmImf/ImfHuf.cpp @@ -897,6 +897,11 @@ hufDecode // lc -= pl.len; + + if ( lc < 0 ) + { + invalidCode(); // code length too long + } getCode (pl.lit, rlc, c, lc, in, out, outb, oe); } else @@ -954,6 +959,10 @@ hufDecode if (pl.len) { lc -= pl.len; + if ( lc < 0 ) + { + invalidCode(); // code length too long + } getCode (pl.lit, rlc, c, lc, in, out, outb, oe); } else diff --git a/IlmImfTest/testHuf.cpp b/IlmImfTest/testHuf.cpp index d2728fb..10d3906 100644 --- a/IlmImfTest/testHuf.cpp +++ b/IlmImfTest/testHuf.cpp @@ -180,67 +180,86 @@ testHuf (const std::string&) IMATH_NAMESPACE::Rand48 rand48 (0); - const int N = 1000000; - Array raw (N); - - fill1 (raw, N, 1, rand48); // test various symbol distributions - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - fill1 (raw, N, 10, rand48); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - fill1 (raw, N, 100, rand48); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - fill1 (raw, N, 1000, rand48); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - - fill2 (raw, N, 1, rand48); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - fill2 (raw, N, 10, rand48); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - fill2 (raw, N, 100, rand48); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - fill2 (raw, N, 1000, rand48); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - - fill3 (raw, N, 0); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - fill3 (raw, N, 1); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - fill3 (raw, N, USHRT_MAX - 1); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - fill3 (raw, N, USHRT_MAX); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - - fill4 (raw, USHRT_MAX + 1); - compressUncompress (raw, USHRT_MAX + 1); - compressUncompressSubset (raw, USHRT_MAX + 1); - fill4 (raw, N); - compressUncompress (raw, N); - compressUncompressSubset (raw, N); - - fill4 (raw, 0); - compressUncompress (raw, 0); // test small input data sets - fill4 (raw, 1); - compressUncompress (raw, 1); - fill4 (raw, 2); - compressUncompress (raw, 2); - fill4 (raw, 3); - compressUncompress (raw, 3); - - fill5 (raw, N); // test run-length coding of code table - compressUncompress (raw, N); - compressUncompressSubset (raw, N); + // + // FastHufDecoder is used for more than 128 bits, so first test with fewer than 128 bits, + // then test FastHufDecoder + // + for (int pass = 0 ; pass < 2 ; ++pass) + { + + int N = pass==0 ? 12 : 1000000; + Array raw (N); + + fill1 (raw, N, 1, rand48); // test various symbol distributions + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + fill1 (raw, N, 10, rand48); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + fill1 (raw, N, 100, rand48); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + fill1 (raw, N, 1000, rand48); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + + fill2 (raw, N, 1, rand48); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + fill2 (raw, N, 10, rand48); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + fill2 (raw, N, 100, rand48); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + fill2 (raw, N, 1000, rand48); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + + fill3 (raw, N, 0); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + fill3 (raw, N, 1); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + fill3 (raw, N, USHRT_MAX - 1); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + fill3 (raw, N, USHRT_MAX); + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + + if (pass==1) + { + fill4 (raw, USHRT_MAX + 1); + compressVerify(raw, USHRT_MAX + 1, HUF_COMPRESS_DEK_HASH_FOR_FILL4_USHRT_MAX_PLUS_ONE); + + compressUncompress (raw, USHRT_MAX + 1); + compressUncompressSubset (raw, USHRT_MAX + 1); + fill4 (raw, N); + compressVerify(raw, N, HUF_COMPRESS_DEK_HASH_FOR_FILL4_N); + } + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + + fill4 (raw, 0); + compressUncompress (raw, 0); // test small input data sets + fill4 (raw, 1); + compressUncompress (raw, 1); + fill4 (raw, 2); + compressUncompress (raw, 2); + fill4 (raw, 3); + compressUncompress (raw, 3); + + fill5 (raw, N); // test run-length coding of code table + if (pass==1) + { + compressVerify(raw, N, HUF_COMPRESS_DEK_HASH_FOR_FILL5_N); + } + compressUncompress (raw, N); + compressUncompressSubset (raw, N); + + } cout << "ok\n" << endl; } -- 2.33.0