pax_global_header00006660000000000000000000000064144327660300014517gustar00rootroot0000000000000052 comment=d816c519417615642c43a9f640093842a3e2cdda ocaml-afl-persistent-1.4/000077500000000000000000000000001443276603000154145ustar00rootroot00000000000000ocaml-afl-persistent-1.4/.gitignore000066400000000000000000000000351443276603000174020ustar00rootroot00000000000000_build afl-persistent.config ocaml-afl-persistent-1.4/CHANGES.md000066400000000000000000000007431443276603000170120ustar00rootroot00000000000000v1.4 (22nd May 2023) -------------------- Switch build system to dune v1.3 (13th Nov 2018) --------------------- Uses /bin/sh instead of /bin/bash to fix install problems v1.2 (22nd May 2017) --------------------- Allow installation on non-AFL switches. (Doesn't do much, but lets you use Crowbar in quickcheck mode) v1.1 (12th January 2017) --------------------- Improved stability of instrumentation output v1.0 (6th December 2016) --------------------- Initial release ocaml-afl-persistent-1.4/LICENSE.md000066400000000000000000000020421443276603000170160ustar00rootroot00000000000000Copyright (c) 2016 Stephen Dolan Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ocaml-afl-persistent-1.4/README.md000066400000000000000000000010271443276603000166730ustar00rootroot00000000000000# afl-persistent - persistent-mode afl-fuzz for ocaml by using `AflPersistent.run`, you can fuzz things really fast: ```ocaml let f () = let s = read_line () in match Array.to_list (Array.init (String.length s) (String.get s)) with ['s'; 'e'; 'c'; 'r'; 'e'; 't'; ' '; 'c'; 'o'; 'd'; 'e'] -> failwith "uh oh" | _ -> () let _ = AflPersistent.run f ``` compile with a version of ocaml that supports afl. that means trunk for now, but the next release (4.05) will work too, and pass the `-afl-instrument` option to ocamlopt. ocaml-afl-persistent-1.4/afl-persistent.opam000066400000000000000000000021521443276603000212320ustar00rootroot00000000000000opam-version: "2.0" maintainer: "stephen.dolan@cl.cam.ac.uk" authors: ["Stephen Dolan"] homepage: "https://github.com/stedolan/ocaml-afl-persistent" bug-reports: "https://github.com/stedolan/ocaml-afl-persistent/issues" dev-repo: "git+https://github.com/stedolan/ocaml-afl-persistent.git" license: "MIT" build: [ [ "dune" "build" "-p" name "-j" jobs ] [ "./config.sh" ] ] depends: [ "ocaml" {>= "4.05"} "dune" {>= "2.9"} "base-unix" ] post-messages: [ "afl-persistent is installed, but since the current OCaml compiler does not enable AFL instrumentation by default, most packages will not be instrumented and fuzzing with afl-fuzz may not be effective. To globally enable AFL instrumentation, create an OCaml switch like: opam switch create %{ocaml:version}%+afl ocaml-variants.%{ocaml:version}%+options ocaml-option-afl" {success & afl-available & !afl-always} ] synopsis: "Use afl-fuzz in persistent mode" description: """ afl-fuzz normally works by repeatedly fork()ing the program being tested. using this package, you can run afl-fuzz in 'persistent mode', which avoids repeated forking and is much faster.""" ocaml-afl-persistent-1.4/aflPersistent.ml000066400000000000000000000011071443276603000205700ustar00rootroot00000000000000external reset_instrumentation : bool -> unit = "caml_reset_afl_instrumentation" external sys_exit : int -> 'a = "caml_sys_exit" let run f = let _ = try ignore (Sys.getenv "##SIG_AFL_PERSISTENT##") with Not_found -> () in let persist = match Sys.getenv "__AFL_PERSISTENT" with | _ -> true | exception Not_found -> false in let pid = Unix.getpid () in if persist then begin reset_instrumentation true; for _ = 1 to 1000 do f (); Unix.kill pid Sys.sigstop; reset_instrumentation false done; f (); sys_exit 0; end else f () ocaml-afl-persistent-1.4/aflPersistent.mli000066400000000000000000000000411443276603000207350ustar00rootroot00000000000000val run : (unit -> unit) -> unit ocaml-afl-persistent-1.4/config.sh000077500000000000000000000006161443276603000172230ustar00rootroot00000000000000#!/bin/sh set -e tmpdir="$(mktemp -d 2>/dev/null || mktemp -d -t 'mytmpdir')" output="$(pwd)/afl-persistent.config" cd "$tmpdir" echo 'print_string "Hello"' > test.ml if ocamlopt -dcmm -c test.ml 2>&1 | grep -q caml_afl; then afl_always=true else afl_always=false fi rm test.* cd / rmdir "$tmpdir" cat > "$output" < exit 0); failwith "AflPersistent.run failed" ocaml-afl-persistent-1.4/test/000077500000000000000000000000001443276603000163735ustar00rootroot00000000000000ocaml-afl-persistent-1.4/test/harness.ml000066400000000000000000000013271443276603000203730ustar00rootroot00000000000000external reset_instrumentation : bool -> unit = "caml_reset_afl_instrumentation" external sys_exit : int -> 'a = "caml_sys_exit" let name n = fst (Test.tests.(int_of_string n - 1)) let run n = snd (Test.tests.(int_of_string n - 1)) () let orig_random = Random.get_state () let () = (* Random.set_state orig_random; *) reset_instrumentation true; begin match Sys.argv with | [| _; "len" |] -> print_int (Array.length Test.tests); print_newline (); flush stdout | [| _; "name"; n |] -> print_string (name n); flush stdout | [| _; "1"; n |] -> run n | [| _; "2"; n |] -> run n; (* Random.set_state orig_random; *)reset_instrumentation false; run n | _ -> failwith "error" end; sys_exit 0 ocaml-afl-persistent-1.4/test/test.ml000066400000000000000000000041351443276603000177070ustar00rootroot00000000000000let opaque = Sys.opaque_identity let lists n = let l = opaque [n; n; n] in match List.rev l with | [a; b; c] when a = n && b = n && c = n -> () | _ -> assert false let fresh_exception x = opaque @@ let module M = struct exception E of int let throw () = raise (E x) end in try M.throw () with M.E n -> assert (n = x) let obj_with_closure x = opaque (object method foo = x end) let r = ref 42 let state () = incr r; if !r > 43 then print_string "woo" else () let classes (x : int) = opaque @@ let module M = struct class a = object method foo = x end class c = object inherit a end end in let o = new M.c in assert (o#foo = x) class c_global = object method foo = 42 end let obj_ordering () = opaque @@ (* Object IDs change, but should be in the same relative order *) let a = new c_global in let b = new c_global in if a < b then print_string "a" else print_string "b" let random () = opaque @@ (* as long as there's no self_init, this should be deterministic *) if Random.int 100 < 50 then print_string "a" else print_string "b"; if Random.int 100 < 50 then print_string "a" else print_string "b"; if Random.int 100 < 50 then print_string "a" else print_string "b"; if Random.int 100 < 50 then print_string "a" else print_string "b"; if Random.int 100 < 50 then print_string "a" else print_string "b"; if Random.int 100 < 50 then print_string "a" else print_string "b"; if Random.int 100 < 50 then print_string "a" else print_string "b"; if Random.int 100 < 50 then print_string "a" else print_string "b"; if Random.int 100 < 50 then print_string "a" else print_string "b" let tests = [| ("lists", fun () -> lists 42); ("manylists", fun () -> for i = 1 to 10 do lists 42 done); ("exceptions", fun () -> fresh_exception 100); ("objects", fun () -> ignore (obj_with_closure 42)); (* ("state", state); *) (* this one should fail *) ("classes", fun () -> classes 42); ("obj_ordering", obj_ordering); (* ("random", random); *) |] ocaml-afl-persistent-1.4/test/test.sh000077500000000000000000000014671443276603000177210ustar00rootroot00000000000000#!/bin/bash set -e ocamlopt -c -afl-instrument test.ml ocamlopt -afl-inst-ratio 0 test.cmx harness.ml -o test NTESTS=`./test len` failures='' echo "running $NTESTS tests..." for t in `seq 1 $NTESTS`; do printf "%14s: " `./test name $t` # when run twice, the instrumentation output should double afl-showmap -q -o output-1 -- ./test 1 $t afl-showmap -q -o output-2 -- ./test 2 $t # see afl-showmap.c for what the numbers mean cat output-1 | sed ' s/:6/:7/; s/:5/:6/; s/:4/:5/; s/:3/:4/; s/:2/:4/; s/:1/:2/; ' > output-2-predicted if cmp -s output-2-predicted output-2; then echo "passed." else echo "failed:" paste output-2 output-1 failures=1 fi done if [ -z "$failures" ]; then echo "all tests passed"; fi rm -f {test,harness}.{cmi,cmx,o} test output-{1,2,2-predicted}