File podofo-CVE-2018-20797.patch of Package podofo.35911

--- src/base/PdfFiltersPrivate.cpp
+++ src/base/PdfFiltersPrivate.cpp
@@ -93,6 +93,14 @@
         m_nBPC         = static_cast<int>(pDecodeParms->GetKeyAsLong( "BitsPerComponent", 8L ));
         m_nColumns     = static_cast<int>(pDecodeParms->GetKeyAsLong( "Columns", 1L ));
         m_nEarlyChange = static_cast<int>(pDecodeParms->GetKeyAsLong( "EarlyChange", 1L ));
+        
+        // check that input values are in range (CVE-2018-20797)
+        // ISO 32000-2008 specifies these values as all 1 or greater
+        // negative values for m_nColumns / m_nColors / m_nBPC result in huge podofo_calloc
+        if ( m_nColumns < 1 || m_nColors < 1 || m_nBPC < 1 )
+        {
+            PODOFO_RAISE_ERROR( ePdfError_ValueOutOfRange );
+        }
 
         if( m_nPredictor >= 10)
         {
@@ -108,6 +116,18 @@
         m_nCurRowIndex  = 0;
         m_nBpp  = (m_nBPC * m_nColors) >> 3;
         m_nRows = (m_nColumns * m_nColors * m_nBPC) >> 3;
+
+        // check for multiplication overflow on buffer sizes (e.g. if m_nBPC=2 and m_nColors=SIZE_MAX/2+1)
+        if ( podofo_multiplication_overflow( m_nBPC, m_nColors ) || podofo_multiplication_overflow( m_nColumns, m_nBPC * m_nColors ) )
+        {
+            PODOFO_RAISE_ERROR( ePdfError_ValueOutOfRange );
+        }
+
+        // check that computed allocation sizes are > 0 (CVE-2018-20797)
+        if ( m_nRows < 1 || m_nBpp < 1 )
+        {
+            PODOFO_RAISE_ERROR( ePdfError_ValueOutOfRange );
+        }
 
         m_pPrev = static_cast<char*>(podofo_calloc( m_nRows, sizeof(char) ));
         if( !m_pPrev )
--- src/base/PdfMemoryManagement.cpp
+++ src/base/PdfMemoryManagement.cpp
@@ -113,6 +113,48 @@
 	if (nmemb == 0)
 		nmemb = 1;
 
+	if ( podofo_multiplication_overflow( nmemb, size ) )
+	{
+		errno = ENOMEM;
+		return NULL;
+	}
+
+	return calloc(nmemb, size);
+}
+
+void* podofo_realloc( void* buffer, size_t size )
+{
+	/*
+		realloc behaviour with size==0 is platform specific (and dangerous in Visual C++)
+	
+		Windows Visual C++
+		If size is zero, then the block pointed to by memblock is freed; the return value is NULL, and buffer is left pointing at a freed block.
+		NOTE: this is very dangerous, since NULL is also returned when there's not enough memory, but the block ISN'T freed
+
+		OpenBSD
+		If size is equal to 0, a unique pointer to an access protected, zero sized object is returned. 
+        Access via this pointer will generate a SIGSEGV exception.
+
+		Linux
+		If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
+
+		OS X
+		If size is zero and buffer is not NULL, a new, minimum sized object is allocated and the original object is freed.	
+	*/
+
+	if (size == 0)
+		size = 1;
+
+    return realloc( buffer, size );
+}
+
+void podofo_free( void* buffer )
+{
+    free( buffer );
+}
+
+bool podofo_multiplication_overflow(size_t nmemb, size_t size)
+{
 	/*
 		This overflow check is from OpenBSD reallocarray.c, and is also used in GifLib 5.1.2 onwards.
 		
@@ -129,42 +171,10 @@
 	if ((nmemb >= MUL_NO_OVERFLOW || size >= MUL_NO_OVERFLOW) &&
 		nmemb > 0 && SIZE_MAX / nmemb < size) 
 	{
-		errno = ENOMEM;
-		return NULL;
+		return true;
 	}
 
-	return calloc(nmemb, size);
-}
-
-void* podofo_realloc( void* buffer, size_t size )
-{
-	/*
-		realloc behaviour with size==0 is platform specific (and dangerous in Visual C++)
-	
-		Windows Visual C++
-		If size is zero, then the block pointed to by memblock is freed; the return value is NULL, and buffer is left pointing at a freed block.
-		NOTE: this is very dangerous, since NULL is also returned when there's not enough memory, but the block ISN'T freed
-
-		OpenBSD
-		If size is equal to 0, a unique pointer to an access protected, zero sized object is returned. 
-        Access via this pointer will generate a SIGSEGV exception.
-
-		Linux
-		If size was equal to 0, either NULL or a pointer suitable to be passed to free() is returned.
-
-		OS X
-		If size is zero and buffer is not NULL, a new, minimum sized object is allocated and the original object is freed.	
-	*/
-
-	if (size == 0)
-		size = 1;
-
-    return realloc( buffer, size );
-}
-
-void podofo_free( void* buffer )
-{
-    free( buffer );
+	return false;
 }
 
 };
--- src/base/PdfMemoryManagement.h
+++ src/base/PdfMemoryManagement.h
@@ -75,6 +75,11 @@
  */
 PODOFO_API bool podofo_is_little_endian();
 
+/**
+ * Check if multiplying two numbers will overflow. This is crucial when calculating buffer sizes that are the product of two numbers/
+ * \returns true if multiplication will overflow
+ */
+PODOFO_API bool podofo_multiplication_overflow( size_t nmemb, size_t size );
 
 };
 
openSUSE Build Service is sponsored by