fuzz: fix macOS AFL toolchain and linker setup for macOS 26.4

On macOS 26.4, AFL builds were picking up Nix compiler-wrapper
variables and Apple SDK target settings from the shell environment.
That caused afl-cc to drive the wrong linker and target configuration,
which broke even simple fuzz harness builds. Unset the Nix compiler and 
linker environment in the fuzz dev shell so AFL++ uses the system or 
Homebrew Apple toolchain directly. 

Also force afl-cc to link with lld because the newer Apple linker
asserts on the custom sections emitted by AFL's LLVM
instrumentation. Finally, 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 08:40:40 -07:00
parent b34c62bf04
commit ae1dd5666d
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", .{