Bug 698680 - Error: /typecheck in --setfileposition--
Summary: Error: /typecheck in --setfileposition--
Status: RESOLVED WONTFIX
Alias: None
Product: Ghostscript
Classification: Unclassified
Component: General (show other bugs)
Version: master
Hardware: PC Linux
: P4 normal
Assignee: Chris Liddell (chrisl)
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2017-10-20 15:52 UTC by m17
Modified: 2017-11-08 01:23 UTC (History)
3 users (show)

See Also:
Customer:
Word Size: ---


Attachments
Example Ghostscript transcript under preview-latex use (42.91 KB, text/plain)
2017-11-06 03:56 UTC, David Kastrup
Details

Note You need to log in before you can comment on or make changes to this bug.
Description m17 2017-10-20 15:52:27 UTC
Since I upgraded ghostscript to version 9.22-1 on Arch Linux, Preview-LaTeX in Emacs is not working anymore. I get the following error output:


/usr/bin/rungs -dOutputFile\=\(_region_.prv/tmp981trj/pr1-8.png\) -q -dDELAYSAFER -dNOPAUSE -DNOPLATFONTS -dPrinted -dTextAlphaBits\=4 -dGraphicsAlphaBits\=4 -sDEVICE\=png16m -r105.205x105.482
GS>{<</PermitFileReading[(_region_.pdf)(_region_.prv/tmp981trj/preview.dsc)]>> setuserparams .locksafe} stopped pop {DELAYSAFER{.setsafe}if}stopped pop/.preview-BP currentpagedevice/BeginPage get dup null eq{pop{pop}bind}if def<</BeginPage{currentpagedevice/PageSize get dup 0 get 1 ne exch 1 get 1 ne or{.preview-BP }{pop}ifelse}bind/PageSize[1 1]>>setpagedevice/preview-do{[count 3 roll save]3 1 roll dup length 0 eq{pop}{setpagedevice}{ifelse .runandhide}stopped{handleerror quit}if aload pop restore}bind def [(_region_.prv/tmp981trj/preview.dsc)(r)file]aload exch dup 0 setfileposition 965()/SubFileDecode filter cvx .runandhide aload pop dup dup 1541 setfileposition 55()/SubFileDecode filter cvx<<>>preview-do
Error: /typecheck in --setfileposition--
Operand stack:
   --nostringval--   --nostringval--   --nostringval--   --nostringval--   1870   1870   1870   1815   1815   1815   1761   1761   1761   1706   1706   1706   1651   1651   1651   1596   1596   1596   1541
Execution stack:
   %interp_exit   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--   --nostringval--   %loop_continue   --nostringval--   --nostringval--   false   1   %stopped_push   .runexec2   --nostringval--   --nostringval--   --nostringval--   2   %stopped_push   --nostringval--
Dictionary stack:
   --dict:991/1684(ro)(G)--   --dict:0/20(G)--   --dict:80/200(L)--
Current allocation mode is local
Current file position is 29
GS<23>


I use Emacs 25.3-1 and AucTeX 11.91-1. Both have not been updated recently.

Someone else is having the same problem, and describing it here in some detail:
https://tex.stackexchange.com/questions/397147/can-not-generate-preview-by-
auctex

