From 4e47c225b1541339600d24fd0d8d8689292ce848 Mon Sep 17 00:00:00 2001 From: Mitchell Hashimoto Date: Sat, 28 Feb 2026 20:01:07 -0800 Subject: [PATCH] pkg/afl++ --- pkg/afl++/afl.c | 85 +++++++++++++++++++++++++++++++++++++++++ pkg/afl++/build.zig | 24 ++++++++++++ pkg/afl++/build.zig.zon | 11 ++++++ 3 files changed, 120 insertions(+) create mode 100644 pkg/afl++/afl.c create mode 100644 pkg/afl++/build.zig create mode 100644 pkg/afl++/build.zig.zon diff --git a/pkg/afl++/afl.c b/pkg/afl++/afl.c new file mode 100644 index 000000000..e085945c7 --- /dev/null +++ b/pkg/afl++/afl.c @@ -0,0 +1,85 @@ +#include +#include +#include +#include +#include +#include +#include + +/* Main entry point. */ + +/* To ensure checks are not optimized out it is recommended to disable + code optimization for the fuzzer harness main() */ +#pragma clang optimize off +#pragma GCC optimize("O0") + + +// Zig integration +void zig_fuzz_init(); +void zig_fuzz_test(unsigned char *, ssize_t); + + +// Linker-provided symbols marking the boundaries of the __sancov_guards section. +// These must be declared extern so the linker provides the actual section boundaries +// from the instrumented code, rather than creating new variables that shadow them. +extern uint32_t __start___sancov_guards; +extern uint32_t __stop___sancov_guards; +void __sanitizer_cov_trace_pc_guard_init(uint32_t*, uint32_t*); + + + +// Symbols not defined by afl-compiler-rt +__attribute__((visibility("default"))) __attribute__((tls_model("initial-exec"))) _Thread_local uintptr_t __sancov_lowest_stack; + +void __sanitizer_cov_trace_pc_indir () {} +void __sanitizer_cov_8bit_counters_init () {} +void __sanitizer_cov_pcs_init () {} + +//__AFL_FUZZ_INIT() +int __afl_sharedmem_fuzzing = 1; +extern __attribute__((visibility("default"))) unsigned int *__afl_fuzz_len; +extern __attribute__((visibility("default"))) unsigned char *__afl_fuzz_ptr; +unsigned char __afl_fuzz_alt[1048576]; +unsigned char *__afl_fuzz_alt_ptr = __afl_fuzz_alt; + +int main(int argc, char **argv) { + __sanitizer_cov_trace_pc_guard_init(&__start___sancov_guards, &__stop___sancov_guards); + + // __AFL_INIT(); + static volatile const char *_A __attribute__((used,unused)); + _A = (const char*)"##SIG_AFL_DEFER_FORKSRV##"; +#ifdef __APPLE__ + __attribute__((visibility("default"))) + void _I(void) __asm__("___afl_manual_init"); +#else + __attribute__((visibility("default"))) + void _I(void) __asm__("__afl_manual_init"); +#endif + _I(); + + + zig_fuzz_init(); + + // unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF; + unsigned char *buf = __afl_fuzz_ptr ? __afl_fuzz_ptr : __afl_fuzz_alt_ptr; + + // while (__AFL_LOOP(UINT_MAX)) { + while (({ static volatile const char *_B __attribute__((used,unused)); _B = (const char*)"##SIG_AFL_PERSISTENT##"; extern __attribute__((visibility("default"))) int __afl_connected; + #ifdef __APPLE__ + __attribute__((visibility("default"))) int _L(unsigned int) __asm__("___afl_persistent_loop"); + #else + __attribute__((visibility("default"))) int _L(unsigned int) __asm__("__afl_persistent_loop"); + #endif + _L(__afl_connected ? UINT_MAX : 1); })) { + + // int len = __AFL_FUZZ_TESTCASE_LEN; + int len = __afl_fuzz_ptr ? *__afl_fuzz_len : + (*__afl_fuzz_len = read(0, __afl_fuzz_alt_ptr, 1048576)) == 0xffffffff ? 0 : + *__afl_fuzz_len; + + + zig_fuzz_test(buf, len); + } + + return 0; +} diff --git a/pkg/afl++/build.zig b/pkg/afl++/build.zig new file mode 100644 index 000000000..bd562256d --- /dev/null +++ b/pkg/afl++/build.zig @@ -0,0 +1,24 @@ +const std = @import("std"); + +pub fn addInstrumentedExe( + b: *std.Build, + obj: *std.Build.Step.Compile, +) ?std.Build.LazyPath { + const pkg = b.dependencyFromBuildZig(@This(), .{}); + + const run_afl_cc = b.addSystemCommand(&.{ + b.findProgram(&.{"afl-cc"}, &.{}) catch + @panic("Could not find 'afl-cc', which is required to build"), + "-O3", + }); + _ = obj.getEmittedBin(); // hack around build system bug + run_afl_cc.addArg("-o"); + const fuzz_exe = run_afl_cc.addOutputFileArg(obj.name); + run_afl_cc.addFileArg(pkg.path("afl.c")); + run_afl_cc.addFileArg(obj.getEmittedLlvmBc()); + return fuzz_exe; +} + +pub fn build(b: *std.Build) !void { + _ = b; +} diff --git a/pkg/afl++/build.zig.zon b/pkg/afl++/build.zig.zon new file mode 100644 index 000000000..1fd3d5a4b --- /dev/null +++ b/pkg/afl++/build.zig.zon @@ -0,0 +1,11 @@ +.{ + .name = .afl_plus_plus, + .fingerprint = 0x465bc4bebb188f16, + .version = "0.1.0", + .dependencies = .{}, + .paths = .{ + "build.zig", + "build.zig.zon", + "afl.c", + }, +}