summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKen Sharp <ken.sharp@artifex.com>2022-09-06 14:00:11 +0100
committerChris Liddell <chris.liddell@artifex.com>2022-09-06 16:58:55 +0100
commit7b4f4e871ad5a0ec98f8e995e058ff87795fe272 (patch)
treee992ad890759faa9895d2c99ed7695dce471463b
parent5f758c8ce6f33889a44445c073c5aaf98dde1f0e (diff)
downloadghostpdl-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.c13
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);