Skip to content
Permalink
Browse files Browse the repository at this point in the history
Fix denial-of-service attack when reading corrupt PDF files.
  • Loading branch information
michaelrsweet committed Feb 4, 2023
1 parent 57d5894 commit 4f10021
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 18 deletions.
5 changes: 3 additions & 2 deletions CHANGES.md
Expand Up @@ -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 `pdfioDictIterateKeys` function (Issue #31)
- Added `pdfioContentPathEnd` function.
Expand Down
4 changes: 2 additions & 2 deletions Makefile
@@ -1,7 +1,7 @@
#
# 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
# information.
Expand Down Expand Up @@ -29,7 +29,7 @@ DSONAME =
LDFLAGS =
LIBS = -lm -lz
RANLIB = ranlib
VERSION = 1.1
VERSION = 1.1.0
prefix = /usr/local


Expand Down
2 changes: 1 addition & 1 deletion NOTICE
@@ -1,6 +1,6 @@
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:
================================================
Expand Down
6 changes: 4 additions & 2 deletions pdfio-common.c
@@ -1,7 +1,7 @@
//
// 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
// information.
Expand Down Expand Up @@ -38,6 +38,8 @@ _pdfioFileConsume(pdfio_file_t *pdf, // I - PDF file
else if (_pdfioFileSeek(pdf, (off_t)bytes, SEEK_CUR) < 0)
return (false);

PDFIO_DEBUG("_pdfioFileConsume: pos=%ld\n", (long)(pdf->bufpos + pdf->bufptr - pdf->buffer));

return (true);
}

Expand Down Expand Up @@ -525,7 +527,7 @@ read_buffer(pdfio_file_t *pdf, // I - PDF file
return (rbytes);
}


//
// 'write_buffer()' - Write a buffer to a PDF file.
//
Expand Down
15 changes: 11 additions & 4 deletions pdfio-dict.c
@@ -1,7 +1,7 @@
//
// 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
// information.
Expand Down Expand Up @@ -541,8 +541,15 @@ _pdfioDictRead(pdfio_file_t *pdf, // I - PDF file
_pdfioFileError(pdf, "Invalid dictionary contents.");
break;
}
else if (_pdfioDictGetValue(dict, key + 1))
{
_pdfioFileError(pdf, "Duplicate dictionary key '%s'.", key + 1);
return (NULL);
}

// Then get the next value...
PDFIO_DEBUG("_pdfioDictRead: Reading value for '%s'.\n", key + 1);

if (!_pdfioValueRead(pdf, obj, tb, &value, depth))
{
_pdfioFileError(pdf, "Missing value for dictionary key.");
Expand Down Expand Up @@ -932,9 +939,9 @@ _pdfioDictSetValue(

#ifdef DEBUG
PDFIO_DEBUG("_pdfioDictSetValue(%p): %lu pairs\n", (void *)dict, (unsigned long)dict->num_pairs);
PDFIO_DEBUG("_pdfioDictSetValue(%p): ", (void *)dict);
PDFIO_DEBUG_DICT(dict);
PDFIO_DEBUG("\n");
// PDFIO_DEBUG("_pdfioDictSetValue(%p): ", (void *)dict);
// PDFIO_DEBUG_DICT(dict);
// PDFIO_DEBUG("\n");
#endif // DEBUG

return (true);
Expand Down
4 changes: 3 additions & 1 deletion pdfio-file.c
@@ -1,7 +1,7 @@
//
// 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
// information.
Expand Down Expand Up @@ -1984,6 +1984,8 @@ load_xref(
return (false);
}

PDFIO_DEBUG("load_xref: Got trailer dict.\n");

_pdfioTokenFlush(&tb);

if (!pdf->trailer_dict)
Expand Down
2 changes: 1 addition & 1 deletion pdfio-object.c
@@ -1,7 +1,7 @@
//
// 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
// information.
Expand Down
21 changes: 17 additions & 4 deletions pdfio-token.c
@@ -1,7 +1,7 @@
//
// 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
// information.
Expand Down Expand Up @@ -129,9 +129,20 @@ _pdfioTokenGet(_pdfio_token_t *tb, // I - Token buffer/stack
if (tb->num_tokens > 0)
{
// Yes, return it...
size_t len; // Length of token

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);

Expand Down Expand Up @@ -536,7 +547,7 @@ _pdfioTokenRead(_pdfio_token_t *tb, // I - Token buffer/stack

*bufptr = '\0';

PDFIO_DEBUG("_pdfioTokenRead: Read '%s'.\n", buffer);
// PDFIO_DEBUG("_pdfioTokenRead: Read '%s'.\n", buffer);

return (bufptr > buffer);
}
Expand Down Expand Up @@ -573,6 +584,7 @@ get_char(_pdfio_token_t *tb) // I - Token buffer
tb->bufptr = tb->buffer;
tb->bufend = tb->buffer + bytes;

#if 0
#ifdef DEBUG
unsigned char *ptr; // Pointer into buffer

Expand All @@ -586,6 +598,7 @@ get_char(_pdfio_token_t *tb) // I - Token buffer
}
PDFIO_DEBUG("'\n");
#endif // DEBUG
#endif // 0
}

// Return the next character...
Expand Down
2 changes: 1 addition & 1 deletion pdfio-value.c
@@ -1,7 +1,7 @@
//
// 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
// information.
Expand Down

0 comments on commit 4f10021

Please sign in to comment.