Skip to content

Commit

Permalink
fuzz: link fuzz programs with make all on Linux
Browse files Browse the repository at this point in the history
Since 5e47215 (fuzz: add basic fuzz testing target., 2018-10-12), we
have compiled object files for the fuzz tests as part of the default
'make all' target. This helps prevent bit-rot in lesser-used parts of
the codebase, by making sure that incompatible changes are caught at
build time.

However, since we never linked the fuzzer executables, this did not
protect us from link-time errors. As of 8b9a42b (fuzz: fix fuzz test
build rules, 2024-01-19), it's now possible to link the fuzzer
executables without using a fuzzing engine and a variety of
compiler-specific (and compiler-version-specific) flags, at least on
Linux. So let's add a platform-specific option in config.mak.uname to
link the executables as part of the default `make all` target.

Since linking the fuzzer executables without a fuzzing engine does not
require a C++ compiler, we can change the FUZZ_PROGRAMS build rule to
use $(CC) by default. This avoids compiler mis-match issues when
overriding $(CC) but not $(CXX). When we *do* want to actually link with
a fuzzing engine, we can set $(FUZZ_CXX). The build instructions in the
CI fuzz-smoke-test job and in the Makefile comment have been updated
accordingly.

While we're at it, we can consolidate some of the fuzzer build
instructions into one location in the Makefile.

Suggested-by: Junio C Hamano <[email protected]>
Helped-by: Jeff King <[email protected]>
Signed-off-by: Josh Steadmon <[email protected]>
Signed-off-by: Junio C Hamano <[email protected]>
  • Loading branch information
steadmon authored and gitster committed Apr 11, 2024
1 parent 65d60d3 commit e41f480
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 22 deletions.
51 changes: 30 additions & 21 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ include shared.mak
# to the "<name>" of the corresponding `compat/fsmonitor/fsm-settings-<name>.c`
# that implements the `fsm_os_settings__*()` routines.
#
# Define LINK_FUZZ_PROGRAMS if you want `make all` to also build the fuzz test
# programs in oss-fuzz/.
#
# === Optional library: libintl ===
#
# Define NO_GETTEXT if you don't want Git output to be translated.
Expand Down Expand Up @@ -752,23 +755,6 @@ SCRIPTS = $(SCRIPT_SH_GEN) \

ETAGS_TARGET = TAGS

# If you add a new fuzzer, please also make sure to run it in
# ci/run-build-and-minimal-fuzzers.sh so that we make sure it still links and
# runs in the future.
FUZZ_OBJS += oss-fuzz/dummy-cmd-main.o
FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o
FUZZ_OBJS += oss-fuzz/fuzz-config.o
FUZZ_OBJS += oss-fuzz/fuzz-date.o
FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o
FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o
.PHONY: fuzz-objs
fuzz-objs: $(FUZZ_OBJS)

# Always build fuzz objects even if not testing, to prevent bit-rot.
all:: $(FUZZ_OBJS)

FUZZ_PROGRAMS += $(patsubst %.o,%,$(filter-out %dummy-cmd-main.o,$(FUZZ_OBJS)))

# Empty...
EXTRA_PROGRAMS =

Expand Down Expand Up @@ -2372,6 +2358,29 @@ ifndef NO_TCLTK
endif
$(QUIET_SUBDIR0)templates $(QUIET_SUBDIR1) SHELL_PATH='$(SHELL_PATH_SQ)' PERL_PATH='$(PERL_PATH_SQ)'

# If you add a new fuzzer, please also make sure to run it in
# ci/run-build-and-minimal-fuzzers.sh so that we make sure it still links and
# runs in the future.
FUZZ_OBJS += oss-fuzz/dummy-cmd-main.o
FUZZ_OBJS += oss-fuzz/fuzz-commit-graph.o
FUZZ_OBJS += oss-fuzz/fuzz-config.o
FUZZ_OBJS += oss-fuzz/fuzz-date.o
FUZZ_OBJS += oss-fuzz/fuzz-pack-headers.o
FUZZ_OBJS += oss-fuzz/fuzz-pack-idx.o
.PHONY: fuzz-objs
fuzz-objs: $(FUZZ_OBJS)

# Always build fuzz objects even if not testing, to prevent bit-rot.
all:: $(FUZZ_OBJS)

FUZZ_PROGRAMS += $(patsubst %.o,%,$(filter-out %dummy-cmd-main.o,$(FUZZ_OBJS)))

# Build fuzz programs when possible, even without the necessary fuzzing support,
# to prevent bit-rot.
ifdef LINK_FUZZ_PROGRAMS
all:: $(FUZZ_PROGRAMS)
endif

please_set_SHELL_PATH_to_a_more_modern_shell:
@$$(:)

Expand Down Expand Up @@ -3857,22 +3866,22 @@ cover_db_html: cover_db
#
# An example command to build against libFuzzer from LLVM 11.0.0:
#
# make CC=clang CXX=clang++ \
# make CC=clang FUZZ_CXX=clang++ \
# CFLAGS="-fsanitize=fuzzer-no-link,address" \
# LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \
# fuzz-all
#
FUZZ_CXX ?= $(CC)
FUZZ_CXXFLAGS ?= $(ALL_CFLAGS)

.PHONY: fuzz-all
fuzz-all: $(FUZZ_PROGRAMS)

$(FUZZ_PROGRAMS): %: %.o oss-fuzz/dummy-cmd-main.o $(GITLIBS) GIT-LDFLAGS
$(QUIET_LINK)$(CXX) $(FUZZ_CXXFLAGS) -o $@ $(ALL_LDFLAGS) \
$(QUIET_LINK)$(FUZZ_CXX) $(FUZZ_CXXFLAGS) -o $@ $(ALL_LDFLAGS) \
-Wl,--allow-multiple-definition \
$(filter %.o,$^) $(filter %.a,$^) $(LIBS) $(LIB_FUZZING_ENGINE)

fuzz-all: $(FUZZ_PROGRAMS)

$(UNIT_TEST_PROGS): $(UNIT_TEST_BIN)/%$X: $(UNIT_TEST_DIR)/%.o $(UNIT_TEST_DIR)/test-lib.o $(GITLIBS) GIT-LDFLAGS
$(call mkdir_p_parent_template)
$(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) \
Expand Down
2 changes: 1 addition & 1 deletion ci/run-build-and-minimal-fuzzers.sh
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@

group "Build fuzzers" make \
CC=clang \
CXX=clang++ \
FUZZ_CXX=clang++ \
CFLAGS="-fsanitize=fuzzer-no-link,address" \
LIB_FUZZING_ENGINE="-fsanitize=fuzzer,address" \
fuzz-all
Expand Down
1 change: 1 addition & 0 deletions config.mak.uname
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ ifeq ($(uname_S),Linux)
ifneq ($(findstring .el7.,$(uname_R)),)
BASIC_CFLAGS += -std=c99
endif
LINK_FUZZ_PROGRAMS = YesPlease
endif
ifeq ($(uname_S),GNU/kFreeBSD)
HAVE_ALLOCA_H = YesPlease
Expand Down

0 comments on commit e41f480

Please sign in to comment.