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-07 11:00:09 +0100
commit505eab7782b429017eb434b2b95120855f2b0e3c (patch)
tree0795faf90835b5275b725b36af3d188f8e05fc71
parent0013784cf994827f6e321281732396a063dfb4b2 (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 5f39ebba7..2fb87f769 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 eb566ed06..d2a1aa91d 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++) {