CVE-2023-28428 (published 2023-03-20T15:15Z)

PDFio is a C library for reading and writing PDF files. In versions 1.1.0 and prior, a denial of service vulnerability exists in the pdfio parser. Crafted pdf files can cause the program to run at 100% utilization and never terminate. This is different from CVE-2023-24808. A patch for this issue is available in version 1.1.1.

CVSS v3 base score: 3.3, LOW (CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:L)

Weakness information:
cwe_id: CWE-770
cwe_name: Allocation of Resources Without Limits or Throttling
description: The product allocates a reusable resource or group of resources on behalf of an actor without imposing any restrictions on the size or number of resources that can be allocated, in violation of the intended security policy for that actor.
extended_description: Code frequently has to work with limited resources, so programmers must be careful to ensure that resources are not consumed too quickly, or too easily.  Without use of quotas, resource limits, or other protection mechanisms, it can be easy for an attacker to consume many resources by rapidly making many requests, or causing larger resources to be used than is needed. When too many resources are allocated, or if a single resource is too large, then it can prevent the code from working correctly, possibly leading to a denial of service.
         

Fix information:
repo_url: https://github.com/michaelrsweet/pdfio
commit_details: repo_url: https://github.com/michaelrsweet/pdfio
author: Michael R Sweet
author_date: 2023-03-20 09:27:19-04:00
msg: Fix potential denial-of-service in flate stream code.
repository: repo_url: https://github.com/michaelrsweet/pdfio
repo_name: michaelrsweet/pdfio
description: PDFio is a simple C library for reading and writing PDF files.
repo_language: C
owner: michaelrsweet
file_changes: filename: CHANGES.md
change_type: ModificationType.MODIFY
diff: @@ -2,9 +2,10 @@ Changes in PDFio
 ================
 
 
-v1.1.1 (Month DD, YYYY)
+v1.1.1 (March 20, 2023)
 -----------------------
 
+- CVE-2023-NNNNN: Fixed a potential denial-of-service with corrupt PDF files.
 - Fixed a build issue.
 
 

programming_language: Markdown
filename: pdfio-stream.c
change_type: ModificationType.MODIFY
diff: @@ -1008,6 +1008,7 @@ stream_read(pdfio_stream_t *st,		// I - Stream
             size_t         bytes)	// I - Number of bytes to read
 {
   ssize_t	rbytes;			// Bytes read
+  uInt		avail_in, avail_out;	// Previous flate values
 
 
   if (st->filter == PDFIO_FILTER_NONE)
@@ -1060,11 +1061,19 @@ stream_read(pdfio_stream_t *st,		// I - Stream
       st->flate.next_out  = (Bytef *)buffer;
       st->flate.avail_out = (uInt)bytes;
 
+      avail_in  = st->flate.avail_in;
+      avail_out = st->flate.avail_out;
+
       if ((status = inflate(&(st->flate), Z_NO_FLUSH)) < Z_OK)
       {
 	_pdfioFileError(st->pdf, "Unable to decompress stream data: %s", zstrerror(status));
 	return (-1);
       }
+      else if (avail_in == st->flate.avail_in && avail_out == st->flate.avail_out)
+      {
+	_pdfioFileError(st->pdf, "Corrupt stream data.");
+	return (-1);
+      }
 
       return (st->flate.next_out - (Bytef *)buffer);
     }
@@ -1113,12 +1122,15 @@ stream_read(pdfio_stream_t *st,		// I - Stream
 	  st->flate.avail_in = (uInt)rbytes;
 	}
 
+        avail_in  = st->flate.avail_in;
+        avail_out = st->flate.avail_out;
+
 	if ((status = inflate(&(st->flate), Z_NO_FLUSH)) < Z_OK)
 	{
 	  _pdfioFileError(st->pdf, "Unable to decompress stream data: %s", zstrerror(status));
 	  return (-1);
 	}
-	else if (status == Z_STREAM_END)
+	else if (status == Z_STREAM_END || (avail_in == st->flate.avail_in && avail_out == st->flate.avail_out))
 	  break;
       }
 
@@ -1180,12 +1192,15 @@ stream_read(pdfio_stream_t *st,		// I - Stream
 	  st->flate.avail_in = (uInt)rbytes;
 	}
 
+        avail_in  = st->flate.avail_in;
+        avail_out = st->flate.avail_out;
+
 	if ((status = inflate(&(st->flate), Z_NO_FLUSH)) < Z_OK)
 	{
 	  _pdfioFileError(st->pdf, "Unable to decompress stream data: %s", zstrerror(status));
 	  return (-1);
 	}
-	else if (status == Z_STREAM_END)
+	else if (status == Z_STREAM_END || (avail_in == st->flate.avail_in && avail_out == st->flate.avail_out))
 	  break;
       }
 

programming_language: C