ALT Linux Bugzilla
– Attachment 9659 Details for
Bug 40899
CVE-2021-3781 (RCE)
New bug
|
Search
|
[?]
|
Help
Register
|
Log In
[x]
|
Forgot Password
Login:
[x]
|
EN
|
RU
[patch]
принятый в апстрим патч
a9bd3dec9fde03327a4a2c69dad1036bf9632e20.patch (text/plain), 8.13 KB, created by
Michael Shigorin
on 2021-09-11 08:50:11 MSK
(
hide
)
Description:
принятый в апстрим патч
Filename:
MIME Type:
Creator:
Michael Shigorin
Created:
2021-09-11 08:50:11 MSK
Size:
8.13 KB
patch
obsolete
>From: Chris Liddell <chris.liddell@artifex.com> >Date: Tue, 7 Sep 2021 19:36:12 +0000 (+0100) >Subject: Bug 704342: Include device specifier strings in access validation >X-Git-Tag: ghostpdl-9.55.0rc1_test_001~1 >X-Git-Url: https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff_plain;h=a9bd3dec9fde03327a4a2c69dad1036bf9632e20 > >Bug 704342: Include device specifier strings in access validation > >for the "%pipe%", %handle%" and %printer% io devices. > >We previously validated only the part after the "%pipe%" Postscript device >specifier, but this proved insufficient. > >This rebuilds the original file name string, and validates it complete. The >slight complication for "%pipe%" is it can be reached implicitly using >"|" so we have to check both prefixes. > >Addresses CVE-2021-3781 >--- > >diff --git a/base/gdevpipe.c b/base/gdevpipe.c >index 96d71f5d8..5bdc485be 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); >+ const size_t preflen = strlen(iodev->dname); >+ const size_t nlen = strlen(fname); >+ int code1; >+ >+ 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 2b964ed74..8d87ceadc 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 ed4827968..746a974f7 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 f852c71fc..ba54cde66 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 6dfed6cd5..318039fad 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
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 40899
: 9659