Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

A long list of vulnerabilites (CVE-2020-16287 up to CVE-2020-16310 and CVE-2020-17538)has been fixed for ghostscript-9.51 after a thorough security review.

...

This list contains only CVEs of third parties with correctly applying the awkward zlib API with buffer over- and/or underruns. zlib itself is not subject to any CVE, which appear during the last 3 yearsappeared during the last 3 years.

valgrind Runs

These valgrind runs are based on an example from our customers, which crashes ghostscript-9.25 when rendering to the pngalpha output device. The example involves fonts, image masks and is other wise not very complex.

The test runs have been executed on a centos8 machine with recent centos 8.2 updates as of 2020-12-28.

valgrind clazzes-ghostscript-9.53.3-1 pngalpha

Code Block
[root@centos8 ~]# valgrind /usr/clazzes-ghostscript/bin/gs -sDEVICE=pngalpha -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==408600== Memcheck, a memory error detector
==408600== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==408600== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==408600== Command: /usr/clazzes-ghostscript/bin/gs -sDEVICE=pngalpha -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==408600== 
GPL Ghostscript 9.53.3 (2020-10-01)
Copyright (C) 2020 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Processing pages 1 through 1.
Page 1
==408600== Syscall param pwrite64(buf) points to uninitialised byte(s)
==408600==    at 0x53D6278: pwrite (in /usr/lib64/libpthread-2.28.so)
==408600==    by 0x45B984: gp_pwrite_impl (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x560CF7: clist_fwrite_chars (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x54B5FB: cmd_write_pseudo_band (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x538918: clist_icc_writetable (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x538D3B: clist_end_page (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x54509F: clist_close_writer_and_init_reader (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x5459E2: clist_get_bits_rectangle (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x85C31A: gx_default_get_bits (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x52D933: gx_downscaler_getbits (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x75A061: do_png_print_page (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x525662: gdev_prn_output_page_aux (in /usr/clazzes-ghostscript/bin/gs)
==408600==  Address 0x81a9ef8 is 11,960 bytes inside a block of size 20,048 alloc'd
==408600==    at 0x4C30F0B: malloc (vg_replace_malloc.c:307)
==408600==    by 0x780777: gs_heap_alloc_bytes (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x75DFE4: alloc_acquire_clump (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x75EEA1: alloc_obj.isra.4 (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x8DEA18: alloc_save_change_alloc (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x8D9915: gs_alloc_ref_array (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x8A3DCD: dict_create_unpacked_keys.isra.0 (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x8A4105: dict_unpack (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x8A50B1: dict_put (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x8BC5F1: zput (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x8A95F5: gs_interpret (in /usr/clazzes-ghostscript/bin/gs)
==408600==    by 0x89D5B8: gs_main_run_string_end (in /usr/clazzes-ghostscript/bin/gs)
==408600== 
==408600== 
==408600== HEAP SUMMARY:
==408600==     in use at exit: 0 bytes in 0 blocks
==408600==   total heap usage: 7,108 allocs, 7,108 frees, 108,179,726 bytes allocated
==408600== 
==408600== All heap blocks were freed -- no leaks are possible
==408600== 
==408600== Use --track-origins=yes to see where uninitialised values come from
==408600== For lists of detected and suppressed errors, rerun with: -s
==408600== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

The reported writing of uninitialized memory seems to be immanent to the png output writer, this is a frequent warning for compressed output wrriting.

valgrind ghostscript-9.25-7.el8 pngalpha crash

Code Block
[root@centos8 ~]# valgrind /usr/bin/gs -sDEVICE=pngalpha -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==408602== Memcheck, a memory error detector
==408602== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==408602== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==408602== Command: /usr/bin/gs -sDEVICE=pngalpha -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==408602== 
GPL Ghostscript 9.25 (2018-09-13)
Copyright (C) 2018 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
==408602== Syscall param pwrite64(buf) points to uninitialised byte(s)
==408602==    at 0x60AFBD7: pwrite (in /usr/lib64/libc-2.28.so)
==408602==    by 0x4F56396: gp_fpwrite (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x503AFAC: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x502618F: cmd_write_pseudo_band (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x50132C2: clist_icc_writetable (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x501371F: clist_end_page (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x501F747: clist_close_writer_and_init_reader (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x5020172: clist_get_bits_rectangle (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x5039059: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x51F71D2: gx_default_get_bits (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x500741E: gx_downscaler_getbits (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x516A279: ??? (in /usr/lib64/libgs.so.9.25)
==408602==  Address 0xf00db00 is 11,728 bytes inside a block of size 20,048 alloc'd
==408602==    at 0x4C30F0B: malloc (vg_replace_malloc.c:307)
==408602==    by 0x518F6B3: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x516C3D4: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x516D2EE: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x52757F7: gs_alloc_ref_array (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x523D1E5: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x523D385: dict_alloc (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x5242194: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x5243C16: gs_interpret (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x5236BCB: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x52370BF: gs_main_init2aux (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x5237695: gs_main_init2 (in /usr/lib64/libgs.so.9.25)
==408602== 
==408602== Invalid read of size 8
==408602==    at 0x5000D77: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x50015A2: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x4FC3F7F: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x4FC9854: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x5017320: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x501E131: clist_playback_band (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x501F94B: clist_playback_file_bands (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x501FD8D: clist_render_rectangle (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x501FFAE: clist_rasterize_lines (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x502021E: clist_get_bits_rectangle (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x5039059: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x51F71D2: gx_default_get_bits (in /usr/lib64/libgs.so.9.25)
==408602==  Address 0x18 is not stack'd, malloc'd or (recently) free'd
==408602== 
==408602== 
==408602== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==408602==  Access not within mapped region at address 0x18
==408602==    at 0x5000D77: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x50015A2: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x4FC3F7F: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x4FC9854: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x5017320: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x501E131: clist_playback_band (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x501F94B: clist_playback_file_bands (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x501FD8D: clist_render_rectangle (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x501FFAE: clist_rasterize_lines (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x502021E: clist_get_bits_rectangle (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x5039059: ??? (in /usr/lib64/libgs.so.9.25)
==408602==    by 0x51F71D2: gx_default_get_bits (in /usr/lib64/libgs.so.9.25)
==408602==  If you believe this happened as a result of a stack
==408602==  overflow in your program's main thread (unlikely but
==408602==  possible), you can try to increase the size of the
==408602==  main thread stack using the --main-stacksize= flag.
==408602==  The main thread stack size used in this run was 8388608.
==408602== 
==408602== HEAP SUMMARY:
==408602==     in use at exit: 24,266,244 bytes in 1,985 blocks
==408602==   total heap usage: 9,208 allocs, 7,223 frees, 89,693,975 bytes allocated
==408602== 
==408602== LEAK SUMMARY:
==408602==    definitely lost: 0 bytes in 0 blocks
==408602==    indirectly lost: 0 bytes in 0 blocks
==408602==      possibly lost: 0 bytes in 0 blocks
==408602==    still reachable: 24,266,244 bytes in 1,985 blocks
==408602==         suppressed: 0 bytes in 0 blocks
==408602== Rerun with --leak-check=full to see details of leaked memory
==408602== 
==408602== Use --track-origins=yes to see where uninitialised values come from
==408602== For lists of detected and suppressed errors, rerun with: -s
==408602== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
Segmentation fault (core dumped)

This crash (occurring in other customers examples too) was the original cause for our clazzes-ghostscript efforts.

valgrind clazzes-ghostscript-9.53.3-1 png16m

Code Block
[root@centos8 ~]# valgrind /usr/clazzes-ghostscript/bin/gs -sDEVICE=png16m -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==408615== Memcheck, a memory error detector
==408615== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==408615== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==408615== Command: /usr/clazzes-ghostscript/bin/gs -sDEVICE=png16m -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==408615== 
GPL Ghostscript 9.53.3 (2020-10-01)
Copyright (C) 2020 Artifex Software, Inc.  All rights reserved.
This software is supplied under the GNU AGPLv3 and comes with NO WARRANTY:
see the file COPYING for details.
Processing pages 1 through 1.
Page 1
==408615== Syscall param pwrite64(buf) points to uninitialised byte(s)
==408615==    at 0x53D6278: pwrite (in /usr/lib64/libpthread-2.28.so)
==408615==    by 0x45B984: gp_pwrite_impl (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x560CF7: clist_fwrite_chars (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x54B5FB: cmd_write_pseudo_band (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x538918: clist_icc_writetable (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x538D3B: clist_end_page (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x54509F: clist_close_writer_and_init_reader (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x5459E2: clist_get_bits_rectangle (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x85C31A: gx_default_get_bits (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x52D933: gx_downscaler_getbits (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x75A061: do_png_print_page (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x525662: gdev_prn_output_page_aux (in /usr/clazzes-ghostscript/bin/gs)
==408615==  Address 0x81181a8 is 10,792 bytes inside a block of size 20,048 alloc'd
==408615==    at 0x4C30F0B: malloc (vg_replace_malloc.c:307)
==408615==    by 0x780777: gs_heap_alloc_bytes (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x75DFE4: alloc_acquire_clump (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x75EEA1: alloc_obj.isra.4 (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x8DEA18: alloc_save_change_alloc (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x8D9915: gs_alloc_ref_array (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x8A3DCD: dict_create_unpacked_keys.isra.0 (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x8A4105: dict_unpack (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x8A50B1: dict_put (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x8BC5F1: zput (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x8A95F5: gs_interpret (in /usr/clazzes-ghostscript/bin/gs)
==408615==    by 0x89D5B8: gs_main_run_string_end (in /usr/clazzes-ghostscript/bin/gs)
==408615== 
==408615== 
==408615== HEAP SUMMARY:
==408615==     in use at exit: 0 bytes in 0 blocks
==408615==   total heap usage: 6,256 allocs, 6,256 frees, 96,871,426 bytes allocated
==408615== 
==408615== All heap blocks were freed -- no leaks are possible
==408615== 
==408615== Use --track-origins=yes to see where uninitialised values come from
==408615== For lists of detected and suppressed errors, rerun with: -s
==408615== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

This works as expected.

valgrind ghostscript-9.25-7.el8 png16m

Code Block
[root@centos8 ~]# valgrind /usr/bin/gs -sDEVICE=png16m -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==408616== Memcheck, a memory error detector
==408616== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==408616== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==408616== Command: /usr/bin/gs -sDEVICE=png16m -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==408616== 
GPL Ghostscript 9.25 (2018-09-13)
Copyright (C) 2018 Artifex Software, Inc.  All rights reserved.
This software comes with NO WARRANTY: see the file PUBLIC for details.
Processing pages 1 through 1.
Page 1
==408616== Syscall param pwrite64(buf) points to uninitialised byte(s)
==408616==    at 0x60AFBD7: pwrite (in /usr/lib64/libc-2.28.so)
==408616==    by 0x4F56396: gp_fpwrite (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x503AFAC: ??? (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x502618F: cmd_write_pseudo_band (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x50132C2: clist_icc_writetable (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x501371F: clist_end_page (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x501F747: clist_close_writer_and_init_reader (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x5020172: clist_get_bits_rectangle (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x5039059: ??? (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x51F71D2: gx_default_get_bits (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x500741E: gx_downscaler_getbits (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x516A279: ??? (in /usr/lib64/libgs.so.9.25)
==408616==  Address 0xf0093f0 is 13,968 bytes inside a block of size 20,048 alloc'd
==408616==    at 0x4C30F0B: malloc (vg_replace_malloc.c:307)
==408616==    by 0x518F6B3: ??? (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x516C3D4: ??? (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x516D2EE: ??? (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x52757F7: gs_alloc_ref_array (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x523D0BD: ??? (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x523D282: ??? (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x523E0E0: dict_resize (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x524F872: ??? (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x5243A1D: ??? (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x5243C16: gs_interpret (in /usr/lib64/libgs.so.9.25)
==408616==    by 0x5236BCB: ??? (in /usr/lib64/libgs.so.9.25)
==408616== 
==408616== 
==408616== HEAP SUMMARY:
==408616==     in use at exit: 0 bytes in 0 blocks
==408616==   total heap usage: 6,479 allocs, 6,479 frees, 98,412,130 bytes allocated
==408616== 
==408616== All heap blocks were freed -- no leaks are possible
==408616== 
==408616== Use --track-origins=yes to see where uninitialised values come from
==408616== For lists of detected and suppressed errors, rerun with: -s
==408616== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

This shows, that the crash we observed is related to the pngalpha output device.