]> code.ossystems Code Review - openembedded-core.git/blob
cd786595833e99541e2a0de159f8c21a7d096206
[openembedded-core.git] /
1 From 1f9a91c86bd56acf57826b9b0e020ebe1953e2ae Mon Sep 17 00:00:00 2001
2 From: Chris Liddell <chris.liddell@artifex.com>
3 Date: Thu, 4 Oct 2018 10:42:13 +0100
4 Subject: [PATCH 3/5] Bug 699832: add control over hiding error handlers.
5
6 With a previous commit changing error handling in SAFER so the handler gets
7 passed a name object (rather than executable object), it is less critical to
8 hide the error handlers.
9
10 This introduces a -dSAFERERRORS option to force only use of the default error
11 handlers.
12
13 It also adds a .setsafererrors Postscript call, meaning a caller, without
14 -dSAFERERRORS, can create their own default error handlers (in errordict, as
15 normal), and then call .setsafererrors meaning their own handlers are always
16 called.
17
18 With -dSAFERERRORS or after a call to .setsafererrors, .setsafererrors is
19 removed.
20
21 CVE: CVE-2018-17961
22 Upstream-Status: Backport [git://git.ghostscript.com/ghostpdl.git]
23 Signed-off-by: Hongxu Jia <hongxu.jia@windriver.com>
24 ---
25  Resource/Init/gs_init.ps | 42 +++++++++++++++++++++++++++++------------
26  psi/interp.c             | 49 ++++++++++++++++++++++++++++--------------------
27  2 files changed, 59 insertions(+), 32 deletions(-)
28
29 diff --git a/Resource/Init/gs_init.ps b/Resource/Init/gs_init.ps
30 index bec307d..f952f32 100644
31 --- a/Resource/Init/gs_init.ps
32 +++ b/Resource/Init/gs_init.ps
33 @@ -188,6 +188,16 @@ currentdict /DELAYSAFER known { /DELAYSAFER //true def /NOSAFER //true def } if
34    currentdict /PARANOIDSAFER known or  % PARANOIDSAFER is equivalent
35  }
36  ifelse def
37 +
38 +/SAFERERRORS
39 +currentdict /NOSAFERERRORS known
40 +{
41 +  //false
42 +}
43 +{
44 +  currentdict /SAFERERRORS known
45 +} ifelse def
46 +
47  currentdict /SHORTERRORS known   /SHORTERRORS exch def
48  currentdict /TTYPAUSE known   /TTYPAUSE exch def
49  currentdict /WRITESYSTEMDICT known   /WRITESYSTEMDICT exch def
50 @@ -1123,12 +1133,23 @@ errordict begin
51   } bind def
52  end            % errordict
53  
54 -% Put all the default handlers in gserrordict
55 -gserrordict
56 -errordict {2 index 3 1 roll put} forall
57 -noaccess pop
58 -% remove the non-standard errors from errordict
59 +gserrordict /unknownerror errordict /unknownerror get put
60  errordict /unknownerror .undef
61 +
62 +/.SAFERERRORLIST ErrorNames def
63 +/.setsafererrors
64 +{
65 +% Put all the requested handlers in gserrordict
66 +  gserrordict
67 +  //.SAFERERRORLIST
68 +  {dup errordict exch get 2 index 3 1 roll put} forall
69 +  noaccess pop
70 +  systemdict /.setsafeerrors .forceundef
71 +  systemdict /.SAFERERRORLIST .forceundef
72 +} bind executeonly odef
73 +
74 +SAFERERRORS {.setsafererrors} if
75 +
76  % Define a stable private copy of handleerror that we will always use under
77  % JOBSERVER mode.
78  /.GShandleerror errordict /handleerror get def
79 @@ -1760,18 +1781,15 @@ currentdict /.runlibfile .undef
80  
81  % Bind all the operators defined as procedures.
82  /.bindoperators                % binds operators in currentdict
83 - { % Temporarily disable the typecheck error.
84 -   errordict /typecheck 2 copy get
85 -   errordict /typecheck { pop } put    % pop the command
86 + {
87     currentdict
88      { dup type /operatortype eq
89 -       { % This might be a real operator, so bind might cause a typecheck,
90 -         % but we've made the error a no-op temporarily.
91 -         .bind
92 +       {
93 +         % This might be a real operator, so bind might cause a typecheck
94 +         {.bind} .internalstopped pop
95         }
96        if pop pop
97      } forall
98 -   put
99   } def
100  DELAYBIND not { .bindoperators } if
101  
102 diff --git a/psi/interp.c b/psi/interp.c
103 index 3dd5f7a..cd894f9 100644
104 --- a/psi/interp.c
105 +++ b/psi/interp.c
106 @@ -662,27 +662,18 @@ again:
107      if (gs_errorname(i_ctx_p, code, &error_name) < 0)
108          return code;            /* out-of-range error code! */
109  
110 -    /*  If LockFilePermissions is true, we only refer to gserrordict, which
111 -     *  is not accessible to Postcript jobs
112 +    /*  We refer to gserrordict first, which is not accessible to Postcript jobs
113 +     *  If we're running with SAFERERRORS all the handlers are copied to gserrordict
114 +     *  so we'll always find the default one. If not SAFERERRORS, only gs specific
115 +     *  errors are in gserrordict.
116       */
117 -    if (i_ctx_p->LockFilePermissions) {
118 -        if (((dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
119 -              dict_find(perrordict, &error_name, &epref) <= 0))
120 -            )
121 -            return code;            /* error name not in errordict??? */
122 -    }
123 -    else {
124 -        /*
125 -         * For greater Adobe compatibility, only the standard PostScript errors
126 -         * are defined in errordict; the rest are in gserrordict.
127 -         */
128 -        if (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
129 -            (dict_find(perrordict, &error_name, &epref) <= 0 &&
130 -             (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
131 -              dict_find(perrordict, &error_name, &epref) <= 0))
132 -            )
133 -            return code;            /* error name not in errordict??? */
134 -    }
135 +    if (dict_find_string(systemdict, "gserrordict", &perrordict) <= 0 ||
136 +        (dict_find(perrordict, &error_name, &epref) <= 0 &&
137 +         (dict_find_string(systemdict, "errordict", &perrordict) <= 0 ||
138 +          dict_find(perrordict, &error_name, &epref) <= 0))
139 +        )
140 +        return code;            /* error name not in errordict??? */
141 +
142      doref = *epref;
143      epref = &doref;
144      /* Push the error object on the operand stack if appropriate. */
145 @@ -695,6 +686,24 @@ again:
146          }
147          *osp = *perror_object;
148          errorexec_find(i_ctx_p, osp);
149 +        /* If using SAFER, hand a name object to the error handler, rather than the executable
150 +         * object/operator itself.
151 +         */
152 +        if (i_ctx_p->LockFilePermissions) {
153 +            code = obj_cvs(imemory, osp, buf + 2, 256, &rlen, (const byte **)&bufptr);
154 +            if (code < 0) {
155 +                const char *unknownstr = "--unknown--";
156 +                rlen = strlen(unknownstr);
157 +                memcpy(buf, unknownstr, rlen);
158 +            }
159 +            else {
160 +                buf[0] = buf[1] = buf[rlen + 2] = buf[rlen + 3] = '-';
161 +                rlen += 4;
162 +            }
163 +            code = name_ref(imemory, buf, rlen, osp, 1);
164 +            if (code < 0)
165 +                make_null(osp);
166 +        }
167      }
168      goto again;
169  }
170 -- 
171 2.7.4
172