clazzes-ghostscript 9.54.0 Security Review
Resources
List of third party libraries
https://www.ghostscript.com/doc/current/thirdparty.htm
checked against code
https://github.com/ArtifexSoftware/ghostpdl/tree/ghostpdl-9.54.0
Configuration of clazzes-ghostscript
The following configure options are used for clazzes-ghostscript
./configure --prefix=/usr/clazzes-ghostscript --enable-dynamic
--disable-cups --disable-gtk --without-x
Hence, the security review does not need to cover the CUPS library or any X-Windows or GTK-releated ghostscript issues.
Applicable Third Party Libraries
Library Name | Version | Function | License | URL |
---|---|---|---|---|
eXpat | 2.2.9 | XML parsing for XPS interpreter | MIT/eXpat License | |
FreeType | 2.10.4 | Font scaling and rendering for Ghostscript | FreeType License | |
jbig2dec | 0.19 | JBIG2 decoding for the PDF interpreter | Licensed with Ghostscript/GhostPDL | |
libjpeg | 9c | JPEG/DCT decoding/encoding | "Free" | |
LittleCMS 2 mt | 2.12 | ICC profile based color conversion and management | MIT LICENSE | |
libpng | 1.6.37 | PNG image encoding/decoding. | libpng license | |
OpenJPEG | 2.4.0 | JPEG2000 image decoding for the PDF interpreter | BSD-style | |
libtiff | 4.2.0 | TIFF image encoding/decoding | BSD-style | |
zlib | 1.2.11 | (De)Flate compression | zlib License |
Review of CVEs
CVEs of ghostscript-9.54.0
Query:
As of 2021-11-16 no major CVEs are open against the core ghostscript project apart from https://www.ghostscript.com/blog/CVE-2021-3781.html published on the ghostscript homepage itself.
The patch https://git.ghostscript.com/?p=ghostpdl.git;a=commitdiff_plain;h=a9bd3dec9fde for CVE-2021-3781 applies to ghostscript-9.54.0 sources and has been intergrated into clazzes-ghostscript.
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.
CVEs of libexpat 2.2.9
No known CVEs as of 2021-11-16. CVE-2021-40439 is specific to OpenOffice and has no impact on ghostscript.
CVEs of freetype 2.10.4
freetype-2.10.4is subject to no vulnerabilities as of 2021-11-16
The upgraded to freetype-2.10.4 has been conducted between ghostscript.9.53.3 and ghostscript-9.54.0
CVEs of jbig2dec 0.19
jbig2dec-0.19 is subject to no vulnerabilities as 2021-11-16
CVEs of libjpeg-9c
libjpeg-9c is vulnerable to
https://nvd.nist.gov/vuln/detail/CVE-2020-14152
https://nvd.nist.gov/vuln/detail/CVE-2020-14153
Hence, we upgraded to libjpeg-9d as of svn rev. 72, which has no vulvnerabilities as of 2021-11-16
CVE-2021-39514 through CVE-2021-39520 are address a different library (https://github.com/thorfdbg/libjpeg), which is also called libjpeg and is implemented in C++ rather than plain C.
CVEs of libpng-1.6.37
No known CVEs as of 2020-12-27.
CVEs of openjpeg-2.4.0
The vulnerability
only affects openjpeg cmdline tools, which are not included in ghostscript, because ghostscript actually uses the openjpeg library.
openjpeg-2.4.0 resolves several vulnerabilities compared to openjpeg-2.3.1
CVEs fo libtiff-4.2.0
All CVEs are reported against libtiff-4.0.x and a review of git commits revealed, that libtiff-4.2.0 is indeed incorporating all fixes for the CVEs listed above.
CVEs of zlib 1.2.11
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 appeared during the last 3 years.
valgrind Runs
These valgrind runs are based on an example from our customers, which crashed ghostscript-9.25 when rendering to the pngalpha output device. The example involves fonts, image masks and is otherwise not very complex.
The test runs have been executed on a centos8 machine with recent centos 8.4 updates as of 2021-11-16.
valgrind clazzes-ghostscript-9.54.0-1 pngalpha
# valgrind /usr/clazzes-ghostscript/bin/gs -sDEVICE=pngalpha -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==1701570== Memcheck, a memory error detector
==1701570== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1701570== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==1701570== Command: /usr/clazzes-ghostscript/bin/gs -sDEVICE=pngalpha -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==1701570==
GPL Ghostscript 9.54.0 (2021-03-30)
Copyright (C) 2021 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
==1701570== Syscall param pwrite64(buf) points to uninitialised byte(s)
==1701570== at 0x53DA278: pwrite (in /usr/lib64/libpthread-2.28.so)
==1701570== by 0x45D2E4: gp_pwrite_impl (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x565697: clist_fwrite_chars (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x54F89B: cmd_write_pseudo_band (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x53C748: clist_icc_writetable (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x53CB6B: clist_end_page (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x5492BF: clist_close_writer_and_init_reader (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x549C02: clist_get_bits_rectangle (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x87FD3A: gx_default_get_bits (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x530A63: gx_downscaler_getbits (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x77C5A1: do_png_print_page (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x5286AC: gdev_prn_output_page_aux (in /usr/clazzes-ghostscript/bin/gs)
==1701570== Address 0x60bbda0 is 2,768 bytes inside a block of size 20,048 alloc'd
==1701570== at 0x4C34F0B: malloc (vg_replace_malloc.c:307)
==1701570== by 0x7A37B7: gs_heap_alloc_bytes (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x780524: alloc_acquire_clump (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x7813E1: alloc_obj.isra.4 (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x77C9AE: gdevpng_malloc (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x4D55D3: png_malloc_warn (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x4D7336: png_set_iCCP (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x77C867: do_png_print_page (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x5286AC: gdev_prn_output_page_aux (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x538D95: default_subclass_output_page (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x52B915: flp_output_page (in /usr/clazzes-ghostscript/bin/gs)
==1701570== by 0x88255D: gx_forward_output_page (in /usr/clazzes-ghostscript/bin/gs)
==1701570==
==1701570==
==1701570== HEAP SUMMARY:
==1701570== in use at exit: 0 bytes in 0 blocks
==1701570== total heap usage: 7,238 allocs, 7,238 frees, 113,288,380 bytes allocated
==1701570==
==1701570== All heap blocks were freed -- no leaks are possible
==1701570==
==1701570== Use --track-origins=yes to see where uninitialised values come from
==1701570== For lists of detected and suppressed errors, rerun with: -s
==1701570== 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.27-1.el8 pngalpha
# valgrind /usr/bin/gs -sDEVICE=pngalpha -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==1701568== Memcheck, a memory error detector
==1701568== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1701568== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==1701568== Command: /usr/bin/gs -sDEVICE=pngalpha -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==1701568==
GPL Ghostscript 9.27 (2019-04-04)
Copyright (C) 2018 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
==1701568== Syscall param pwrite64(buf) points to uninitialised byte(s)
==1701568== at 0x60C3977: pwrite (in /usr/lib64/libc-2.28.so)
==1701568== by 0x4F5A706: gp_fpwrite (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x5040C4C: ??? (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x502BE1F: cmd_write_pseudo_band (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x5018DE2: clist_icc_writetable (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x501923F: clist_end_page (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x50253D7: clist_close_writer_and_init_reader (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x5025E02: clist_get_bits_rectangle (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x503ECF9: ??? (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x5200152: gx_default_get_bits (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x500CE7E: gx_downscaler_getbits (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x51712D9: ??? (in /usr/lib64/libgs.so.9.27)
==1701568== Address 0xf040a88 is 9,224 bytes inside a block of size 20,048 alloc'd
==1701568== at 0x4C34F0B: malloc (vg_replace_malloc.c:307)
==1701568== by 0x5196DC3: ??? (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x51735F4: ??? (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x517450E: ??? (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x52833E7: gs_alloc_ref_array (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x524A7CD: ??? (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x524AB54: dict_unpack (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x524BBA5: dict_put (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x5264251: ??? (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x5250597: gs_interpret (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x5243ADB: ??? (in /usr/lib64/libgs.so.9.27)
==1701568== by 0x5243FFF: gs_main_init2aux (in /usr/lib64/libgs.so.9.27)
==1701568==
==1701568==
==1701568== HEAP SUMMARY:
==1701568== in use at exit: 0 bytes in 0 blocks
==1701568== total heap usage: 10,980 allocs, 10,980 frees, 129,841,737 bytes allocated
==1701568==
==1701568== All heap blocks were freed -- no leaks are possible
==1701568==
==1701568== Use --track-origins=yes to see where uninitialised values come from
==1701568== For lists of detected and suppressed errors, rerun with: -s
==1701568== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
The original crash from gs-9.25 as of RHEL-8.1 crash has ben fixed in RHEL-8.4
valgrind clazzes-ghostscript-9.54.0-1 png16m
# valgrind /usr/clazzes-ghostscript/bin/gs -sDEVICE=png16m -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==1701565== Memcheck, a memory error detector
==1701565== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==1701565== Using Valgrind-3.16.0 and LibVEX; rerun with -h for copyright info
==1701565== Command: /usr/clazzes-ghostscript/bin/gs -sDEVICE=png16m -sOutputFile=tmp.png -dSAFER -dBATCH -dNOPAUSE -dUseCropBox -dFirstPage=1 -dLastPage=1 -r100.0 -f tmp.pdf
==1701565==
GPL Ghostscript 9.54.0 (2021-03-30)
Copyright (C) 2021 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
==1701565== Syscall param pwrite64(buf) points to uninitialised byte(s)
==1701565== at 0x53DA278: pwrite (in /usr/lib64/libpthread-2.28.so)
==1701565== by 0x45D2E4: gp_pwrite_impl (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x565697: clist_fwrite_chars (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x54F89B: cmd_write_pseudo_band (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x53C748: clist_icc_writetable (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x53CB6B: clist_end_page (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x5492BF: clist_close_writer_and_init_reader (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x549C02: clist_get_bits_rectangle (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x87FD3A: gx_default_get_bits (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x530A63: gx_downscaler_getbits (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x77C5A1: do_png_print_page (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x5286AC: gdev_prn_output_page_aux (in /usr/clazzes-ghostscript/bin/gs)
==1701565== Address 0x8122190 is 16,656 bytes inside a block of size 20,048 alloc'd
==1701565== at 0x4C34F0B: malloc (vg_replace_malloc.c:307)
==1701565== by 0x7A37B7: gs_heap_alloc_bytes (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x780524: alloc_acquire_clump (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x7813E1: alloc_obj.isra.4 (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x8FDA63: gs_alloc_ref_array (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x8C7BCD: dict_create_unpacked_keys.isra.0 (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x8C7F05: dict_unpack (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x8C8EB1: dict_put (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x8E0651: zput (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x8CD598: gs_interpret (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x8C0FB8: gs_main_run_string_end (in /usr/clazzes-ghostscript/bin/gs)
==1701565== by 0x8C102F: gs_main_run_string_with_length (in /usr/clazzes-ghostscript/bin/gs)
==1701565==
==1701565==
==1701565== HEAP SUMMARY:
==1701565== in use at exit: 0 bytes in 0 blocks
==1701565== total heap usage: 6,391 allocs, 6,391 frees, 101,989,676 bytes allocated
==1701565==
==1701565== All heap blocks were freed -- no leaks are possible
==1701565==
==1701565== Use --track-origins=yes to see where uninitialised values come from
==1701565== For lists of detected and suppressed errors, rerun with: -s
==1701565== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
This works as expected.
valgrind ghostscript-9.27-1.el8 png16m
This shows, that the crash we observed is related to the pngalpha output device.