REDHAT-BUG-2542396: Use After Free
Ghostscript's -dSAFER sandbox can be bypassed by a crafted PostScript document that chains two memory-safety bugs to achieve arbitrary command execution in the Ghostscript process context.
Bug 1 , Procedure-source filter stream use-after-free (psi/zfproc.c): The sprocreadcontinue function stores a procedure's returned string via a raw C assignment (ss->data = opbuf at line 323) without a save/restore write barrier. A procedure stream created in global VM can be tricked into holding a reference to a local-VM string; after save/restore frees that string, the stale reference enables a heap information leak that defeats ASLR. The 10.09.0 source contains a cross-space copy defense (sproccopystring, lines 313-321) and save-ID tracking (sprocrecorddata/sprocdatavalid), but the PoC was confirmed working on versions through 10.07.1, suggesting these defenses are either recent additions or bypassable.
Bug 2 , Shading Function array out-of-bounds heap write (base/gsshade.c, base/gsfunc3.c, psi/zshade.c): checkCBFD validates the number of output components for a shading Function, but when the Function is an array, it checked only the ArrayedOutput (AdOt) wrapper's n field (set to the array length). A single-element array wrapping a sub-function with many outputs passes the n==ncomp check. At evaluation, fnAdOtevaluate (gsfunc3.c line 643-648) calls gsfunctionevaluate for each sub-function passing out+i as the output pointer, assuming 1 output per sub-function. If the sub-function actually writes multiple outputs, this overruns the color buffer. The 10.09.0 source contains a fix in checkCBFD (lines 82-93) that validates each sub-function declares exactly 1 output.
The exploit chain: (1) UAF leak recovers a PIE code pointer and heap pointers; (2) Type 5 shading OOB write overwrites a SubFileDecode stream's read cursor to build an arbitrary-read primitive; (3) Structural memory scanning locates gslibctxcoret.pathcontrolactive; (4) Shading write sets pathcontrolactive to 0; (5) Normal PostScript %pipe% support executes the command.
The PoC was publicly released by V12 Security on 2026-09-26 at https://github.com/v12-security/pocs/tree/main/ghostscript following a talk at BSides Canberra 2026. Confirmed working on Ghostscript 10.00.0 through 10.07.1 across Alpine, Arch, Debian, Fedora, and Ubuntu. Dynamic testing in sandbox confirmed the UAF leak primitive works on GS 10.06.0 (Fedora) but full exploitation failed due to aarch64 architecture mismatch (PoC targets x86-64). The GhostPDL 10.09.0 source contains apparent fixes for both bugs.
Red Hat dynamic verification (RHEL 10.2 x8664 lab host): ghostscript-10.02.1-16.el10 (CentOS Stream 10) and ghostscript-10.02.1-16.el100 (UBI 10) both executed a shell command with -dSAFER; gs exited with signal 139 after proof file write.
Reporter: Akiyoshi Kurita (ticket submitter); original research by V12 Security. PSIRT ticket: PSIRTSUPT-24732
Affected Software
Remediation
Recommended actions to resolve this vulnerability, in priority order.
- Upgrade
Upgrade
Ghostscriptto a version that resolves this vulnerability.Fixed in 10.09.0
Event History
Frequently Asked Questions
What does an attacker need to provide to exploit this issue?
The attacker needs to get Ghostscript to process a crafted PostScript document. The document chains a procedure-source filter stream use-after-free with a shading Function array out-of-bounds heap write.
Does running Ghostscript with -dSAFER prevent exploitation?
No. The reported issue specifically bypasses the -dSAFER sandbox and can result in arbitrary command execution in the Ghostscript process context.
Which versions have been confirmed vulnerable?
The proof of concept was confirmed working through Ghostscript 10.07.1. Although 10.09.0 source includes cross-space copying and save-ID tracking defenses, the available data does not establish that those changes fully remediate the issue.