Bug 699670

Summary: gssetresolution memory corruption
Product: Ghostscript Reporter: Tavis Ormandy <taviso>
Component: Security (public)Assignee: Chris Liddell (chrisl) <chris.liddell>
Status: RESOLVED FIXED    
Severity: normal CC: cbuissar, henry.stiles, scorneli
Priority: P4    
Version: unspecified   
Hardware: PC   
OS: Linux   
Customer: Word Size: ---

Description Tavis Ormandy 2018-08-24 18:25:28 UTC
This works in HEAD:

$ ./gs -dSAFER -sDEVICE=ppmraw
GPL Ghostscript GIT PRERELEASE 9.24 (2018-03-21)
Copyright (C) 2018 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>false false false gssetresolution
quit
Error: /typecheck in --.putdeviceprops--
Operand stack:
   false
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--   --nostringval--   1882   5   3   %oparray_pop   --nostringval--   1863   5   3   %oparray_pop
Dictionary stack:
   --dict:978/1684(ro)(G)--   --dict:0/20(G)--   --dict:78/200(L)--
Current allocation mode is local
Last OS error: No such file or directory
Current file position is 34
GS<1>Segmentation fault
Comment 1 Henry Stiles 2018-08-24 19:16:35 UTC
I wasn't able to reproduce the segv, but see an invalid write in valgrind:

valgrind ./gs -dSAFER -sDEVICE=ppmraw
==5006== Memcheck, a memory error detector
==5006== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==5006== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==5006== Command: ./gs -dSAFER -sDEVICE=ppmraw
==5006== 
GPL Ghostscript GIT PRERELEASE 9.24 (2018-03-21)
Copyright (C) 2018 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
GS>false false false gssetresolution
==5006== Invalid write of size 8
==5006==    at 0x4C326CB: memcpy@@GLIBC_2.14 (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5006==    by 0x7A02E2: gx_device_init (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x7A040E: gs_copydevice2 (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x8FF016: zcopydevice2 (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x8D2B19: interp (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x8D353C: gs_interpret (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x8C7BCE: gs_main_run_string_with_length (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x8C96E3: run_string (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x46D11D: main (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==  Address 0xc9a8648 is 0 bytes after a block of size 1,880 alloc'd
==5006==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==5006==    by 0x7B63D5: gs_heap_alloc_bytes (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x7943D1: alloc_acquire_clump (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x794C2A: alloc_obj.isra.4 (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x7A03F2: gs_copydevice2 (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x8FF016: zcopydevice2 (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x8D2B19: interp (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x8D353C: gs_interpret (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x8C7BCE: gs_main_run_string_with_length (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x8C96E3: run_string (in /home/henrys/ghostpdl_last6/bin/gs)
==5006==    by 0x46D11D: main (in /home/henrys/ghostpdl_last6/bin/gs)
==5006== 
Error: /typecheck in --.putdeviceprops--
Operand stack:
   false
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--   --nostringval--   1866   5   3   %oparray_pop   --nostringval--   1847   5   3   %oparray_pop
Dictionary stack:
   --dict:978/1684(ro)(G)--   --dict:0/20(G)--   --dict:78/200(L)--
Current allocation mode is local
Last OS error: No such file or directory
Current file position is 34
GS<1>


Thanks for reporting Tavis but we probably won't get to this until Monday.
Comment 2 Chris Liddell (chrisl) 2018-08-27 13:14:20 UTC
Fixed in:

http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=f52734ba87


Note that gssetresolution is non-standard, and not used anywhere, so it is being removed shortly.
Comment 3 Chris Liddell (chrisl) 2018-08-27 14:10:39 UTC
Unfortunately, I just realised why the above commit is not the correct solution....
Comment 4 Chris Liddell (chrisl) 2018-08-28 13:03:40 UTC
It really is fixed in this commit:

http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=c9b362ba908c


Also:
http://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff;h=5b5536fa88a9
removes gsset/getresolution.