aboutsummaryrefslogtreecommitdiff
path: root/test/mkfuzzdata1.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'test/mkfuzzdata1.tcl')
-rw-r--r--test/mkfuzzdata1.tcl112
1 files changed, 112 insertions, 0 deletions
diff --git a/test/mkfuzzdata1.tcl b/test/mkfuzzdata1.tcl
new file mode 100644
index 000000000..766757b91
--- /dev/null
+++ b/test/mkfuzzdata1.tcl
@@ -0,0 +1,112 @@
+#!/usr/bin/tclsh
+#
+# Run this script in order to rebuild the fuzzdata1.txt file containing
+# fuzzer data for the fuzzershell utility that is create by afl-fuzz.
+#
+# This script gathers all of the test cases identified by afl-fuzz and
+# runs afl-cmin and afl-tmin over them all to try to generate a mimimum
+# set of tests that cover all observed behavior.
+#
+# Options:
+#
+# --afl-bin DIR1 DIR1 contains the AFL binaries
+# --fuzzershell PATH Full pathname of instrumented fuzzershell
+# --afl-data DIR3 DIR3 is the "-o" directory from afl-fuzz
+# -o FILE Write results into FILE
+#
+set AFLBIN {}
+set FUZZERSHELL {}
+set AFLDATA {}
+set OUTFILE {}
+
+proc usage {} {
+ puts stderr "Usage: $::argv0 --afl-bin DIR --fuzzershell PATH\
+ --afl-data DIR -o FILE"
+ exit 1
+}
+proc cmdlineerr {msg} {
+ puts stderr $msg
+ usage
+}
+
+for {set i 0} {$i<[llength $argv]} {incr i} {
+ set x [lindex $argv $i]
+ if {[string index $x 0]!="-"} {cmdlineerr "illegal argument: $x"}
+ set x [string trimleft $x -]
+ incr i
+ if {$i>=[llength $argv]} {cmdlineerr "no argument on --$x"}
+ set a [lindex $argv $i]
+ switch -- $x {
+ afl-bin {set AFLBIN $a}
+ afl-data {set AFLDATA $a}
+ fuzzershell {set FUZZERSHELL $a}
+ o {set OUTFILE $a}
+ default {cmdlineerr "unknown option: --$x"}
+ }
+}
+proc checkarg {varname option} {
+ set val [set ::$varname]
+ if {$val==""} {cmdlineerr "required option missing: --$option"}
+}
+checkarg AFLBIN afl-bin
+checkarg AFLDATA afl-data
+checkarg FUZZERSHELL fuzzershell
+checkarg OUTFILE o
+proc checkexec {x} {
+ if {![file exec $x]} {cmdlineerr "cannot find $x"}
+}
+checkexec $AFLBIN/afl-cmin
+checkexec $AFLBIN/afl-tmin
+checkexec $FUZZERSHELL
+proc checkdir {x} {
+ if {![file isdir $x]} {cmdlineerr "no such directory: $x"}
+}
+checkdir $AFLDATA/queue
+
+proc progress {msg} {
+ puts "******** $msg"
+ flush stdout
+}
+progress "mkdir tmp1 tmp2"
+file mkdir tmp1 tmp2
+progress "copying test cases from $AFLDATA into tmp1..."
+set n 0
+foreach file [glob -nocomplain $AFLDATA/queue/id:*] {
+ incr n
+ file copy $file tmp1/$n
+}
+foreach file [glob -nocomplain $AFLDATA/crash*/id:*] {
+ incr n
+ file copy $file tmp1/$n
+}
+progress "total $n files copied."
+progress "running: $AFLBIN/afl-cmin -i tmp1 -o tmp2 $FUZZERSHELL"
+exec $AFLBIN/afl-cmin -i tmp1 -o tmp2 $FUZZERSHELL >&@ stdout
+progress "afl-cmin complete."
+#
+# Experiments show that running afl-tmin is too slow for this application.
+# And it doesn't really make the test cases that much smaller. So let's
+# just skip it.
+#
+# foreach file [glob tmp2/*] {
+# progress "$AFLBIN/afl-tmin -i $file -o tmp3/[file tail $file] $FUZZERSHELL"
+# exec $AFLBIN/afl-tmin -i $file -o tmp3/[file tail $file] \
+# $FUZZERSHELL >&@ stdout
+# }
+progress "generating final output into $OUTFILE"
+set out [open $OUTFILE wb]
+puts $out "# Test data for use with fuzzershell. Automatically
+# generated using $argv0. This file contains binary data
+#"
+set n 0
+foreach file [glob tmp2/*] {
+ incr n
+ puts -nonewline $out "/****<$n>****/"
+ set in [open $file rb]
+ puts -nonewline $out [read $in]
+ close $in
+}
+close $out
+progress "done. $n test cases written to $OUTFILE"
+progress "clean-up..."
+file delete -force tmp1 tmp2