Skip to content

Commit

Permalink
Fix possible out of bounds read in PDF parser
Browse files Browse the repository at this point in the history
The `find_length()` function in the PDF parser incorrectly assumes that
objects found are located in the main PDF file map, and fails to take
into account whether the objects were in fact found in extracted PDF
object streams. The resulting pointer is then invalid and may be an out
of bounds read.

This issue was found by OSS-Fuzz.

This fix checks if the object is from an object stream, and then
calculates the pointer based on the start of the object stream instead
of based on the start of the PDF.

I've also added extra checks to verify the calculated pointer and object
size are within the stream (or PDF file map). I'm not entirely sure this
is necessary, but better safe than sorry.

Fixes: https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=69617
  • Loading branch information
micahsnyder committed Sep 4, 2024
1 parent 25ca17b commit 8915bd2
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 6 deletions.
45 changes: 39 additions & 6 deletions libclamav/pdf.c
Original file line number Diff line number Diff line change
Expand Up @@ -1003,8 +1003,26 @@ static size_t find_length(struct pdf_struct *pdf, struct pdf_obj *obj, const cha
return 0;
}

indirect_obj_start = pdf->map + obj->start;
bytes_remaining = pdf->size - obj->start;
if (NULL == obj->objstm) {
indirect_obj_start = (const char *)(obj->start + pdf->map);

if (!CLI_ISCONTAINED(pdf->map, pdf->size, indirect_obj_start, obj->size)) {
cli_dbgmsg("find_length: indirect object found, but not contained in PDF\n");
return 0;
}

bytes_remaining = pdf->size - obj->start;

} else {
indirect_obj_start = (const char *)(obj->start + obj->objstm->streambuf);

if (!CLI_ISCONTAINED(obj->objstm->streambuf, obj->objstm->streambuf_len, indirect_obj_start, obj->size)) {
cli_dbgmsg("find_length: indirect object found, but not contained in PDF streambuf\n");
return 0;
}

bytes_remaining = obj->objstm->streambuf_len - obj->start;
}

/* Ok so we found the indirect object, lets read the value. */
index = pdf_nextobject(indirect_obj_start, bytes_remaining);
Expand Down Expand Up @@ -3260,15 +3278,30 @@ void pdf_handle_enc(struct pdf_struct *pdf)

obj = find_obj(pdf, pdf->objs[0], pdf->enc_objid);
if (!obj) {
cli_dbgmsg("pdf_handle_enc: can't find encrypted object %d %d\n", pdf->enc_objid >> 8, pdf->enc_objid & 0xff);
noisy_warnmsg("pdf_handle_enc: can't find encrypted object %d %d\n", pdf->enc_objid >> 8, pdf->enc_objid & 0xff);
cli_dbgmsg("pdf_handle_enc: can't find encryption object %d %d\n", pdf->enc_objid >> 8, pdf->enc_objid & 0xff);
noisy_warnmsg("pdf_handle_enc: can't find encryption object %d %d\n", pdf->enc_objid >> 8, pdf->enc_objid & 0xff);
return;
}

len = obj->size;

q = (obj->objstm) ? (const char *)(obj->start + obj->objstm->streambuf)
: (const char *)(obj->start + pdf->map);
if (NULL == obj->objstm) {
q = (const char *)(obj->start + pdf->map);

if (!CLI_ISCONTAINED(pdf->map, pdf->size, q, len)) {
cli_dbgmsg("pdf_handle_enc: encryption object found, but not contained in PDF\n");
noisy_warnmsg("pdf_handle_enc: encryption object found, but not contained in PDF\n");
return;
}
} else {
q = (const char *)(obj->start + obj->objstm->streambuf);

if (!CLI_ISCONTAINED(obj->objstm->streambuf, obj->objstm->streambuf_len, q, len)) {
cli_dbgmsg("pdf_handle_enc: encryption object found, but not contained in PDF streambuf\n");
noisy_warnmsg("pdf_handle_enc: encryption object found, but not contained in PDF streambuf\n");
return;
}
}

O = U = UE = StmF = StrF = EFF = NULL;

Expand Down
5 changes: 5 additions & 0 deletions libclamav/pdfng.c
Original file line number Diff line number Diff line change
Expand Up @@ -518,6 +518,11 @@ char *pdf_parse_string(struct pdf_struct *pdf, struct pdf_obj *obj, const char *
if (!(newobj))
return NULL;

if (!CLI_ISCONTAINED(pdf->map, pdf->size, newobj->start, newobj->size)) {
cli_dbgmsg("pdf_parse_string: object not contained in PDF\n");
return NULL;
}

if (newobj == obj)
return NULL;

Expand Down

0 comments on commit 8915bd2

Please sign in to comment.