diff options
author | Ken Sharp <ken.sharp@artifex.com> | 2022-09-06 14:00:11 +0100 |
---|---|---|
committer | Chris Liddell <chris.liddell@artifex.com> | 2022-09-06 16:58:55 +0100 |
commit | 7b4f4e871ad5a0ec98f8e995e058ff87795fe272 (patch) | |
tree | e992ad890759faa9895d2c99ed7695dce471463b | |
parent | 5f758c8ce6f33889a44445c073c5aaf98dde1f0e (diff) | |
download | ghostpdl-7b4f4e871ad5a0ec98f8e995e058ff87795fe272.tar.gz |
GhostPDF - check for 0 Size entries in XRefStm /Index array
Bug #705843 " heap-buffer-overflow in pdf/pdf_xref.c:114 read_xref_stream_entries (exploitable)"
The /Index array in the XRefStm holds pairs of values, the first is the
first object number in a subsection, the second is the number of entries
in a subsection.
We were doing loads of checks on the validity of these numbers, but
forgot to check that the size was at least 1. Because we later use
start + size - 1 we could then end up with a ridiculously large index,
because these are unsigned values.
If we get a size of 0, just ignore the subsection.
While making changes, renamed 'end' to 'size' because its a better
descriptive name.
-rw-r--r-- | pdf/pdf_xref.c | 13 |
1 files changed, 8 insertions, 5 deletions
diff --git a/pdf/pdf_xref.c b/pdf/pdf_xref.c index 78c0f1008..3f3d8008f 100644 --- a/pdf/pdf_xref.c +++ b/pdf/pdf_xref.c @@ -308,7 +308,7 @@ static int pdfi_process_xref_stream(pdf_context *ctx, pdf_stream *stream_obj, pd return code; } } else { - int64_t start, end; + int64_t start, size; if (code < 0) { pdfi_close_file(ctx, XRefStrm); @@ -335,7 +335,7 @@ static int pdfi_process_xref_stream(pdf_context *ctx, pdf_stream *stream_obj, pd return code; } - code = pdfi_array_get_int(ctx, a, (uint64_t)i+1, &end); + code = pdfi_array_get_int(ctx, a, (uint64_t)i+1, &size); if (code < 0) { pdfi_countdown(a); pdfi_close_file(ctx, XRefStrm); @@ -344,8 +344,11 @@ static int pdfi_process_xref_stream(pdf_context *ctx, pdf_stream *stream_obj, pd return code; } - if (start + end >= ctx->xref_table->xref_size) { - code = resize_xref(ctx, start + end); + if (size < 1) + continue; + + if (start + size >= ctx->xref_table->xref_size) { + code = resize_xref(ctx, start + size); if (code < 0) { pdfi_countdown(a); pdfi_close_file(ctx, XRefStrm); @@ -355,7 +358,7 @@ static int pdfi_process_xref_stream(pdf_context *ctx, pdf_stream *stream_obj, pd } } - code = read_xref_stream_entries(ctx, XRefStrm, start, start + end - 1, (uint64_t *)W); + code = read_xref_stream_entries(ctx, XRefStrm, start, start + size - 1, (uint64_t *)W); if (code < 0) { pdfi_countdown(a); pdfi_close_file(ctx, XRefStrm); |