0002-Sanitize-op-stack-for-error-conditions.patch 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176
  1. From a1de1e6ab51ab37a17975aad1193f2523e7e7e84 Mon Sep 17 00:00:00 2001
  2. From: Chris Liddell <chris.liddell@artifex.com>
  3. Date: Wed, 5 Dec 2018 12:22:13 +0000
  4. Subject: [PATCH] Sanitize op stack for error conditions
  5. We save the stacks to an array and store the array for the error handler to
  6. access.
  7. For SAFER, we traverse the array, and deep copy any op arrays (procedures). As
  8. we make these copies, we check for operators that do *not* exist in systemdict,
  9. when we find one, we replace the operator with a name object (of the form
  10. "/--opname--").
  11. Signed-off-by: Baruch Siach <baruch@tkos.co.il>
  12. ---
  13. Upstream status: commit 13b0a36f818
  14. psi/int.mak | 3 +-
  15. psi/interp.c | 8 ++++++
  16. psi/istack.c | 78 ++++++++++++++++++++++++++++++++++++++++++++++++++++
  17. psi/istack.h | 3 ++
  18. 4 files changed, 91 insertions(+), 1 deletion(-)
  19. diff --git a/psi/int.mak b/psi/int.mak
  20. index 6ab5bf0069dd..6b349cb042dd 100644
  21. --- a/psi/int.mak
  22. +++ b/psi/int.mak
  23. @@ -204,7 +204,8 @@ $(PSOBJ)iparam.$(OBJ) : $(PSSRC)iparam.c $(GH)\
  24. $(PSOBJ)istack.$(OBJ) : $(PSSRC)istack.c $(GH) $(memory__h)\
  25. $(ierrors_h) $(gsstruct_h) $(gsutil_h)\
  26. $(ialloc_h) $(istack_h) $(istkparm_h) $(istruct_h) $(iutil_h) $(ivmspace_h)\
  27. - $(store_h) $(INT_MAK) $(MAKEDIRS)
  28. + $(store_h) $(icstate_h) $(iname_h) $(dstack_h) $(idict_h) \
  29. + $(INT_MAK) $(MAKEDIRS)
  30. $(PSCC) $(PSO_)istack.$(OBJ) $(C_) $(PSSRC)istack.c
  31. $(PSOBJ)iutil.$(OBJ) : $(PSSRC)iutil.c $(GH) $(math__h) $(memory__h) $(string__h)\
  32. diff --git a/psi/interp.c b/psi/interp.c
  33. index 6dc0ddae1b3c..aa5779c51420 100644
  34. --- a/psi/interp.c
  35. +++ b/psi/interp.c
  36. @@ -761,6 +761,7 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
  37. uint size = ref_stack_count(pstack) - skip;
  38. uint save_space = ialloc_space(idmemory);
  39. int code, i;
  40. + ref *safety, *safe;
  41. if (size > 65535)
  42. size = 65535;
  43. @@ -778,6 +779,13 @@ copy_stack(i_ctx_t *i_ctx_p, const ref_stack_t * pstack, int skip, ref * arr)
  44. make_null(&arr->value.refs[i]);
  45. }
  46. }
  47. + if (pstack == &o_stack && dict_find_string(systemdict, "SAFETY", &safety) > 0 &&
  48. + dict_find_string(safety, "safe", &safe) > 0 && r_has_type(safe, t_boolean) &&
  49. + safe->value.boolval == true) {
  50. + code = ref_stack_array_sanitize(i_ctx_p, arr, arr);
  51. + if (code < 0)
  52. + return code;
  53. + }
  54. ialloc_set_space(idmemory, save_space);
  55. return code;
  56. }
  57. diff --git a/psi/istack.c b/psi/istack.c
  58. index 8fe151fa5628..f1a3e511534d 100644
  59. --- a/psi/istack.c
  60. +++ b/psi/istack.c
  61. @@ -27,6 +27,10 @@
  62. #include "iutil.h"
  63. #include "ivmspace.h" /* for local/global test */
  64. #include "store.h"
  65. +#include "icstate.h"
  66. +#include "iname.h"
  67. +#include "dstack.h"
  68. +#include "idict.h"
  69. /* Forward references */
  70. static void init_block(ref_stack_t *pstack, const ref *pblock_array,
  71. @@ -294,6 +298,80 @@ ref_stack_store_check(const ref_stack_t *pstack, ref *parray, uint count,
  72. return 0;
  73. }
  74. +int
  75. +ref_stack_array_sanitize(i_ctx_t *i_ctx_p, ref *sarr, ref *darr)
  76. +{
  77. + int i, code;
  78. + ref obj, arr2;
  79. + ref *pobj2;
  80. + gs_memory_t *mem = (gs_memory_t *)idmemory->current;
  81. +
  82. + if (!r_is_array(sarr) || !r_has_type(darr, t_array))
  83. + return_error(gs_error_typecheck);
  84. +
  85. + for (i = 0; i < r_size(sarr); i++) {
  86. + code = array_get(mem, sarr, i, &obj);
  87. + if (code < 0)
  88. + make_null(&obj);
  89. + switch(r_type(&obj)) {
  90. + case t_operator:
  91. + {
  92. + int index = op_index(&obj);
  93. +
  94. + if (index > 0 && index < op_def_count) {
  95. + const byte *data = (const byte *)(op_index_def(index)->oname + 1);
  96. + if (dict_find_string(systemdict, (const char *)data, &pobj2) <= 0) {
  97. + byte *s = gs_alloc_bytes(mem, strlen((char *)data) + 5, "ref_stack_array_sanitize");
  98. + if (s) {
  99. + s[0] = '\0';
  100. + strcpy((char *)s, "--");
  101. + strcpy((char *)s + 2, (char *)data);
  102. + strcpy((char *)s + strlen((char *)data) + 2, "--");
  103. + }
  104. + else {
  105. + s = (byte *)data;
  106. + }
  107. + code = name_ref(imemory, s, strlen((char *)s), &obj, 1);
  108. + if (code < 0) make_null(&obj);
  109. + if (s != data)
  110. + gs_free_object(mem, s, "ref_stack_array_sanitize");
  111. + }
  112. + }
  113. + else {
  114. + make_null(&obj);
  115. + }
  116. + ref_assign(darr->value.refs + i, &obj);
  117. + break;
  118. + }
  119. + case t_array:
  120. + case t_shortarray:
  121. + case t_mixedarray:
  122. + {
  123. + int attrs = r_type_attrs(&obj) & (a_write | a_read | a_execute | a_executable);
  124. + /* We only want to copy executable arrays */
  125. + if (attrs & (a_execute | a_executable)) {
  126. + code = ialloc_ref_array(&arr2, attrs, r_size(&obj), "ref_stack_array_sanitize");
  127. + if (code < 0) {
  128. + make_null(&arr2);
  129. + }
  130. + else {
  131. + code = ref_stack_array_sanitize(i_ctx_p, &obj, &arr2);
  132. + }
  133. + ref_assign(darr->value.refs + i, &arr2);
  134. + }
  135. + else {
  136. + ref_assign(darr->value.refs + i, &obj);
  137. + }
  138. + break;
  139. + }
  140. + default:
  141. + ref_assign(darr->value.refs + i, &obj);
  142. + }
  143. + }
  144. + return 0;
  145. +}
  146. +
  147. +
  148. /*
  149. * Store the top 'count' elements of a stack, starting 'skip' elements below
  150. * the top, into an array, with or without store/undo checking. age=-1 for
  151. diff --git a/psi/istack.h b/psi/istack.h
  152. index 051dcbe216cf..54be405adfb3 100644
  153. --- a/psi/istack.h
  154. +++ b/psi/istack.h
  155. @@ -129,6 +129,9 @@ int ref_stack_store(const ref_stack_t *pstack, ref *parray, uint count,
  156. uint skip, int age, bool check,
  157. gs_dual_memory_t *idmem, client_name_t cname);
  158. +int
  159. +ref_stack_array_sanitize(i_ctx_t *i_ctx_p, ref *sarr, ref *darr);
  160. +
  161. /*
  162. * Pop the top N elements off a stack.
  163. * The number must not exceed the number of elements in use.
  164. --
  165. 2.20.1