Please tell me if you need more information. Thanks for your help!
Comment 1 Ken Sharp 2017-10-21 00:37:39 UTC
(In reply to m17 from comment #0)

 
> Someone else is having the same problem, and describing it here in some
> detail:
> https://tex.stackexchange.com/questions/397147/can-not-generate-preview-by-
> auctex
> 
> Please tell me if you need more information. Thanks for your help!

At a guess I would suggest (in the absence of a PostScript file to look at) that its the use of the non-standard PostScript extension operator unique to Ghostscript '.runandhide'.

As part of the security review in 9.22 we have removed a large number of non-standard extensions which we don't believe to have any real use, .runandhide was one of those.

I'd suggest that you contact the maintainer of whatever it is producing the PostScript (Preview-LaTex ?) and bring this to their attention.

Ideally ask that maintainer to contact us for further discussion of the situation. If there is genuinely a good reason for using the operator we will consider re-introducing it, but I doubt there actually is a good reason. As it is the prolog you've supplied looks like an invitation to security problems. It looks like an attempt to bypass the -dSAFER mechanism in Ghostscript.

This is, however, merely a guess, we'd need the actual input file to stand any chance of figuring out the real problem.
Comment 2 Nguyen Dang 2017-10-22 05:47:42 UTC
(In reply to Ken Sharp from comment #1)
> (In reply to m17 from comment #0)
> 
>  
> > Someone else is having the same problem, and describing it here in some
> > detail:
> > https://tex.stackexchange.com/questions/397147/can-not-generate-preview-by-
> > auctex
> > 
> > Please tell me if you need more information. Thanks for your help!
> 
> At a guess I would suggest (in the absence of a PostScript file to look at)
> that its the use of the non-standard PostScript extension operator unique to
> Ghostscript '.runandhide'.
> 
> As part of the security review in 9.22 we have removed a large number of
> non-standard extensions which we don't believe to have any real use,
> .runandhide was one of those.
> 
> I'd suggest that you contact the maintainer of whatever it is producing the
> PostScript (Preview-LaTex ?) and bring this to their attention.
> 
> Ideally ask that maintainer to contact us for further discussion of the
> situation. If there is genuinely a good reason for using the operator we
> will consider re-introducing it, but I doubt there actually is a good
> reason. As it is the prolog you've supplied looks like an invitation to
> security problems. It looks like an attempt to bypass the -dSAFER mechanism
> in Ghostscript.
> 
> This is, however, merely a guess, we'd need the actual input file to stand
> any chance of figuring out the real problem.

I can confirm your guess. After downgrading ghostscript to version 9.21-3, Preview-Latex works again.
Comment 3 Ken Sharp 2017-11-01 09:02:34 UTC
I'm unable to find a maintainer for this package. The bug is not (in my opinion) in Ghostscript, its the use of non-standard extensions to the language.

I'd like to get this resolved, but at the moment I can't see a way forward. Downgrading Ghostscript is a short-term solution, but in the long run not a viable option. Bugs and security patches will not be back-portable to old versions, sooner or later using the old version will not be viable.

If anyone can find a maintainer for this code, and have them contact us, I'd like to discuss it with them with a view to removing the non-standard code from (I think) AucTeX. In the meantime I'm closing this bug report.
Comment 4 David Kastrup 2017-11-06 03:56:16 UTC
Created attachment 14440 [details]
Example Ghostscript transcript under preview-latex use
Comment 5 David Kastrup 2017-11-06 03:57:30 UTC
As the original author responsible for the code in preview-latex using .runandhide, I had been contacted off-tracker about this issue.

Private communication not being able to resolve this issue, the tracker has been chosen as the next way forward.

Ken Sharp asked for transcripts of the Ghostscript sessions to be appended.  I now created the necessary tools for diverting the respective sessions' Ghostscript input in order to append these.  In the process of this I noticed that preview-latex's current default modes of operation do not correspond to the original design I remembered when being brought into the discussion and based my contributions on.

In particular, preview-latex's current dependencies on .runandhide, while including one using a "save" object, do not appear to be security-relevant but rather use it for processing single files on a clean stack and clean graphics context while saving some information across the scope of processing those files.

It should therefore be possible to instead store the pertinent information in a named variable: it being accessible to included files will still be open to nuisance tampering but should not result in security implications, just in uncleaner code and uncleaner namespaces: even beyond SAFER/DELAYSAFER considerations .runandhide had been a nice tool for executing isolated parts of code on a clean slate.

This use is not theoretical: I remember that we originally used .runandhide only for hiding the "save" object while retaining other information on the stack, and badly written PostScript files led to followup errors very hard to track down because they accidentally messed with the other information on the stack, if only by leaving material on top.

I am attaching a transcript of both Ghostscript command line and its standard input for one of the current use cases (PDF->PNG conversion via a file created by pdftodsc: using Ghostscript in a similarly directed manner on PDF files directly must certainly be possible but was not documented well enough at the time this code was written).

At the current point of time I don't require assistance for how to move forward with resolving the problem for preview-latex: a named variable for storing the pertinent information should work well enough and previous refactorings of the code already had removed the security relevance of the .runandhide operator being used here.  I apologize for not having remembered that.
Comment 6 Chris Liddell (chrisl) 2017-11-06 04:44:40 UTC
I feel a little background might be beneficial.

What your code does with .runandhide is what's known as running an "encapsulated job" (this is *not* the same as encapsulated Postscript EPS files). An encapsulated job essentially means having a initial state in the interpreter which a job cannot change without special action (involving a password), to which the interpreter will always return at the end-of-job

The thing is, Postscript includes the ability to run encapsulated jobs (see the startjob and exitserver operators). In fact, Ghostscript is about the only full Postscript interpreter I've encountered that doesn't default to running jobs encapsulated.

So, given that the language includes support for this, it seemed to us pointless having a Ghostscript specific, rarely (if ever) QA tested, way to achieve the same thing.

The .runandhide operator was one of many Ghostscript specific operators that we removed or made inaccessible as part of a review we undertook before the 9.22 release.

A big part of the problem is that many of these were introduced long ago, and we have little, if any, documentation giving the original reasoning for them.

.runandhide is an example of where that's a problem: there may have been a solid reason for providing a non-standard way to achieve something the language already supports, but if there was, it is lost in the mists of time. Hence why I wanted communications done here (on bugzilla) so, in the event we conclude we have to re-introduce .runandhide, we then have full visibility of *why*.



Anyway, (and correct me if I'm wrong) as I understand Comment #5, we need no further action on this, at this time. I will leave the bug open for at least a day or two, just in case.
Comment 7 David Kastrup 2017-11-06 05:06:12 UTC
This is not really the same as an encapsulated job since a number of things are shared: the same open files, the same already loaded fonts, the same already loaded preamble of a file structured in DSC manner.  When actually separating this into independent jobs, performance would drop significantly since then only the PostScript startup time, contributing rather little to the per-run costs, would be saved.

Originally, this was used for switching between SAFER and not-SAFER modes in a controlled manner.  Over the years, this has been reorganized several times, ultimately allowing for SAFER state to be entered permantly rather than only when interpreting single pages.  As far as I read the current code, .runandhide is now only used for maintaining clean stack and interpreter setup for the sake of each page.

This is decidedly less than what a job server's responsibility would be I think.  I admit that when I looked at its documentation in the old days, it was eyes-glaze-over material to me.  In contrast, the semantics of .runandhide were limited and clear.  Also they don't, by themselves, have any security implications that I can see: those are rather implied by the semantics of a save/restore pair across setting SAFER mode.

preview-latex still uses some Ghostscript-specific things, like .setsafe and .locksafe and the PermitFileReading user parameter (correct me if I am wrong about those being specific to Ghostscript).  Foregoing those without the use of -dSAFER breaking down completely would not likely be an option, so we remain dependent on some continuity in Ghostscript's implementation.
Comment 8 David Kastrup 2017-11-06 07:06:55 UTC
Looking at the default documentation for the current Ubuntu distribution 17.10 (which uses Ghostscript 9.21), I read in /usr/share/ghostscript/Doc.htm for -dSAFER :

 When running -dNOSAFER it is possible to perform a save, followed by .setsafe, execute a file or procedure in SAFER mode, then use restore to return to NOSAFER mode. In order to prevent the save object from being restored by the foreign file or procedure, the .runandhide operator should be used to hide the save object from the restricted procedure.

Given that this is the state of currently distributed documentation (note that I cannot find anywhere what password startjob, a somewhat more standard replacement for some uses, is supposed to take) in quite current-day Ghostscript distributions, it would appear that the deprecation process for a thoroughly documented and recommended operator (Language.htm is actually chock-full of examples and recommendations) is a bit rushed here.

Given its prevalence in current documentation, it would make sense to first deprecate it for a while before removal.  It is not like this operator, in itself, has hard-to-control security implications.

In contrast, the documentation for using startjob is not there.  The PLRM states in appendix C.3.1 that the startjob password when a "PostScript interpreter is initially installed" is an empty string, yet even
gsnd -c "true () startjob =="
shows
dak@lola:~$ gsnd -c 'true () startjob =='
GPL Ghostscript 9.21 (2017-03-16)
Copyright (C) 2017 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
false
GS>

So as late as 9.21, there is no documentation allowing to actually use startjob, and .runandhide is the documented way for dealing with temporary use of .setsafe .

In the light of that, I'd strongly suggest rethinking the deprecation strategy for .runandhide .
Comment 9 David Kastrup 2017-11-06 07:42:29 UTC
The current documentation has removed references to .runandhide .  Neither Use.htm nor Language.htm contain any reference to the default password for startjob, and the -dSAFER information has been changed to read:

> When running -dNOSAFER it is possible to perform a save, followed by .setsafe, execute a file or procedure in SAFER mode, then use restore to return to NOSAFER mode. It is possible that the a crafted foreign file could restore back to a point when NOSAFER was in operation. 

So the previous suggestion for temporarily entering safe mode is essentially replaced by "tough luck, we decided to remove any possibility to do this safely".

startjob might conceivably work for some use cases, but the documentation does not contain the necessary information allowing to facilitate it.

What part of the story am I missing?  Currently I have problems making sense of this.
Comment 10 Ray Johnston 2017-11-06 08:45:10 UTC
Using Ghostscript to run under a job server requires the -dJOBSERVER option.

This will create an outer save state that can be restored by:
   true () startjob

Changes made in the outermost level will become part of subsequent job's
initial state. After persistent changes are made, you can return to the
encapsulated job state with:
    false 

Note that encapsulated jobs cannot "quit" (this operator is a no-op in an
encapsulated job) -- only the outermost level can execute 'quit'

Errors during an encapsulated job will end that job after executing the error
handler. The error handler of the outermost server level is used so that
PostScript that has bad error handlers will be ignored.

The problem is that the 'save' object for the outermost level is kept in
".jobsave" in the serverdict, which means that it is possible for a simple
PS operation to 'restore' to that state without the use of the starjob with
the password.

Note also that the default password of Ghostscript is not at all secure, in
fact both an empty string () and 0 work, and passwords in general are not a
very secure method, but if the PS is "constrained" (i.e., PS from the wild is
not executed) then using -dJOBSERVER may suffice.
Comment 11 Chris Liddell (chrisl) 2017-11-06 08:56:20 UTC
We've tried deprecating things and asking for feedback before removing completely, and it has *never* worked. No one contacts us until we actually remove the thing in question.

As you've already been told, if there's a compelling reason to keep .runandhide, we'll do so. (NOTE: the operator still exists, it is simply undefined during initialisation).

But, frankly, we *had* to reduce the number of custom operations that gave access to interpreter internals which jobs aren't supposed to be able to use. We'd have preferred to ask for feedback before just removing stuff *but*, as I said above, we've tried that before, and got nothing back until we actually made the changes.
Comment 12 David Kastrup 2017-11-06 13:24:34 UTC
Thanks for the explanation of -dJOBSERVER, Ray.  Under the string "startjob" I could find nothing in the documentation except some basics about its password management.

Some cursory tests seem to corroborate that even in a local job started with
true () startjob == false () startjob ()
I can access the job save state with serverdict /.jobsave get .

The .jobsave entry is not part of PLRM: this is just how Ghostscript does it.

So Ghostscript has removed .runandhide as a way to temporarily enter and exit SAFER mode, leaving the standard startjob tool to do the same job though its implementation is unable to do so.  Now I still may be missing some of the picture: after all, I have been checking Ghostscript 9.21 so things might have changed with regard to .jobsave behavior.

But at the very least, there is no usefully temporarily SAFER procedure that would work for both 9.21 and 9.22, and there has been no grace or warning period either, and given that .runandhide does so little at all, I would be surprised if it was hard to do right.

The job server approach is also a tool with global semantics while .runandhide has nicely local semantics.  It would have made for something nice in the original PostScript language definition.

Now preview-latex does not suffer fundamentally: as far as I can see, we just sacrifice elegance and namespace cleanliness here since we had already bailed out of temporary safety approaches previously.

But I hope we'll get better warning and deprecation phases when .setsafe and .locksafe and whatever else get the shaft in a similar manner.