blob: 3a28dd26be0a734b23896ee541cb5966da7607ba (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
# Standalone fuzzing harness for slosh's parser surfaces.
#
# Deliberately separate from the main build: the main build uses zig cc for
# static musl linking, but libFuzzer wants clang's own runtime, and the six
# parsers under test include nothing but their own headers -- so this Makefile
# needs no vendor step, no libghostty-vt, nothing but clang and ../../src.
#
# make build every fuzz_* binary (libFuzzer + ASan + UBSan)
# make replay build every replay_* binary (same target, file-replay main)
# make corpus check the seed corpora replay cleanly (a fast CI gate)
# make run-kdl fuzz one target (TIME=60 seconds, default 30)
# make run-all fuzz every target for TIME seconds each, sequentially
#
# Findings land in findings/<target>/ and grown corpora stay in corpus/<target>/.
CLANG ?= clang
ROOT := ../..
TARGETS := kdl jsonval expr proto osc5577 input
TIME ?= 30
# src/input.c includes <ghostty/vt.h> for key/mod constants only (it calls
# nothing), so the vendored header is enough and no library is linked. It
# exists once the main build's `make vendor` has run.
VT_INC := $(ROOT)/vendor/libghostty-vt/zig-out/include
CFLAGS := -std=c23 -O1 -g -Wall -Wextra -Wno-unused-parameter \
-I$(ROOT)/include -I$(VT_INC) \
-fsanitize=address,undefined -fno-sanitize-recover=all
FUZZ_BINS := $(TARGETS:%=fuzz_%)
REPLAY_BINS := $(TARGETS:%=replay_%)
all: $(FUZZ_BINS) ## build libFuzzer binaries
replay: $(REPLAY_BINS) ## build file-replay binaries (no libFuzzer runtime)
# Each target is fuzz_<name>.c + src/<name>.c, nothing else. If that ever
# stops being true for a new target, list its extra objects explicitly.
fuzz_%: fuzz_%.c $(ROOT)/src/%.c
$(CLANG) $(CFLAGS) -fsanitize=fuzzer $^ -o $@
replay_%: fuzz_%.c $(ROOT)/src/%.c standalone_main.c
$(CLANG) $(CFLAGS) $^ -o $@
run-%: fuzz_%
@mkdir -p findings/$* corpus/$*
./fuzz_$* -max_total_time=$(TIME) -max_len=65536 \
-artifact_prefix=findings/$*/ corpus/$*
run-all: $(FUZZ_BINS) ## fuzz every target for TIME seconds each
@for t in $(TARGETS); do $(MAKE) --no-print-directory run-$$t || exit 1; done
corpus: $(REPLAY_BINS) ## replay all seed corpora (CI-friendly, no fuzzing)
@for t in $(TARGETS); do \
files=$$(find corpus/$$t -type f 2>/dev/null); \
if [ -n "$$files" ]; then ./replay_$$t $$files || exit 1; fi; \
done
@echo "corpus replay: all clean"
clean:
rm -f $(FUZZ_BINS) $(REPLAY_BINS)
.PHONY: all replay run-all corpus clean
|