summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Liddell <chris.liddell@artifex.com>2023-06-07 10:23:06 +0100
committerChris Liddell <chris.liddell@artifex.com>2023-06-21 09:51:54 +0100
commit5e65eeae225c7d02d447de5abaf4a8e6d234fcea (patch)
tree3dc47d157f565958a54e7233e2b7e75ddcbe9582
parent8d53dad731e5c35276f79760f6b16ac75a333a39 (diff)
Bug 706761: Don't "reduce" %pipe% file names for permission validation
For regular file names, we try to simplfy relative paths before we use them. Because the %pipe% device can, effectively, accept command line calls, we shouldn't be simplifying that string, because the command line syntax can end up confusing the path simplifying code. That can result in permitting a pipe command which does not match what was originally permitted. Special case "%pipe" in the validation code so we always deal with the entire string.
-rw-r--r--base/gpmisc.c31
-rw-r--r--base/gslibctx.c56
2 files changed, 64 insertions, 23 deletions
diff --git a/base/gpmisc.c b/base/gpmisc.c
index 38d6d60e2..cad018219 100644
--- a/base/gpmisc.c
+++ b/base/gpmisc.c
@@ -1076,16 +1076,29 @@ gp_validate_path_len(const gs_memory_t *mem,
1076 && !memcmp(path + cdirstrl, dirsepstr, dirsepstrl)) { 1076 && !memcmp(path + cdirstrl, dirsepstr, dirsepstrl)) {
1077 prefix_len = 0; 1077 prefix_len = 0;
1078 } 1078 }
1079 rlen = len+1;
1080 bufferfull = (char *)gs_alloc_bytes(mem->thread_safe_memory, rlen + prefix_len, "gp_validate_path");
1081 if (bufferfull == NULL)
1082 return gs_error_VMerror;
1083
1084 buffer = bufferfull + prefix_len;
1085 if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
1086 return gs_error_invalidfileaccess;
1087 buffer[rlen] = 0;
1088 1079
1080 /* "%pipe%" do not follow the normal rules for path definitions, so we
1081 don't "reduce" them to avoid unexpected results
1082 */
1083 if (len > 5 && memcmp(path, "%pipe", 5) != 0) {
1084 bufferfull = buffer = (char *)gs_alloc_bytes(mem->thread_safe_memory, len + 1, "gp_validate_path");
1085 if (buffer == NULL)
1086 return gs_error_VMerror;
1087 memcpy(buffer, path, len);
1088 buffer[len] = 0;
1089 rlen = len;
1090 }
1091 else {
1092 rlen = len+1;
1093 bufferfull = (char *)gs_alloc_bytes(mem->thread_safe_memory, rlen + prefix_len, "gp_validate_path");
1094 if (bufferfull == NULL)
1095 return gs_error_VMerror;
1096
1097 buffer = bufferfull + prefix_len;
1098 if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
1099 return gs_error_invalidfileaccess;
1100 buffer[rlen] = 0;
1101 }
1089 while (1) { 1102 while (1) {
1090 switch (mode[0]) 1103 switch (mode[0])
1091 { 1104 {
diff --git a/base/gslibctx.c b/base/gslibctx.c
index 186248211..3b737df4b 100644
--- a/base/gslibctx.c
+++ b/base/gslibctx.c
@@ -740,14 +740,28 @@ gs_add_control_path_len_flags(const gs_memory_t *mem, gs_path_control_t type, co
740 return gs_error_rangecheck; 740 return gs_error_rangecheck;
741 } 741 }
742 742
743 rlen = len+1; 743 /* "%pipe%" do not follow the normal rules for path definitions, so we
744 buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gp_validate_path"); 744 don't "reduce" them to avoid unexpected results
745 if (buffer == NULL) 745 */
746 return gs_error_VMerror; 746 if (len > 5 && memcmp(path, "%pipe", 5) != 0) {
747 buffer = (char *)gs_alloc_bytes(core->memory, len + 1, "gs_add_control_path_len");
748 if (buffer == NULL)
749 return gs_error_VMerror;
750 memcpy(buffer, path, len);
751 buffer[len] = 0;
752 rlen = len;
753 }
754 else {
755 rlen = len + 1;
747 756
748 if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) 757 buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gs_add_control_path_len");
749 return gs_error_invalidfileaccess; 758 if (buffer == NULL)
750 buffer[rlen] = 0; 759 return gs_error_VMerror;
760
761 if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
762 return gs_error_invalidfileaccess;
763 buffer[rlen] = 0;
764 }
751 765
752 n = control->num; 766 n = control->num;
753 for (i = 0; i < n; i++) 767 for (i = 0; i < n; i++)
@@ -833,14 +847,28 @@ gs_remove_control_path_len_flags(const gs_memory_t *mem, gs_path_control_t type,
833 return gs_error_rangecheck; 847 return gs_error_rangecheck;
834 } 848 }
835 849
836 rlen = len+1; 850 /* "%pipe%" do not follow the normal rules for path definitions, so we
837 buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gp_validate_path"); 851 don't "reduce" them to avoid unexpected results
838 if (buffer == NULL) 852 */
839 return gs_error_VMerror; 853 if (len > 5 && memcmp(path, "%pipe", 5) != 0) {
854 buffer = (char *)gs_alloc_bytes(core->memory, len + 1, "gs_remove_control_path_len");
855 if (buffer == NULL)
856 return gs_error_VMerror;
857 memcpy(buffer, path, len);
858 buffer[len] = 0;
859 rlen = len;
860 }
861 else {
862 rlen = len+1;
840 863
841 if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success) 864 buffer = (char *)gs_alloc_bytes(core->memory, rlen, "gs_remove_control_path_len");
842 return gs_error_invalidfileaccess; 865 if (buffer == NULL)
843 buffer[rlen] = 0; 866 return gs_error_VMerror;
867
868 if (gp_file_name_reduce(path, (uint)len, buffer, &rlen) != gp_combine_success)
869 return gs_error_invalidfileaccess;
870 buffer[rlen] = 0;
871 }
844 872
845 n = control->num; 873 n = control->num;
846 for (i = 0; i < n; i++) { 874 for (i = 0; i < n; i++) {