fuzz: fix macOS AFL toolchain and linker setup for macOS 26.4 (#12398)

* Unset the Nix compiler and linker environment in the fuzz dev shell so
AFL++ uses the system or Homebrew Apple toolchain directly.
* Force afl-cc to link with lld because the newer Apple linker asserts
on the custom sections emitted by AFL's LLVM instrumentation.
* Pin fuzz-libghostty to the host target so the build does not inherit
stray SDK targets from the environment.
This commit is contained in:
Mitchell Hashimoto
2026-04-23 09:18:47 -07:00
committed by GitHub
3 changed files with 25 additions and 1 deletions

View File

@@ -227,8 +227,22 @@ in
unset SDKROOT
unset DEVELOPER_DIR
# AFL++ needs to use the Homebrew/system Apple toolchain directly.
# The Nix compiler wrapper variables leak a Nix linker into afl-cc,
# which breaks even trivial fuzz harness links on macOS.
unset NIX_CC
unset NIX_CFLAGS_COMPILE
unset NIX_LDFLAGS
unset LD
unset CC
unset CXX
unset CFLAGS
unset CPPFLAGS
unset LDFLAGS
# We need to remove "xcrun" from the PATH. It is injected by
# some dependency but we need to rely on system Xcode tools
export PATH=$(echo "$PATH" | awk -v RS=: -v ORS=: '$0 !~ /xcrun/ || $0 == "/usr/bin" {print}' | sed 's/:$//')
export PATH="/opt/homebrew/opt/llvm/bin:/opt/homebrew/bin:/usr/local/opt/llvm/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:$PATH"
'');
}

View File

@@ -1,4 +1,5 @@
const std = @import("std");
const builtin = @import("builtin");
/// Creates a build step that produces an AFL++-instrumented fuzzing
/// executable.
@@ -23,6 +24,12 @@ pub fn addInstrumentedExe(
@panic("Could not find 'afl-cc', which is required to build"),
"-O3",
});
if (builtin.target.os.tag.isDarwin()) {
// Apple's newer ld asserts on the custom section names emitted by
// AFL's LLVM instrumentation when linking our Zig-produced bitcode.
// lld links the same inputs without issue.
afl_cc.addArg("-fuse-ld=lld");
}
afl_cc.addArg("-o");
const fuzz_exe = afl_cc.addOutputFileArg(obj.name);
afl_cc.addFileArg(pkg.path("afl.c"));

View File

@@ -23,7 +23,10 @@ const fuzzers: []const Fuzzer = &.{
};
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
// Resolve a "generic" host target so the emitted LLVM bitcode does not
// contain native CPU features (e.g. +zcm, +zcz) that the LLVM version
// bundled with afl-cc may not recognise, which would produce warnings.
const target = b.resolveTargetQuery(.{});
const optimize = b.standardOptimizeOption(.{});
const ghostty_dep = b.lazyDependency("ghostty", .{