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.m473
1 files changed, 66 insertions, 7 deletions
diff --git a/fix.m4 b/fix.m4
index b6fd666..d3ee7fa 100644
--- a/fix.m4
+++ b/fix.m4
@@ -17,17 +17,76 @@
 # You should have received a copy of the GNU Affero General Public License
 # along with taosc.  If not, see <https://www.gnu.org/licenses/>.
 
-set -ex
+set -ex -o pipefail
+save_exit_code() {
+  set +e
+  # TODO: make timeout configurable
+  timeout -k 1 5 $@ 2>&1 1>/dev/null
+  exit_code=$?
+  set -e
+}
+
 if test $# -lt 3
 then
-  echo Usage: taosc-fix binary address workdir option...
+  echo Usage: taosc-fix workdir binary option...
   exit 1
 fi
-binary="$(realpath $1)"
-address="$2"
-wd="$(realpath $3)"
-bin="$wd/$(basename $binary)"
-opts="${@:4}"
+wd="$(realpath $1)"
+test -d "$wd"
+bin="$wd/$(basename $2)"
+binary="$(realpath $2)"
+test -x "$binary"
+opts="${@:3}" # TODO: interpolation
+
+test -d "$wd/exploits"
+test ! -z "$(ls -A "$wd/exploits")"
+mkdir -p "$wd/exit-codes"
+for exploit in "$wd/exploits"/*
+do
+  save_exit_code "$binary" "$opts" "$exploit"
+  echo $exit_code > "$wd/exit-codes/$(basename "$exploit")"
+done
+
+> "$wd/stack-trace"
+for exploit in "$wd/exploits"/*
+do
+  gdb --batch --ex run --ex backtrace --args \
+    "$binary" "$opts" "$exploit" 2>/dev/null |
+    grep '^#[0-9]\+ \+0x[0-9a-f]\+' |
+    awk '!$7 || $7 == bin {print $1, $2}' "bin=$binary" >> "$wd/stack-trace"
+done
+
+grep '^#0 0x[0-9a-f]\+$' "$wd/stack-trace" |
+  sed 's/^#0 0x0*//' > "$wd/return-blocks"
+# 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" |
+  sort |
+  sed 's/^#[0-9]\+ 0x0*//' |
+  taosc-trace-call "$binary" >> "$wd/return-blocks"
+
+> "$wd/jumps"
+pushd DATA_DIR > /dev/null
+taosc-scout "$binary" < "$wd/return-blocks" |
+  while read loc destinations
+  do
+    e9tool -100 -M addr=0x$loc -P 'if dest()@jump goto' \
+      -o "$bin.$loc" "$binary"
+    for dest in $destinations
+    do
+      for exploit in "$wd/exploits"/*
+      do
+        save_exit_code env TAOSC_DEST=0x$dest "$bin.$loc" "$opts" "$exploit"
+        if test $exit_code -ge 124 && test $exit_code -le 127 ||
+          test $exit_code -eq $(< "$wd/exit-codes/$(basename "$exploit")")
+        then
+          continue 2 # next destination
+        fi
+      done
+      echo $loc $dest >> "$wd/jumps"
+    done
+  done 2>&1 1>/dev/null
+exit
 
 afl-dyninst -x "$binary" "$bin.fuzzee"
 pushd DATA_DIR > /dev/null