[fuzz] Add MemorySanitizer (MSAN) support to fuzz targets#72743
[fuzz] Add MemorySanitizer (MSAN) support to fuzz targets#72743Alami-Amine wants to merge 4 commits into
Conversation
Builds on the MSAN unit-test infrastructure (project-chip#71784) so the fuzz targets can build and run under MemorySanitizer, both locally and on OSS-Fuzz. - build_msan_sysroot.sh: add an --oss-fuzz mode that builds only the C dependencies (OpenSSL/zlib/libffi/pcre2/GLib) with the OSS-Fuzz compiler ($CC/$CXX) and $CFLAGS, skipping libc++ (OSS-Fuzz ships an instrumented libc++ at /usr/msan, applied via -stdlib=libc++). The default local mode is unchanged. - Move the is_msan / msan_sysroot build args from compiler/BUILD.gn to compiler.gni so the fuzz templates and the pw_fuzzer toolchain (which import the .gni) can read is_msan. - Local libFuzzer targets (chip_fuzz_target): apply sanitize_memory instead of sanitize_address when is_msan is set (ASan and MSAN are mutually exclusive; sanitize_memory is supplied globally via sanitize_default). - Local pw_fuzzer / FuzzTest targets: add a chip_pw_fuzz_msan toolchain arg that swaps pigweed's ASan for chip's sanitize_memory in the chip_pw_fuzztest toolchain (which does not consume the global sanitize_default). - build_examples: the `msan` modifier now composes with `libfuzzer` and `pw-fuzztest`; host.py drives the pw_fuzzer path via chip_pw_fuzz_msan and the libFuzzer / unit-test path via is_msan. Enables, for example: linux-x64-tests-clang-pw-fuzztest-msan linux-x64-tests-clang-libfuzzer-msan
There was a problem hiding this comment.
Code Review
This pull request introduces support for building local pw_fuzzer and FuzzTest targets with MemorySanitizer (MSan) instead of AddressSanitizer (ASan). It refactors the GN build configuration to share MSan variables across toolchains, adds a new chip_pw_fuzz_msan flag, and updates the MSan sysroot build script to support OSS-Fuzz environments by utilizing the container's compiler and skipping the libc++ build. The review feedback points out that when configuring the sysroot dependencies (zlib, libffi, and pcre2), the script completely overrides LDFLAGS with "-fsanitize=memory". The reviewer recommends appending to the existing LDFLAGS instead, ensuring that critical environment-specific flags pre-configured by OSS-Fuzz are not discarded.
Append ${LDFLAGS:-} instead of overriding LDFLAGS when configuring the
autoconf deps (zlib/libffi/pcre2), so any flags set by the build environment
are kept. No-op for the local build (LDFLAGS unset there).
The GLib meson native file builds its c_args/cpp_args arrays by iterating
over $MSAN. The loop quoted "$MSAN", so every flag collapsed into a single
array element and meson passed the whole string to clang as one argument
("clang: error: unsupported argument ... to option '-fsanitize='"), breaking
the GLib dependency build in both the local and --oss-fuzz paths.
Split $MSAN explicitly with `read -ra` so each flag is its own array element.
This is also shellcheck-clean, so the intentional word-splitting won't get
re-quoted by a linter.
|
PR #72743: Size comparison from 413ff63 to 7c23a6f Full report (33 builds for bl602, bl702, bl702l, cc13x4_26x4, cc32xx, efr32, esp32, nrfconnect, psoc6, qpg, realtek, stm32, telink)
|
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #72743 +/- ##
==========================================
+ Coverage 56.76% 56.79% +0.03%
==========================================
Files 1634 1642 +8
Lines 112660 112757 +97
Branches 13144 13139 -5
==========================================
+ Hits 63946 64040 +94
- Misses 48714 48717 +3 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Summary
Adds MemorySanitizer (MSAN) support to the fuzz targets, building on the MSAN unit-test infrastructure from #71784. This makes both the legacy libFuzzer harnesses (
chip_fuzz_target) and the pw_fuzzer / Google FuzzTest harnesses (chip_pw_fuzz_target) buildable and runnable under MSAN — locally for reproduction, and on OSS-Fuzz (which previously had thememorysanitizer disabled for this project due to uninstrumented dependencies).MSAN requires every linked object to be instrumented, including the C++ runtime and third-party dependencies. The unit-test work (#71784) already provides an instrumented dependency sysroot (
build_msan_sysroot.sh) and thesanitize_memoryconfig; this change wires that into the fuzz build paths.Changes
build_msan_sysroot.sh: add an--oss-fuzzmode that builds only the C dependencies (OpenSSL, zlib, libffi, pcre2, GLib) using the OSS-Fuzz compiler ($CC/$CXX) and$CFLAGS, and skips building libc++ — OSS-Fuzz ships its own instrumented libc++ (/usr/msan, applied via-stdlib=libc++), and reusing a libc++ built with a different clang would mismatch. The default local mode is unchanged.is_msan/msan_sysrootdeclare_args frombuild/config/compiler/BUILD.gntobuild/config/compiler/compiler.gni, so the fuzz templates and thepw_fuzzertoolchain (which import the.gni, but cannot import aBUILD.gn) can readis_msan.chip_fuzz_target): applysanitize_memoryinstead ofsanitize_addresswhenis_msanis set. ASan and MSAN are mutually exclusive, andsanitize_memoryis already applied globally viasanitize_default.chip_pw_fuzz_msantoolchain arg that swaps pigweed's ASan for chip'ssanitize_memoryin thechip_pw_fuzztesttoolchain (which does not consume chip's globalsanitize_default).build_examples: themsanmodifier now composes withlibfuzzerandpw-fuzztest;host.pydrives the pw_fuzzer path viachip_pw_fuzz_msanand the libFuzzer / unit-test path viais_msan.New buildable targets, e.g.:
(The OSS-Fuzz
connectedhomeipproject configuration — Dockerfile/build.sh/project.yaml— is updated in a companion change in the OSS-Fuzz repository; it invokesbuild_msan_sysroot.sh --oss-fuzzand re-enables thememorysanitizer.)Testing
linux-x64-tests-clang-libfuzzer-msan—fuzz-tlv-readerran 30000 inputs to a cleanDone, no MSAN report (links the instrumented libc++ and OpenSSL).linux-x64-tests-clang-pw-fuzztest-msan—fuzz-tlv-reader-pwfuzzed cleanly under MSAN.--oss-fuzzpath end-to-end in the OSS-Fuzz base image (SANITIZER=memory): the dependency sysroot builds with the OSS-Fuzz clang, all fuzz targets compile (legacy libFuzzer + per-case FuzzTest wrappers), andcheck_buildpasses.gn gensucceeds for both new target flavors with--fail-on-unused-args; the default (non-MSAN) build paths are unchanged.