summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--base/gdevpipe.c22
-rw-r--r--base/gp_mshdl.c11
-rw-r--r--base/gp_msprn.c10
-rw-r--r--base/gp_os2pr.c13
-rw-r--r--base/gslibctx.c69
5 files changed, 65 insertions, 60 deletions
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,
72#else 72#else
73 gs_lib_ctx_t *ctx = mem->gs_lib_ctx; 73 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
74 gs_fs_list_t *fs = ctx->core->fs; 74 gs_fs_list_t *fs = ctx->core->fs;
75 /* The pipe device can be reached in two ways, explicltly with %pipe%
76 or implicitly with "|", so we have to check for both
77 */
78 char f[gp_file_name_sizeof];
79 const char *pipestr = "|";
80 const size_t pipestrlen = strlen(pipestr);
81 const size_t preflen = strlen(iodev->dname);
82 const size_t nlen = strlen(fname);
83 int code1;
84
85 if (preflen + nlen >= gp_file_name_sizeof)
86 return_error(gs_error_invalidaccess);
87
88 memcpy(f, iodev->dname, preflen);
89 memcpy(f + preflen, fname, nlen + 1);
90
91 code1 = gp_validate_path(mem, f, access);
92
93 memcpy(f, pipestr, pipestrlen);
94 memcpy(f + pipestrlen, fname, nlen + 1);
75 95
76 if (gp_validate_path(mem, fname, access) != 0) 96 if (code1 != 0 && gp_validate_path(mem, f, access) != 0 )
77 return gs_error_invalidfileaccess; 97 return gs_error_invalidfileaccess;
78 98
79 /* 99 /*
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,
95 long hfile; /* Correct for Win32, may be wrong for Win64 */ 95 long hfile; /* Correct for Win32, may be wrong for Win64 */
96 gs_lib_ctx_t *ctx = mem->gs_lib_ctx; 96 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
97 gs_fs_list_t *fs = ctx->core->fs; 97 gs_fs_list_t *fs = ctx->core->fs;
98 char f[gp_file_name_sizeof];
99 const size_t preflen = strlen(iodev->dname);
100 const size_t nlen = strlen(fname);
98 101
99 if (gp_validate_path(mem, fname, access) != 0) 102 if (preflen + nlen >= gp_file_name_sizeof)
103 return_error(gs_error_invalidaccess);
104
105 memcpy(f, iodev->dname, preflen);
106 memcpy(f + preflen, fname, nlen + 1);
107
108 if (gp_validate_path(mem, f, access) != 0)
100 return gs_error_invalidfileaccess; 109 return gs_error_invalidfileaccess;
101 110
102 /* First we try the open_handle method. */ 111 /* 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,
168 uintptr_t *ptid = &((tid_t *)(iodev->state))->tid; 168 uintptr_t *ptid = &((tid_t *)(iodev->state))->tid;
169 gs_lib_ctx_t *ctx = mem->gs_lib_ctx; 169 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
170 gs_fs_list_t *fs = ctx->core->fs; 170 gs_fs_list_t *fs = ctx->core->fs;
171 const size_t preflen = strlen(iodev->dname);
172 const size_t nlen = strlen(fname);
171 173
172 if (gp_validate_path(mem, fname, access) != 0) 174 if (preflen + nlen >= gp_file_name_sizeof)
175 return_error(gs_error_invalidaccess);
176
177 memcpy(pname, iodev->dname, preflen);
178 memcpy(pname + preflen, fname, nlen + 1);
179
180 if (gp_validate_path(mem, pname, access) != 0)
173 return gs_error_invalidfileaccess; 181 return gs_error_invalidfileaccess;
174 182
175 /* First we try the open_printer method. */ 183 /* 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,
107 FILE ** pfile, char *rfname, uint rnamelen) 107 FILE ** pfile, char *rfname, uint rnamelen)
108{ 108{
109 os2_printer_t *pr = (os2_printer_t *)iodev->state; 109 os2_printer_t *pr = (os2_printer_t *)iodev->state;
110 char driver_name[256]; 110 char driver_name[gp_file_name_sizeof];
111 gs_lib_ctx_t *ctx = mem->gs_lib_ctx; 111 gs_lib_ctx_t *ctx = mem->gs_lib_ctx;
112 gs_fs_list_t *fs = ctx->core->fs; 112 gs_fs_list_t *fs = ctx->core->fs;
113 const size_t preflen = strlen(iodev->dname);
114 const int size_t = strlen(fname);
115
116 if (preflen + nlen >= gp_file_name_sizeof)
117 return_error(gs_error_invalidaccess);
118
119 memcpy(driver_name, iodev->dname, preflen);
120 memcpy(driver_name + preflen, fname, nlen + 1);
121
122 if (gp_validate_path(mem, driver_name, access) != 0)
123 return gs_error_invalidfileaccess;
113 124
114 /* First we try the open_printer method. */ 125 /* First we try the open_printer method. */
115 /* Note that the loop condition here ensures we don't 126 /* 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)
655int 655int
656gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname) 656gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname)
657{ 657{
658 char *fp, f[gp_file_name_sizeof]; 658 char f[gp_file_name_sizeof];
659 const int pipe = 124; /* ASCII code for '|' */ 659 int code;
660 const int len = strlen(fname);
661 int i, code;
662 660
663 /* Be sure the string copy will fit */ 661 /* Be sure the string copy will fit */
664 if (len >= gp_file_name_sizeof) 662 if (strlen(fname) >= gp_file_name_sizeof)
665 return gs_error_rangecheck; 663 return gs_error_rangecheck;
666 strcpy(f, fname); 664 strcpy(f, fname);
667 fp = f;
668 /* Try to rewrite any %d (or similar) in the string */ 665 /* Try to rewrite any %d (or similar) in the string */
669 rewrite_percent_specifiers(f); 666 rewrite_percent_specifiers(f);
670 for (i = 0; i < len; i++) { 667
671 if (f[i] == pipe) { 668 code = gs_add_control_path(mem, gs_permit_file_control, f);
672 fp = &f[i + 1];
673 /* Because we potentially have to check file permissions at two levels
674 for the output file (gx_device_open_output_file and the low level
675 fopen API, if we're using a pipe, we have to add both the full string,
676 (including the '|', and just the command to which we pipe - since at
677 the pipe_fopen(), the leading '|' has been stripped.
678 */
679 code = gs_add_control_path(mem, gs_permit_file_writing, f);
680 if (code < 0)
681 return code;
682 code = gs_add_control_path(mem, gs_permit_file_control, f);
683 if (code < 0)
684 return code;
685 break;
686 }
687 if (!IS_WHITESPACE(f[i]))
688 break;
689 }
690 code = gs_add_control_path(mem, gs_permit_file_control, fp);
691 if (code < 0) 669 if (code < 0)
692 return code; 670 return code;
693 return gs_add_control_path(mem, gs_permit_file_writing, fp); 671 return gs_add_control_path(mem, gs_permit_file_writing, f);
694} 672}
695 673
696int 674int
697gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname) 675gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname)
698{ 676{
699 char *fp, f[gp_file_name_sizeof]; 677 char f[gp_file_name_sizeof];
700 const int pipe = 124; /* ASCII code for '|' */ 678 int code;
701 const int len = strlen(fname);
702 int i, code;
703 679
704 /* Be sure the string copy will fit */ 680 /* Be sure the string copy will fit */
705 if (len >= gp_file_name_sizeof) 681 if (strlen(fname) >= gp_file_name_sizeof)
706 return gs_error_rangecheck; 682 return gs_error_rangecheck;
707 strcpy(f, fname); 683 strcpy(f, fname);
708 fp = f;
709 /* Try to rewrite any %d (or similar) in the string */ 684 /* Try to rewrite any %d (or similar) in the string */
710 for (i = 0; i < len; i++) { 685 rewrite_percent_specifiers(f);
711 if (f[i] == pipe) { 686
712 fp = &f[i + 1]; 687 code = gs_remove_control_path(mem, gs_permit_file_control, f);
713 /* Because we potentially have to check file permissions at two levels
714 for the output file (gx_device_open_output_file and the low level
715 fopen API, if we're using a pipe, we have to add both the full string,
716 (including the '|', and just the command to which we pipe - since at
717 the pipe_fopen(), the leading '|' has been stripped.
718 */
719 code = gs_remove_control_path(mem, gs_permit_file_writing, f);
720 if (code < 0)
721 return code;
722 code = gs_remove_control_path(mem, gs_permit_file_control, f);
723 if (code < 0)
724 return code;
725 break;
726 }
727 if (!IS_WHITESPACE(f[i]))
728 break;
729 }
730 code = gs_remove_control_path(mem, gs_permit_file_control, fp);
731 if (code < 0) 688 if (code < 0)
732 return code; 689 return code;
733 return gs_remove_control_path(mem, gs_permit_file_writing, fp); 690 return gs_remove_control_path(mem, gs_permit_file_writing, f);
734} 691}
735 692
736int 693int