diff options
-rw-r--r-- | base/gdevpipe.c | 22 | ||||
-rw-r--r-- | base/gp_mshdl.c | 11 | ||||
-rw-r--r-- | base/gp_msprn.c | 10 | ||||
-rw-r--r-- | base/gp_os2pr.c | 13 | ||||
-rw-r--r-- | base/gslibctx.c | 69 |
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) | |||
655 | int | 655 | int |
656 | gs_add_outputfile_control_path(gs_memory_t *mem, const char *fname) | 656 | gs_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 | ||
696 | int | 674 | int |
697 | gs_remove_outputfile_control_path(gs_memory_t *mem, const char *fname) | 675 | gs_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 | ||
736 | int | 693 | int |