mirror of
				https://github.com/michaelrsweet/pdfio.git
				synced 2025-10-31 02:15:48 +01:00 
			
		
		
		
	Fix denial-of-service attack when reading corrupt PDF files.
This commit is contained in:
		| @@ -2,9 +2,10 @@ Changes in PDFio | |||||||
| ================ | ================ | ||||||
|  |  | ||||||
|  |  | ||||||
| v1.1.0 (Month DD, YYYY) | v1.1.0 (February 3, 2023) | ||||||
| ----------------------- | ------------------------- | ||||||
|  |  | ||||||
|  | - CVE-2023-nnnn: Fixed a potential denial-of-service with corrupt PDF files. | ||||||
| - Added `pdfioFileCreateTemporary` function (Issue #29) | - Added `pdfioFileCreateTemporary` function (Issue #29) | ||||||
| - Added `pdfioDictIterateKeys` function (Issue #31) | - Added `pdfioDictIterateKeys` function (Issue #31) | ||||||
| - Added `pdfioContentPathEnd` function. | - Added `pdfioContentPathEnd` function. | ||||||
|   | |||||||
							
								
								
									
										4
									
								
								Makefile
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								Makefile
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | |||||||
| # | # | ||||||
| # Makefile for PDFio. | # Makefile for PDFio. | ||||||
| # | # | ||||||
| # Copyright © 2021-2022 by Michael R Sweet. | # Copyright © 2021-2023 by Michael R Sweet. | ||||||
| # | # | ||||||
| # Licensed under Apache License v2.0.  See the file "LICENSE" for more | # Licensed under Apache License v2.0.  See the file "LICENSE" for more | ||||||
| # information. | # information. | ||||||
| @@ -29,7 +29,7 @@ DSONAME		= | |||||||
| LDFLAGS		= | LDFLAGS		= | ||||||
| LIBS		=	-lm -lz | LIBS		=	-lm -lz | ||||||
| RANLIB		=	ranlib | RANLIB		=	ranlib | ||||||
| VERSION		=	1.1 | VERSION		=	1.1.0 | ||||||
| prefix		=	/usr/local | prefix		=	/usr/local | ||||||
|  |  | ||||||
|  |  | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								NOTICE
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								NOTICE
									
									
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| PDFio - PDF Read/Write Library | PDFio - PDF Read/Write Library | ||||||
|  |  | ||||||
| Copyright © 2021-2022 by Michael R Sweet. | Copyright © 2021-2023 by Michael R Sweet. | ||||||
|  |  | ||||||
| (Optional) Exceptions to the Apache 2.0 License: | (Optional) Exceptions to the Apache 2.0 License: | ||||||
| ================================================ | ================================================ | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| // | // | ||||||
| // Common support functions for pdfio. | // Common support functions for pdfio. | ||||||
| // | // | ||||||
| // Copyright © 2021 by Michael R Sweet. | // Copyright © 2021-2023 by Michael R Sweet. | ||||||
| // | // | ||||||
| // Licensed under Apache License v2.0.  See the file "LICENSE" for more | // Licensed under Apache License v2.0.  See the file "LICENSE" for more | ||||||
| // information. | // information. | ||||||
| @@ -38,6 +38,8 @@ _pdfioFileConsume(pdfio_file_t *pdf,	// I - PDF file | |||||||
|   else if (_pdfioFileSeek(pdf, (off_t)bytes, SEEK_CUR) < 0) |   else if (_pdfioFileSeek(pdf, (off_t)bytes, SEEK_CUR) < 0) | ||||||
|     return (false); |     return (false); | ||||||
|  |  | ||||||
|  |   PDFIO_DEBUG("_pdfioFileConsume: pos=%ld\n", (long)(pdf->bufpos + pdf->bufptr - pdf->buffer)); | ||||||
|  |  | ||||||
|   return (true); |   return (true); | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -525,7 +527,7 @@ read_buffer(pdfio_file_t *pdf,		// I - PDF file | |||||||
|   return (rbytes); |   return (rbytes); | ||||||
| } | } | ||||||
|  |  | ||||||
|    |  | ||||||
| // | // | ||||||
| // 'write_buffer()' - Write a buffer to a PDF file. | // 'write_buffer()' - Write a buffer to a PDF file. | ||||||
| // | // | ||||||
|   | |||||||
							
								
								
									
										15
									
								
								pdfio-dict.c
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								pdfio-dict.c
									
									
									
									
									
								
							| @@ -1,7 +1,7 @@ | |||||||
| // | // | ||||||
| // PDF dictionary functions for PDFio. | // PDF dictionary functions for PDFio. | ||||||
| // | // | ||||||
| // Copyright © 2021-2022 by Michael R Sweet. | // Copyright © 2021-2023 by Michael R Sweet. | ||||||
| // | // | ||||||
| // Licensed under Apache License v2.0.  See the file "LICENSE" for more | // Licensed under Apache License v2.0.  See the file "LICENSE" for more | ||||||
| // information. | // information. | ||||||
| @@ -541,8 +541,15 @@ _pdfioDictRead(pdfio_file_t   *pdf,	// I - PDF file | |||||||
|       _pdfioFileError(pdf, "Invalid dictionary contents."); |       _pdfioFileError(pdf, "Invalid dictionary contents."); | ||||||
|       break; |       break; | ||||||
|     } |     } | ||||||
|  |     else if (_pdfioDictGetValue(dict, key + 1)) | ||||||
|  |     { | ||||||
|  |       _pdfioFileError(pdf, "Duplicate dictionary key '%s'.", key + 1); | ||||||
|  |       return (NULL); | ||||||
|  |     } | ||||||
|  |  | ||||||
|     // Then get the next value... |     // Then get the next value... | ||||||
|  |     PDFIO_DEBUG("_pdfioDictRead: Reading value for '%s'.\n", key + 1); | ||||||
|  |  | ||||||
|     if (!_pdfioValueRead(pdf, obj, tb, &value, depth)) |     if (!_pdfioValueRead(pdf, obj, tb, &value, depth)) | ||||||
|     { |     { | ||||||
|       _pdfioFileError(pdf, "Missing value for dictionary key."); |       _pdfioFileError(pdf, "Missing value for dictionary key."); | ||||||
| @@ -932,9 +939,9 @@ _pdfioDictSetValue( | |||||||
|  |  | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
|   PDFIO_DEBUG("_pdfioDictSetValue(%p): %lu pairs\n", (void *)dict, (unsigned long)dict->num_pairs); |   PDFIO_DEBUG("_pdfioDictSetValue(%p): %lu pairs\n", (void *)dict, (unsigned long)dict->num_pairs); | ||||||
|   PDFIO_DEBUG("_pdfioDictSetValue(%p): ", (void *)dict); | //  PDFIO_DEBUG("_pdfioDictSetValue(%p): ", (void *)dict); | ||||||
|   PDFIO_DEBUG_DICT(dict); | //  PDFIO_DEBUG_DICT(dict); | ||||||
|   PDFIO_DEBUG("\n"); | //  PDFIO_DEBUG("\n"); | ||||||
| #endif // DEBUG | #endif // DEBUG | ||||||
|  |  | ||||||
|   return (true); |   return (true); | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| // | // | ||||||
| // PDF file functions for PDFio. | // PDF file functions for PDFio. | ||||||
| // | // | ||||||
| // Copyright © 2021-2022 by Michael R Sweet. | // Copyright © 2021-2023 by Michael R Sweet. | ||||||
| // | // | ||||||
| // Licensed under Apache License v2.0.  See the file "LICENSE" for more | // Licensed under Apache License v2.0.  See the file "LICENSE" for more | ||||||
| // information. | // information. | ||||||
| @@ -1984,6 +1984,8 @@ load_xref( | |||||||
| 	return (false); | 	return (false); | ||||||
|       } |       } | ||||||
|  |  | ||||||
|  |       PDFIO_DEBUG("load_xref: Got trailer dict.\n"); | ||||||
|  |  | ||||||
|       _pdfioTokenFlush(&tb); |       _pdfioTokenFlush(&tb); | ||||||
|  |  | ||||||
|       if (!pdf->trailer_dict) |       if (!pdf->trailer_dict) | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| // | // | ||||||
| // PDF object functions for PDFio. | // PDF object functions for PDFio. | ||||||
| // | // | ||||||
| // Copyright © 2021-2022 by Michael R Sweet. | // Copyright © 2021-2023 by Michael R Sweet. | ||||||
| // | // | ||||||
| // Licensed under Apache License v2.0.  See the file "LICENSE" for more | // Licensed under Apache License v2.0.  See the file "LICENSE" for more | ||||||
| // information. | // information. | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| // | // | ||||||
| // PDF token parsing functions for PDFio. | // PDF token parsing functions for PDFio. | ||||||
| // | // | ||||||
| // Copyright © 2021 by Michael R Sweet. | // Copyright © 2021-2023 by Michael R Sweet. | ||||||
| // | // | ||||||
| // Licensed under Apache License v2.0.  See the file "LICENSE" for more | // Licensed under Apache License v2.0.  See the file "LICENSE" for more | ||||||
| // information. | // information. | ||||||
| @@ -129,9 +129,20 @@ _pdfioTokenGet(_pdfio_token_t *tb,	// I - Token buffer/stack | |||||||
|   if (tb->num_tokens > 0) |   if (tb->num_tokens > 0) | ||||||
|   { |   { | ||||||
|     // Yes, return it... |     // Yes, return it... | ||||||
|  |     size_t len;				// Length of token | ||||||
|  |  | ||||||
|     tb->num_tokens --; |     tb->num_tokens --; | ||||||
|     strncpy(buffer, tb->tokens[tb->num_tokens], bufsize - 1); |  | ||||||
|     buffer[bufsize - 1] = '\0'; |     if ((len = strlen(tb->tokens[tb->num_tokens])) > (bufsize - 1)) | ||||||
|  |     { | ||||||
|  |       // Value too large... | ||||||
|  |       PDFIO_DEBUG("_pdfioTokenGet(tb=%p, buffer=%p, bufsize=%u): Token '%s' from stack too large.\n", tb, buffer, (unsigned)bufsize, tb->tokens[tb->num_tokens]); | ||||||
|  |       *buffer = '\0'; | ||||||
|  |       return (false); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     memcpy(buffer, tb->tokens[tb->num_tokens], len); | ||||||
|  |     buffer[len] = '\0'; | ||||||
|  |  | ||||||
|     PDFIO_DEBUG("_pdfioTokenGet(tb=%p, buffer=%p, bufsize=%u): Popping '%s' from stack.\n", tb, buffer, (unsigned)bufsize, buffer); |     PDFIO_DEBUG("_pdfioTokenGet(tb=%p, buffer=%p, bufsize=%u): Popping '%s' from stack.\n", tb, buffer, (unsigned)bufsize, buffer); | ||||||
|  |  | ||||||
| @@ -536,7 +547,7 @@ _pdfioTokenRead(_pdfio_token_t *tb,	// I - Token buffer/stack | |||||||
|  |  | ||||||
|   *bufptr = '\0'; |   *bufptr = '\0'; | ||||||
|  |  | ||||||
|   PDFIO_DEBUG("_pdfioTokenRead: Read '%s'.\n", buffer); | //  PDFIO_DEBUG("_pdfioTokenRead: Read '%s'.\n", buffer); | ||||||
|  |  | ||||||
|   return (bufptr > buffer); |   return (bufptr > buffer); | ||||||
| } | } | ||||||
| @@ -573,6 +584,7 @@ get_char(_pdfio_token_t *tb)		// I - Token buffer | |||||||
|     tb->bufptr = tb->buffer; |     tb->bufptr = tb->buffer; | ||||||
|     tb->bufend = tb->buffer + bytes; |     tb->bufend = tb->buffer + bytes; | ||||||
|  |  | ||||||
|  | #if 0 | ||||||
| #ifdef DEBUG | #ifdef DEBUG | ||||||
|     unsigned char *ptr;			// Pointer into buffer |     unsigned char *ptr;			// Pointer into buffer | ||||||
|  |  | ||||||
| @@ -586,6 +598,7 @@ get_char(_pdfio_token_t *tb)		// I - Token buffer | |||||||
|     } |     } | ||||||
|     PDFIO_DEBUG("'\n"); |     PDFIO_DEBUG("'\n"); | ||||||
| #endif // DEBUG | #endif // DEBUG | ||||||
|  | #endif // 0 | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Return the next character... |   // Return the next character... | ||||||
|   | |||||||
| @@ -1,7 +1,7 @@ | |||||||
| // | // | ||||||
| // PDF value functions for PDFio. | // PDF value functions for PDFio. | ||||||
| // | // | ||||||
| // Copyright © 2021 by Michael R Sweet. | // Copyright © 2021-2023 by Michael R Sweet. | ||||||
| // | // | ||||||
| // Licensed under Apache License v2.0.  See the file "LICENSE" for more | // Licensed under Apache License v2.0.  See the file "LICENSE" for more | ||||||
| // information. | // information. | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user