about summary refs log tree commit diff
path: root/fix.m4
diff options
context:
space:
mode:
Diffstat (limited to 'fix.m4')
-rw-r--r--fix.m481
1 files changed, 31 insertions, 50 deletions
diff --git a/fix.m4 b/fix.m4
index fc7c2ce..d896a5c 100644
--- a/fix.m4
+++ b/fix.m4
@@ -18,50 +18,51 @@
 # along with taosc.  If not, see <https://www.gnu.org/licenses/>.
 
 save_exit_code() {
+  template="${@:3}"
+  cmd="$(printf %s "$template" | sed "s#@@#$2#g")"
   set +e
-  timeout -k 1 $1 ${@:2} 1>/dev/null 2>&1
+  AFL_USE_QASAN=1 timeout -k 0 $1 afl-qemu-trace $cmd
   exit_code=$?
   set -e
 }
 
 bad() {
-  save_exit_code $@
+  save_exit_code $@ 1>/dev/null 2>&1
   test $exit_code -gt 128 ||
     test $exit_code -ge 124 -a $exit_code -le 127 # timeout
 }
 
-if test $# -lt 4
+if test $# -lt 5
 then
-  echo Usage: taosc-fix WORKDIR TIMEOUT EXECUTABLE PROOFS_OF_CONCEPT [OPTION]...
+  echo Usage: taosc-fix TIMEOUT WORKDIR PROOFS_OF_CONCEPT EXECUTABLE ARG...
   exit 1
 fi
 
+timeout=$1
 set -eux -o pipefail
-wd="$(realpath $1)"
+wd="$(realpath "$2")"
 test -d "$wd"
-timeout=$2
-bin="$wd/$(basename $3)"
-binary="$(realpath $3)"
-test -x "$binary"
-poc="$(realpath $4)"
+poc="$(realpath "$3")"
 test -d "$poc"
 test "$(ls -A "$poc")"
-options="${@:5}" # TODO: interpolation
+binary="$(realpath "$4")"
+test -x "$binary"
+bin="$wd/$(basename "$4")"
+args="${@:5}"
 
 mkdir -p "$wd"
 rm -fr "$wd/poc"
 cp -r "$poc" "$wd/poc"
 for exploit in "$wd"/poc/*
 do
-  gdb --batch --ex run --ex backtrace --args\
-    "$binary" $options "$exploit" 2>/dev/null |
-    grep '^#[0-9]\+ \+0x[0-9a-f]\+' |
-    awk '!$7 || $7 == bin {print $1, $2}' "bin=$binary" |
-    sed 's/^#//'
+  save_exit_code $timeout "$exploit" "$binary" $args 2>&1 1>/dev/null |
+    grep '^    #' |
+    grep -F "$binary" |
+    sed 's/^    #\([0-9]\+ 0x[0-9a-f]\+\).*$/\1/'
 done | sort -n | uniq > "$wd/stack-trace"
 
-grep '^0 0x[0-9a-f]\+$' "$wd/stack-trace" |
-  sed 's/^0 0x0*//' > "$wd/call-trace"
+(grep '^0 0x[0-9a-f]\+$' "$wd/stack-trace" | sed 's/^0 0x0*//' ||
+  true) > "$wd/call-trace"
 # Stack trace contains return addresses, not call addresses:
 # https://devblogs.microsoft.com/oldnewthing?p=96116
 grep -v '^0 0x[0-9a-f]\+$' "$wd/stack-trace" |
@@ -83,7 +84,7 @@ taosc-scout "$binary" < "$wd/call-trace" |
       cp -r "$poc" "$wd/poc"
       for exploit in "$wd/poc"/*
       do
-        if bad $timeout env TAOSC_DEST=0x$dest "$bin.jump" $options "$exploit"
+        if TAOSC_DEST=0x$dest bad $timeout "$exploit" "$bin.jump" $args
         then
           continue 2 # next destination
         fi
@@ -91,7 +92,7 @@ taosc-scout "$binary" < "$wd/call-trace" |
       echo $loc > "$wd/patch-location"
       echo $dest >> "$wd/destinations"
     done
-  done 1>/dev/null 2>&1
+  done
 test -s "$wd/patch-location"
 test -s "$wd/destinations"
 
@@ -104,42 +105,22 @@ e9tool -100 -M addr=$patch_loc -P 'if dest(state)@patch goto'\
   -o "$bin.patched" "$binary"
 
 # TODO: FUZZOLIC's options
-fuzzolic -kmprst 90000 -i "$poc" -o "$wd/fuzzolic" -- "$binary" $options @@ ||
+fuzzolic -kmprst 90000 -i "$poc" -o "$wd/fuzzolic" -- "$binary" $args ||
   true # FIXME: failing with the same status as the target program
 rm -fr "$wd/input"
 mkdir -p "$wd/input/benign"
 cp -r "$poc" "$wd/input/malicious"
-# TODO: use parallel
-for dat in "$wd"/fuzzolic/fuzzolic-*/test_case_*.dat
-do
-  if taosc-reach $timeout "$bin.covered" $options "$dat" 1>/dev/null 2>&1
-  then
-    if bad $timeout "$binary" $options "$dat"
-    then
-      cp $dat "$wd/input/malicious"
-    else
-      cp $dat "$wd/input/benign"
-    fi
-  fi
-done
+find "$wd/fuzzolic" -name 'test_case_*.dat' -print0 |
+  xargs -I '{}' -0 -P$(nproc) -n1 \
+  taosc-sort-inputs $timeout "$wd"/input/{malicious,benign} '{}' \
+  "$bin.covered" $args
 
 rm -fr "$wd/values"
-for input_dir in "$wd"/input/*
-do
-  output_dir="$wd/values/$(basename "$input_dir")"
-  mkdir -p "$output_dir"
-  # TODO: use parallel
-  if test "$(ls -A "$input_dir")"
-  then
-    for input in "$input_dir"/*
-    do
-      output="$output_dir/$(basename "$input")"
-      save_exit_code $timeout\
-        env TAOSC_STACK_SIZE=$stack_size TAOSC_OUTPUT=$output\
-        "$bin.collect" $options "$input"
-    done
-  fi
-done
+mkdir -p "$wd"/values/{benign,malicious}
+find "$wd/input" -print0 |
+  xargs -I '{}' -0 -P$(nproc) -n1 \
+  taosc-collect-values $timeout $stack_size "$wd/values" '{}' \
+  "$bin.collect" $args
 # TODO: split if the patch location is reached multiple times with an input
 taosc-synth $stack_size "$wd"/values/{benign,malicious} > "$wd/predicates"
 # vim: filetype=sh.m4