Bug 2542396 (CVE-2026-101258) - CVE-2026-101258 ghostscript: ghostscript: -dSAFER sandbox bypass via Type 5 shading OOB write and procedure-stream use-after-free
Summary: CVE-2026-101258 ghostscript: ghostscript: -dSAFER sandbox bypass via Type 5 s...
Keywords:
Status: NEW
Alias: CVE-2026-101258
Product: Security Response
Classification: Other
Component: vulnerability
Version: unspecified
Hardware: All
OS: Linux
high
high
Target Milestone: ---
Assignee: Product Security
QA Contact:
URL:
Whiteboard:
Depends On: 2546645 2546646
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-09-28 10:25 UTC by OSIDB Bzimport
Modified: 2026-10-06 16:00 UTC (History)
3 users (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-09-28 10:25:28 UTC
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 s_proc_read_continue 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 (s_proc_copy_string, lines 313-321) and save-ID tracking (s_proc_record_data/s_proc_data_valid), 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): check_CBFD 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, fn_AdOt_evaluate (gsfunc3.c line 643-648) calls gs_function_evaluate 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 check_CBFD (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 gs_lib_ctx_core_t.path_control_active; (4) Shading write sets path_control_active 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 x86_64 lab host): ghostscript-10.02.1-16.el10 (CentOS Stream 10) and ghostscript-10.02.1-16.el10_0 (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


Note You need to log in before you can comment on or make changes to this bug.