CVE-2017-9434 (published 2017-06-05T14:29Z)

Crypto++ (aka cryptopp) through 5.6.5 contains an out-of-bounds read vulnerability in zinflate.cpp in the Inflator filter.

Severity: MEDIUM
CVSS v2 base score: 5.0 (AV:N/AC:L/Au:N/C:P/I:N/A:N)
CVSS v3 base score: 5.3, MEDIUM (CVSS:3.0/AV:N/AC:L/PR:N/UI:N/S:U/C:L/I:N/A:N)

Weakness information:
cwe_id: CWE-125
cwe_name: Out-of-bounds Read
description: The product reads data past the end, or before the beginning, of the intended buffer.
extended_description: 
            
            
             
			 
         
         

Fix information:
repo_url: https://github.com/weidai11/cryptopp
commit_details: repo_url: https://github.com/weidai11/cryptopp
author: Jeffrey Walton
author_date: 2017-05-10 18:17:12-04:00
msg: Add Inflator::BadDistanceErr exception (Issue 414)
The improved validation and excpetion clears the Address Sanitizer and Undefined Behavior Sanitizer findings
repository: repo_url: https://github.com/weidai11/cryptopp
repo_name: weidai11/cryptopp
description: free C++ class library of cryptographic schemes
repo_language: C++
owner: weidai11
file_changes: filename: validat1.cpp
change_type: ModificationType.MODIFY
diff: @@ -623,7 +623,7 @@ bool TestRandomPool()
 			std::cout << "FAILED:";
 		else
 			std::cout << "passed:";
-		std::cout << "  GenerateWord32 and Crop\n";	
+		std::cout << "  GenerateWord32 and Crop\n";
 	}
 
 #if !defined(NO_OS_DEPENDENCE)
@@ -711,7 +711,7 @@ bool TestRandomPool()
 			std::cout << "FAILED:";
 		else
 			std::cout << "passed:";
-		std::cout << "  GenerateWord32 and Crop\n";	
+		std::cout << "  GenerateWord32 and Crop\n";
 	}
 #endif
 
@@ -808,7 +808,7 @@ bool TestAutoSeededX917()
 		std::cout << "FAILED:";
 	else
 		std::cout << "passed:";
-	std::cout << "  GenerateWord32 and Crop\n";	
+	std::cout << "  GenerateWord32 and Crop\n";
 
 	std::cout.flush();
 	return pass;

programming_language: C++
filename: zinflate.cpp
change_type: ModificationType.MODIFY
diff: @@ -552,12 +552,18 @@ bool Inflator::DecodeBody()
 		case DISTANCE_BITS:
 					// TODO: this surfaced during fuzzing. What do we do???
 					CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceExtraBits));
-					bits = (m_distance >= COUNTOF(distanceExtraBits)) ? distanceExtraBits[29] : distanceExtraBits[m_distance];
+					if (m_distance >= COUNTOF(distanceExtraBits))
+						throw BadDistanceErr();
+					bits = distanceExtraBits[m_distance];
 					if (!m_reader.FillBuffer(bits))
 					{
 						m_nextDecode = DISTANCE_BITS;
 						break;
 					}
+					// TODO: this surfaced during fuzzing. What do we do???
+					CRYPTOPP_ASSERT(m_distance < COUNTOF(distanceStarts));
+					if (m_distance >= COUNTOF(distanceStarts))
+						throw BadDistanceErr();
 					m_distance = m_reader.GetBits(bits) + distanceStarts[m_distance];
 					OutputPast(m_literal, m_distance);
 				}

programming_language: C++
filename: zinflate.h
change_type: ModificationType.MODIFY
diff: @@ -98,8 +98,12 @@ public:
 		Err(ErrorType e, const std::string &s)
 			: Exception(e, s) {}
 	};
+	//! \brief Exception thrown when a truncated stream is encountered
 	class UnexpectedEndErr : public Err {public: UnexpectedEndErr() : Err(INVALID_DATA_FORMAT, "Inflator: unexpected end of compressed block") {}};
+	//! \brief Exception thrown when a bad block is encountered
 	class BadBlockErr : public Err {public: BadBlockErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in compressed block") {}};
+	//! \brief Exception thrown when an invalid distance is encountered
+	class BadDistanceErr : public Err {public: BadDistanceErr() : Err(INVALID_DATA_FORMAT, "Inflator: error in bit distance") {}};
 
 	//! \brief RFC 1951 Decompressor
 	//! \param attachment the filter's attached transformation

programming_language: C++