Toshaan Bharvani
2 years ago
commit
a260926536
5 changed files with 2338 additions and 0 deletions
@ -0,0 +1,64 @@
@@ -0,0 +1,64 @@
|
||||
From 2a3129365d3bc0d4a41f107ef175920d1505d1f7 Mon Sep 17 00:00:00 2001 |
||||
From: Chris Liddell <chris.liddell@artifex.com> |
||||
Date: Tue, 1 Jun 2021 19:57:16 +0100 |
||||
Subject: [PATCH] Bug 703902: Fix op stack management in |
||||
sampled_data_continue() |
||||
|
||||
Replace pop() (which does no checking, and doesn't handle stack extension |
||||
blocks) with ref_stack_pop() which does do all that. |
||||
|
||||
We still use pop() in one case (it's faster), but we have to later use |
||||
ref_stack_pop() before calling sampled_data_sample() which also accesses the |
||||
op stack. |
||||
|
||||
Fixes: |
||||
https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=34675 |
||||
--- |
||||
psi/zfsample.c | 16 ++++++++++------ |
||||
1 file changed, 10 insertions(+), 6 deletions(-) |
||||
|
||||
diff --git a/psi/zfsample.c b/psi/zfsample.c |
||||
index 0e8e4bc8d..00cd0cfdd 100644 |
||||
--- a/psi/zfsample.c |
||||
+++ b/psi/zfsample.c |
||||
@@ -533,15 +533,19 @@ sampled_data_continue(i_ctx_t *i_ctx_p) |
||||
for (j = 0; j < bps; j++) |
||||
data_ptr[bps * i + j] = (byte)(cv >> ((bps - 1 - j) * 8)); /* MSB first */ |
||||
} |
||||
- pop(num_out); /* Move op to base of result values */ |
||||
|
||||
- /* Check if we are done collecting data. */ |
||||
+ pop(num_out); /* Move op to base of result values */ |
||||
|
||||
+ /* From here on, we have to use ref_stack_pop() rather than pop() |
||||
+ so that it handles stack extension blocks properly, before calling |
||||
+ sampled_data_sample() which also uses the op stack. |
||||
+ */ |
||||
+ /* Check if we are done collecting data. */ |
||||
if (increment_cube_indexes(params, penum->indexes)) { |
||||
if (stack_depth_adjust == 0) |
||||
- pop(O_STACK_PAD); /* Remove spare stack space */ |
||||
+ ref_stack_pop(&o_stack, O_STACK_PAD); /* Remove spare stack space */ |
||||
else |
||||
- pop(stack_depth_adjust - num_out); |
||||
+ ref_stack_pop(&o_stack, stack_depth_adjust - num_out); |
||||
/* Execute the closing procedure, if given */ |
||||
code = 0; |
||||
if (esp_finish_proc != 0) |
||||
@@ -554,11 +558,11 @@ sampled_data_continue(i_ctx_t *i_ctx_p) |
||||
if ((O_STACK_PAD - stack_depth_adjust) < 0) { |
||||
stack_depth_adjust = -(O_STACK_PAD - stack_depth_adjust); |
||||
check_op(stack_depth_adjust); |
||||
- pop(stack_depth_adjust); |
||||
+ ref_stack_pop(&o_stack, stack_depth_adjust); |
||||
} |
||||
else { |
||||
check_ostack(O_STACK_PAD - stack_depth_adjust); |
||||
- push(O_STACK_PAD - stack_depth_adjust); |
||||
+ ref_stack_push(&o_stack, O_STACK_PAD - stack_depth_adjust); |
||||
for (i=0;i<O_STACK_PAD - stack_depth_adjust;i++) |
||||
make_null(op - i); |
||||
} |
||||
-- |
||||
2.35.1 |
||||
|
@ -0,0 +1,98 @@
@@ -0,0 +1,98 @@
|
||||
diff -ur ghostscript-9.54.0/base/gdevvec.c ghostscript-9.54.0-patched/base/gdevvec.c |
||||
--- ghostscript-9.54.0/base/gdevvec.c |
||||
+++ ghostscript-9.54.0-patched/base/gdevvec.c |
||||
@@ -643,7 +643,7 @@ |
||||
*/ |
||||
int |
||||
gdev_vector_dopath_segment(gdev_vector_dopath_state_t *state, int pe_op, |
||||
- gs_fixed_point vs[3]) |
||||
+ gs_fixed_point *vs) |
||||
{ |
||||
gx_device_vector *vdev = state->vdev; |
||||
const gs_matrix *const pmat = &state->scale_mat; |
||||
diff -ur ghostscript-9.54.0/base/gdevvec.h ghostscript-9.54.0-patched/base/gdevvec.h |
||||
--- ghostscript-9.54.0/base/gdevvec.h |
||||
+++ ghostscript-9.54.0-patched/base/gdevvec.h |
||||
@@ -306,7 +306,7 @@ |
||||
|
||||
/* Write a segment of a path using the default implementation. */ |
||||
int gdev_vector_dopath_segment(gdev_vector_dopath_state_t *state, int pe_op, |
||||
- gs_fixed_point vs[3]); |
||||
+ gs_fixed_point *vs); |
||||
|
||||
typedef struct gdev_vector_path_seg_record_s { |
||||
int op; |
||||
diff -ur ghostscript-9.54.0/base/gxclpath.c ghostscript-9.54.0-patched/base/gxclpath.c |
||||
--- ghostscript-9.54.0/base/gxclpath.c 2021-03-30 09:40:28.000000000 +0200 |
||||
+++ ghostscript-9.54.0-patched/base/gxclpath.c 2021-11-23 11:06:14.670137576 +0100 |
||||
@@ -715,10 +715,10 @@ |
||||
} else { |
||||
code = set_cmd_put_op(&dp, cldev, pcls, cmd_opv_set_color_space, |
||||
2 + sizeof(clist_icc_color_t)); |
||||
- memcpy(dp + 2, &(cldev->color_space.icc_info), |
||||
- sizeof(clist_icc_color_t)); |
||||
if (code < 0) |
||||
return code; |
||||
+ memcpy(dp + 2, &(cldev->color_space.icc_info), |
||||
+ sizeof(clist_icc_color_t)); |
||||
} |
||||
dp[1] = cldev->color_space.byte1; |
||||
pcls->known |= color_space_known; |
||||
diff -ur ghostscript-9.54.0/extract/src/mem.c ghostscript-9.54.0-patched/extract/src/mem.c |
||||
--- ghostscript-9.54.0/extract/src/mem.c 2021-03-30 09:40:28.000000000 +0200 |
||||
+++ ghostscript-9.54.0-patched/extract/src/mem.c 2021-11-23 11:11:37.293082828 +0100 |
||||
@@ -19,14 +19,24 @@ |
||||
int extract_vasprintf(extract_alloc_t* alloc, char** out, const char* format, va_list va) |
||||
{ |
||||
int n; |
||||
- int n2; |
||||
+ int ret; |
||||
va_list va2; |
||||
va_copy(va2, va); |
||||
n = vsnprintf(NULL, 0, format, va); |
||||
- if (n < 0) return n; |
||||
- if (extract_malloc(alloc, out, n + 1)) return -1; |
||||
- n2 = vsnprintf(*out, n + 1, format, va2); |
||||
+ if (n < 0) |
||||
+ { |
||||
+ ret = n; |
||||
+ goto end; |
||||
+ } |
||||
+ if (extract_malloc(alloc, out, n + 1)) |
||||
+ { |
||||
+ ret = -1; |
||||
+ goto end; |
||||
+ } |
||||
+ vsnprintf(*out, n + 1, format, va2); |
||||
+ ret = 0; |
||||
+ |
||||
+ end: |
||||
va_end(va2); |
||||
- assert(n2 == n); |
||||
- return n2; |
||||
+ return ret; |
||||
} |
||||
diff -ur ghostscript-9.54.0/psi/icie.h ghostscript-9.54.0-patched/psi/icie.h |
||||
--- ghostscript-9.54.0/psi/icie.h 2021-03-30 09:40:28.000000000 +0200 |
||||
+++ ghostscript-9.54.0-patched/psi/icie.h 2021-10-29 12:48:43.405814563 +0200 |
||||
@@ -53,7 +53,7 @@ |
||||
|
||||
/* Get 3 procedures from a dictionary. */ |
||||
int dict_proc3_param(const gs_memory_t *mem, const ref *pdref, |
||||
- const char *kstr, ref proc3[3]); |
||||
+ const char *kstr, ref *proc3); |
||||
|
||||
/* Get WhitePoint and BlackPoint values. */ |
||||
int cie_points_param(const gs_memory_t *mem, |
||||
diff -ur ghostscript-9.54.0/psi/zcie.c ghostscript-9.54.0-patched/psi/zcie.c |
||||
--- ghostscript-9.54.0/psi/zcie.c 2021-03-30 09:40:28.000000000 +0200 |
||||
+++ ghostscript-9.54.0-patched/psi/zcie.c 2021-11-02 14:36:28.463448728 +0100 |
||||
@@ -144,7 +144,7 @@ |
||||
|
||||
/* Get 3 procedures from a dictionary. */ |
||||
int |
||||
-dict_proc3_param(const gs_memory_t *mem, const ref *pdref, const char *kstr, ref proc3[3]) |
||||
+dict_proc3_param(const gs_memory_t *mem, const ref *pdref, const char *kstr, ref *proc3) |
||||
{ |
||||
return dict_proc_array_param(mem, pdref, kstr, 3, proc3); |
||||
} |
@ -0,0 +1,46 @@
@@ -0,0 +1,46 @@
|
||||
diff --git a/devices/vector/gdevtxtw.c b/devices/vector/gdevtxtw.c |
||||
index c6b95ed5b..f103d598b 100644 |
||||
--- a/devices/vector/gdevtxtw.c |
||||
+++ b/devices/vector/gdevtxtw.c |
||||
@@ -1982,16 +1982,26 @@ textw_text_release(gs_text_enum_t *pte, client_name_t cname) |
||||
gx_device_txtwrite_t *const tdev = (gx_device_txtwrite_t *) pte->dev; |
||||
|
||||
/* Free the working buffer where the Unicode was assembled from the enumerated text */ |
||||
- if (penum->TextBuffer) |
||||
+ if (penum->TextBuffer) { |
||||
gs_free(tdev->memory, penum->TextBuffer, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer"); |
||||
- if (penum->Widths) |
||||
+ penum->TextBuffer = NULL; |
||||
+ } |
||||
+ if (penum->Widths) { |
||||
gs_free(tdev->memory, penum->Widths, sizeof(float), pte->text.size, "txtwrite free temporary widths array"); |
||||
- if (penum->Advs) |
||||
+ penum->Widths = NULL; |
||||
+ } |
||||
+ if (penum->Advs) { |
||||
gs_free(tdev->memory, penum->Advs, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer"); |
||||
- if (penum->GlyphWidths) |
||||
+ penum->Advs = NULL; |
||||
+ } |
||||
+ if (penum->GlyphWidths) { |
||||
gs_free(tdev->memory, penum->GlyphWidths, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer"); |
||||
- if (penum->SpanDeltaX) |
||||
+ penum->GlyphWidths = NULL; |
||||
+ } |
||||
+ if (penum->SpanDeltaX) { |
||||
gs_free(tdev->memory, penum->SpanDeltaX, 1, penum->TextBufferIndex, "txtwrite free temporary text buffer"); |
||||
+ penum->SpanDeltaX = NULL; |
||||
+ } |
||||
/* If this is copied away when we complete the text enumeration succesfully, then |
||||
* we set the pointer to NULL, if we get here with it non-NULL , then there was |
||||
* an error. |
||||
@@ -2008,6 +2018,7 @@ textw_text_release(gs_text_enum_t *pte, client_name_t cname) |
||||
if (penum->text_state->FontName) |
||||
gs_free(tdev->memory, penum->text_state->FontName, 1, penum->TextBufferIndex, "txtwrite free temporary font name copy"); |
||||
gs_free(tdev->memory, penum->text_state, 1, sizeof(penum->text_state), "txtwrite free text state"); |
||||
+ penum->text_state = NULL; |
||||
} |
||||
} |
||||
|
||||
-- |
||||
2.17.1 |
@ -0,0 +1,208 @@
@@ -0,0 +1,208 @@
|
||||
diff --git a/base/gdevpipe.c b/base/gdevpipe.c |
||||
index 96d71f5d81..752a2f1d94 100644 |
||||
--- a/base/gdevpipe.c |
||||
+++ b/base/gdevpipe.c |
||||
@@ -72,8 +72,28 @@ pipe_fopen(gx_io_device * iodev, const char *fname, const char *access, |
||||
#else |
||||
gs_lib_ctx_t *ctx = mem->gs_lib_ctx; |
||||
gs_fs_list_t *fs = ctx->core->fs; |
||||
+ /* The pipe device can be reached in two ways, explicltly with %pipe% |
||||
+ or implicitly with "|", so we have to check for both |
||||
+ */ |
||||
+ char f[gp_file_name_sizeof]; |
||||
+ const char *pipestr = "|"; |
||||
+ const size_t pipestrlen = strlen(pipestr); |
||||
+ int code1; |
||||
+ const size_t preflen = strlen(iodev->dname); |
||||
+ const size_t nlen = strlen(fname); |
||||
+ |
||||
+ if (preflen + nlen >= gp_file_name_sizeof) |
||||
+ return_error(gs_error_invalidaccess); |
||||
+ |
||||
+ memcpy(f, iodev->dname, preflen); |
||||
+ memcpy(f + preflen, fname, nlen + 1); |
||||
+ |
||||
+ code1 = gp_validate_path(mem, f, access); |
||||
+ |
||||
+ memcpy(f, pipestr, pipestrlen); |
||||
+ memcpy(f + pipestrlen, fname, nlen + 1); |
||||
|
||||
- if (gp_validate_path(mem, fname, access) != 0) |
||||
+ if (code1 != 0 && gp_validate_path(mem, f, access) != 0 ) |
||||
return gs_error_invalidfileaccess; |
||||
|
||||
/* |
||||
diff --git a/base/gp_mshdl.c b/base/gp_mshdl.c |
||||
index 2b964ed749..8d87ceadc0 100644 |
||||
--- a/base/gp_mshdl.c |
||||
+++ b/base/gp_mshdl.c |
||||
@@ -95,8 +95,17 @@ mswin_handle_fopen(gx_io_device * iodev, const char *fname, const char *access, |
||||
long hfile; /* Correct for Win32, may be wrong for Win64 */ |
||||
gs_lib_ctx_t *ctx = mem->gs_lib_ctx; |
||||
gs_fs_list_t *fs = ctx->core->fs; |
||||
+ char f[gp_file_name_sizeof]; |
||||
+ const size_t preflen = strlen(iodev->dname); |
||||
+ const size_t nlen = strlen(fname); |
||||
|
||||
- if (gp_validate_path(mem, fname, access) != 0) |
||||
+ if (preflen + nlen >= gp_file_name_sizeof) |
||||
+ return_error(gs_error_invalidaccess); |
||||
+ |
||||
+ memcpy(f, iodev->dname, preflen); |
||||
+ memcpy(f + preflen, fname, nlen + 1); |
||||
+ |
||||
+ if (gp_validate_path(mem, f, access) != 0) |
||||
return gs_error_invalidfileaccess; |
||||
|
||||
/* First we try the open_handle method. */ |
||||
diff --git a/base/gp_msprn.c b/base/gp_msprn.c |
||||
index ed48279685..746a974f78 100644 |
||||
--- a/base/gp_msprn.c |
||||
+++ b/base/gp_msprn.c |
||||
@@ -168,8 +168,16 @@ mswin_printer_fopen(gx_io_device * iodev, const char *fname, const char *access, |
||||
uintptr_t *ptid = &((tid_t *)(iodev->state))->tid; |
||||
gs_lib_ctx_t *ctx = mem->gs_lib_ctx; |
||||
gs_fs_list_t *fs = ctx->core->fs; |
||||
+ const size_t preflen = strlen(iodev->dname); |
||||
+ const size_t nlen = strlen(fname); |
||||
|
||||
- if (gp_validate_path(mem, fname, access) != 0) |
||||
+ if (preflen + nlen >= gp_file_name_sizeof) |
||||
+ return_error(gs_error_invalidaccess); |
||||
+ |
||||
+ memcpy(pname, iodev->dname, preflen); |
||||
+ memcpy(pname + preflen, fname, nlen + 1); |
||||
+ |
||||
+ if (gp_validate_path(mem, pname, access) != 0) |
||||
return gs_error_invalidfileaccess; |
||||
|
||||
/* First we try the open_printer method. */ |
||||
diff --git a/base/gp_os2pr.c b/base/gp_os2pr.c |
||||
index f852c71fc8..ba54cde66f 100644 |
||||
--- a/base/gp_os2pr.c |
||||
+++ b/base/gp_os2pr.c |
||||
@@ -107,9 +107,20 @@ os2_printer_fopen(gx_io_device * iodev, const char *fname, const char *access, |
||||
FILE ** pfile, char *rfname, uint rnamelen) |
||||
{ |
||||
os2_printer_t *pr = (os2_printer_t *)iodev->state; |
||||
- char driver_name[256]; |
||||
+ char driver_name[gp_file_name_sizeof]; |
||||
gs_lib_ctx_t *ctx = mem->gs_lib_ctx; |
||||
gs_fs_list_t *fs = ctx->core->fs; |
||||
+ const size_t preflen = strlen(iodev->dname); |
||||
+ const int size_t = strlen(fname); |
||||
+ |
||||
+ if (preflen + nlen >= gp_file_name_sizeof) |
||||
+ return_error(gs_error_invalidaccess); |
||||
+ |
||||
+ memcpy(driver_name, iodev->dname, preflen); |
||||
+ memcpy(driver_name + preflen, fname, nlen + 1); |
||||
+ |
||||
+ if (gp_validate_path(mem, driver_name, access) != 0) |
||||
+ return gs_error_invalidfileaccess; |
||||
|
||||
/* First we try the open_printer method. */ |
||||
/* Note that the loop condition here ensures we don't |
||||
diff --git a/base/gslibctx.c b/base/gslibctx.c |
||||
index 6dfed6cd5a..318039fad0 100644 |
||||
--- a/base/gslibctx.c |
||||
+++ b/base/gslibctx.c |
||||
@@ -655,82 +655,39 @@ rewrite_percent_specifiers(char *s) |
||||
int |
||||
gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname) |
||||
{ |
||||
- char *fp, f[gp_file_name_sizeof]; |
||||
- const int pipe = 124; /* ASCII code for '|' */ |
||||
- const int len = strlen(fname); |
||||
- int i, code; |
||||
+ char f[gp_file_name_sizeof]; |
||||
+ int code; |
||||
|
||||
/* Be sure the string copy will fit */ |
||||
- if (len >= gp_file_name_sizeof) |
||||
+ if (strlen(fname) >= gp_file_name_sizeof) |
||||
return gs_error_rangecheck; |
||||
strcpy(f, fname); |
||||
- fp = f; |
||||
/* Try to rewrite any %d (or similar) in the string */ |
||||
rewrite_percent_specifiers(f); |
||||
- for (i = 0; i < len; i++) { |
||||
- if (f[i] == pipe) { |
||||
- fp = &f[i + 1]; |
||||
- /* Because we potentially have to check file permissions at two levels |
||||
- for the output file (gx_device_open_output_file and the low level |
||||
- fopen API, if we're using a pipe, we have to add both the full string, |
||||
- (including the '|', and just the command to which we pipe - since at |
||||
- the pipe_fopen(), the leading '|' has been stripped. |
||||
- */ |
||||
- code = gs_add_control_path(mem, gs_permit_file_writing, f); |
||||
- if (code < 0) |
||||
- return code; |
||||
- code = gs_add_control_path(mem, gs_permit_file_control, f); |
||||
- if (code < 0) |
||||
- return code; |
||||
- break; |
||||
- } |
||||
- if (!IS_WHITESPACE(f[i])) |
||||
- break; |
||||
- } |
||||
- code = gs_add_control_path(mem, gs_permit_file_control, fp); |
||||
+ |
||||
+ code = gs_add_control_path(mem, gs_permit_file_control, f); |
||||
if (code < 0) |
||||
return code; |
||||
- return gs_add_control_path(mem, gs_permit_file_writing, fp); |
||||
+ return gs_add_control_path(mem, gs_permit_file_writing, f); |
||||
} |
||||
|
||||
int |
||||
gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname) |
||||
{ |
||||
- char *fp, f[gp_file_name_sizeof]; |
||||
- const int pipe = 124; /* ASCII code for '|' */ |
||||
- const int len = strlen(fname); |
||||
- int i, code; |
||||
+ char f[gp_file_name_sizeof]; |
||||
+ int code; |
||||
|
||||
/* Be sure the string copy will fit */ |
||||
- if (len >= gp_file_name_sizeof) |
||||
+ if (strlen(fname) >= gp_file_name_sizeof) |
||||
return gs_error_rangecheck; |
||||
strcpy(f, fname); |
||||
- fp = f; |
||||
/* Try to rewrite any %d (or similar) in the string */ |
||||
- for (i = 0; i < len; i++) { |
||||
- if (f[i] == pipe) { |
||||
- fp = &f[i + 1]; |
||||
- /* Because we potentially have to check file permissions at two levels |
||||
- for the output file (gx_device_open_output_file and the low level |
||||
- fopen API, if we're using a pipe, we have to add both the full string, |
||||
- (including the '|', and just the command to which we pipe - since at |
||||
- the pipe_fopen(), the leading '|' has been stripped. |
||||
- */ |
||||
- code = gs_remove_control_path(mem, gs_permit_file_writing, f); |
||||
- if (code < 0) |
||||
- return code; |
||||
- code = gs_remove_control_path(mem, gs_permit_file_control, f); |
||||
- if (code < 0) |
||||
- return code; |
||||
- break; |
||||
- } |
||||
- if (!IS_WHITESPACE(f[i])) |
||||
- break; |
||||
- } |
||||
- code = gs_remove_control_path(mem, gs_permit_file_control, fp); |
||||
+ rewrite_percent_specifiers(f); |
||||
+ |
||||
+ code = gs_remove_control_path(mem, gs_permit_file_control, f); |
||||
if (code < 0) |
||||
return code; |
||||
- return gs_remove_control_path(mem, gs_permit_file_writing, fp); |
||||
+ return gs_remove_control_path(mem, gs_permit_file_writing, f); |
||||
} |
||||
|
||||
int |
||||
-- |
||||
2.17.1 |
||||
|
Loading…
Reference in new issue