From ccd918bb59c49750b41a6d2652f69cfd68f7d7a4 Mon Sep 17 00:00:00 2001 From: DavidKorczynski Date: Wed, 22 Jun 2022 22:49:42 -0200 Subject: [PATCH] ghostscript: add targeted ps fuzzer (#7893) * ghostscript: add targeted ps fuzzer - Adds a new fuzzer that avoids PDF files - Adds a dictionary with Postscript commands --- projects/ghostscript/build.sh | 3 +- projects/ghostscript/dicts/ps.dict | 232 ++++++++++++++++++ projects/ghostscript/gstoraster_ps_fuzzer.cc | 45 ++++ .../ghostscript/gstoraster_ps_fuzzer.options | 3 + 4 files changed, 282 insertions(+), 1 deletion(-) create mode 100644 projects/ghostscript/dicts/ps.dict create mode 100644 projects/ghostscript/gstoraster_ps_fuzzer.cc create mode 100644 projects/ghostscript/gstoraster_ps_fuzzer.options diff --git a/projects/ghostscript/build.sh b/projects/ghostscript/build.sh index 64f2dd6d9..8a900b57b 100755 --- a/projects/ghostscript/build.sh +++ b/projects/ghostscript/build.sh @@ -50,7 +50,7 @@ CPPFLAGS="${CPPFLAGS:-} $CUPS_CFLAGS -DPACIFY_VALGRIND" ./autogen.sh \ make -j$(nproc) libgs -for fuzzer in gstoraster_pdf_fuzzer gstoraster_fuzzer gstoraster_fuzzer_all_colors; do +for fuzzer in gstoraster_pdf_fuzzer gstoraster_fuzzer gstoraster_fuzzer_all_colors gstoraster_ps_fuzzer; do $CXX $CXXFLAGS $CUPS_LDFLAGS -std=c++11 -I. -I$SRC \ $SRC/${fuzzer}.cc \ -o "$OUT/${fuzzer}" \ @@ -89,3 +89,4 @@ cp $SRC/*.options $OUT/ # Copy out dictionary cp $SRC/dicts/pdf.dict $OUT/gstoraster_pdf_fuzzer.dict +cp $SRC/dicts/ps.dict $OUT/gstoraster_ps_fuzzer.dict diff --git a/projects/ghostscript/dicts/ps.dict b/projects/ghostscript/dicts/ps.dict new file mode 100644 index 000000000..bcb7eca7b --- /dev/null +++ b/projects/ghostscript/dicts/ps.dict @@ -0,0 +1,232 @@ +"exch" +"pop" +"copy" +"dup" +"index" +"roll" +"clear" +"count" +"mark" +"cleartomark" +"countomark" +"add" +"div" +"sub" +"idiv" +"mul" +"mod" +"abs" +"neg" +"ceiling" +"floor" +"round" +"truncate" +"sqrt" +"atan" +"cos" +"sin" +"exp" +"ln" +"log" +"rand" +"srand" +"rrand" +"array" +"[" +"]" +"length" +"get" +"put" +"getinterval" +"putinterval" +"aload" +"astore" +"copy" +"forall" +"dict" +"length" +"maxlength" +"begin" +"end" +"def" +"load" +"store" +"get" +"put" +"known" +"where" +"copy" +"forall" +"errordict" +"systemdict" +"userdict" +"currentdict" +"countdictstack" +"dictstack" +"string" +"anchorsearch" +"search" +"token" +"eq" +"ne" +"ge" +"gt" +"le" +"lt" +"and" +"not" +"or" +"xor" +"true" +"false" +"bitshift" +"exec" +"if" +"ifself" +"for" +"repeat" +"loop" +"exit" +"stop" +"stopped" +"countexecstack" +"quit" +"start" +"type" +"cvlit" +"cvx" +"xcheck" +"executeonly" +"noaccess" +"readonly" +"rcheck" +"wcheck" +"cvi" +"cvn" +"cvr" +"cvrs" +"cvs" +"file" +"closefile" +"read" +"write" +"readhexstring" +"writehexstring" +"readstring" +"writestring" +"readline" +"bytesavailable" +"flush" +"flushfile" +"resetfile" +"status" +"run" +"currentfile" +"print" +"=" +"stack" +"==" +"pstack" +"prompt" +"echo" +"save" +"restore" +"vmstatus" +"bind" +"null" +"usertime" +"version" +"gsave" +"grestore" +"grestoreall" +"initgraphics" +"setlinewidth" +"currentlinewidth" +"setlinecap" +"currentlinecap" +"setlinejoine" +"currentlinejoin" +"setmiterlimit" +"currentmiterlimit" +"setdash" +"currentdash" +"setflat" +"currentflat" +"setgray" +"currentgray" +"sethsbcolor" +"currenthsbcolor" +"setrgbcolor" +"currentrgbcolor" +"setscreen" +"currentscreen" +"settransfer" +"currenttransfer" +"matrix" +"initmatrix" +"identmatrix2" +"defaultmatrix" +"currentmatrix" +"setmatrix" +"translate" +"scale" +"rotate" +"concat" +"concatmatrix" +"transform" +"dtransform" +"itransform" +"idtransform" +"invertmatrix" +"newpath" +"currentpoint" +"moveto" +"rmoveto" +"lineto" +"rlineto" +"arc" +"arcn" +"arcto" +"curveto" +"rcurveto" +"closepath" +"flattenpath" +"reversepath" +"strokepath" +"charpath" +"clippath" +"pathbbox" +"pathforall" +"initclip" +"clip" +"eoclip" +"erasepage" +"fill" +"eofill" +"stroke" +"image" +"imagemask" +"showpage" +"copypage" +"banddevice" +"framedevice" +"nulldevice" +"renderbands" +"definefont" +"findfont" +"scalefont" +"makefont" +"setfont" +"currentfont" +"show" +"ashow" +"widthshow" +"awidthshow" +"kshow" +"stringwidth" +"FontDirectory" +"standardEncoding" +"cachestatus" +"setcachedevice" +"setcharwidth" +"setcachelimit" diff --git a/projects/ghostscript/gstoraster_ps_fuzzer.cc b/projects/ghostscript/gstoraster_ps_fuzzer.cc new file mode 100644 index 000000000..221b72d8f --- /dev/null +++ b/projects/ghostscript/gstoraster_ps_fuzzer.cc @@ -0,0 +1,45 @@ +/* Copyright 2022 Google LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +#include "gstoraster_fuzzlib.h" + +/* Returns 1 if the data has a PDF header and 0 otherwise */ +static int is_pdf(const uint8_t *data, size_t size) { + /* Two bytes are needed for the check */ + if (size < 2) { + return 0; + } + + /* Check for "%P" tag. */ + if (data[0] == 0x25 || data[1] == 0x50) { + return 1; + } + return 0; +} + + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + /* Avoid PDF files */ + if (size == 0 || is_pdf(data, size)) { + return 0; + } + + /* + * Modulo the possibilities: https://github.com/ArtifexSoftware/ghostpdl/blob/8c97d5adce0040ac38a1fb4d7954499c65f582ff/cups/libs/cups/raster.h#L102 + This enables the fuzzer to explore all color schemes + */ + int color_scheme = ((int)data[0] % 63); + data++; + size--; + + gs_to_raster_fuzz(data, size, color_scheme); + return 0; +} diff --git a/projects/ghostscript/gstoraster_ps_fuzzer.options b/projects/ghostscript/gstoraster_ps_fuzzer.options new file mode 100644 index 000000000..a25fcf1c3 --- /dev/null +++ b/projects/ghostscript/gstoraster_ps_fuzzer.options @@ -0,0 +1,3 @@ +[libfuzzer] +max_len = 16834 +only_ascii = 1