Commit 28a9df5119af12d6d97edf4fa97f88ce23865096

Authored by Jay Berkenbilt
1 parent c729e07d

Avoid buffer overrun copying digest

Converting a password to an encryption key is supposed to copy up to a
certain number of bytes from a digest. Make sure never to copy more
than the size of the digest.
ChangeLog
1 2015-02-21 Jay Berkenbilt <ejb@ql.org> 1 2015-02-21 Jay Berkenbilt <ejb@ql.org>
2 2
  3 + * Prevent buffer overrun when converting a password to an
  4 + encryption key. Thanks to Gynvael Coldwind and Mateusz Jurczyk of
  5 + the Google Security Team for providing a sample file with this
  6 + problem.
  7 +
3 * Ensure that arguments to "R" when parsing the file are direct 8 * Ensure that arguments to "R" when parsing the file are direct
4 objects before trying to resolve them. This prevents specially 9 objects before trying to resolve them. This prevents specially
5 crafted files from causing qpdf to crash with a stack overflow. 10 crafted files from causing qpdf to crash with a stack overflow.
libqpdf/QPDF_encryption.cc
@@ -428,7 +428,9 @@ QPDF::compute_encryption_key_from_password( @@ -428,7 +428,9 @@ QPDF::compute_encryption_key_from_password(
428 } 428 }
429 MD5::Digest digest; 429 MD5::Digest digest;
430 iterate_md5_digest(md5, digest, ((data.getR() >= 3) ? 50 : 0)); 430 iterate_md5_digest(md5, digest, ((data.getR() >= 3) ? 50 : 0));
431 - return std::string(reinterpret_cast<char*>(digest), data.getLengthBytes()); 431 + return std::string(reinterpret_cast<char*>(digest),
  432 + std::min(static_cast<int>(sizeof(digest)),
  433 + data.getLengthBytes()));
432 } 434 }
433 435
434 static void 436 static void