Repository navigation
build: fix clang sanitizer and fuzzing builds, add build.sh fuzz - #4222
Merged
Merged
Conversation
With only CC=clang, the C++ tests of libnvme are built and linked by the gcc C++ compiler, with the gcc sanitizer runtime. Where that is not installed, meson fails while generating the targets: ERROR: Linker cc does not support sanitizer arguments ['-fsanitize=address,undefined'] And mixing the runtimes of two toolchains does not work anyway. Fail at the start of the setup instead, and name the fix: CC=clang CXX=clang++. Signed-off-by: Daniel Wagner <dwagner@suse.de>
clang links the sanitizer runtime only into executables, so a shared library of a sanitizer build has undefined references to it, which -Wl,--no-undefined rejects: FAILED: libnvme/tests/libmock-ifaddrs.so undefined reference to `__asan_report_load8' meson only warns about b_lundef with a clang sanitizer build. Fail the setup with the option to set instead. Signed-off-by: Daniel Wagner <dwagner@suse.de>
-Dfuzzing=true adds -fsanitize=fuzzer-no-link to all C code. The fuzz targets get the coverage hooks from libFuzzer, every other program from the sanitizer runtime. Without a sanitizer the test programs fail to link: undefined reference to `__sanitizer_cov_trace_const_cmp4' Fail the setup instead. Signed-off-by: Daniel Wagner <dwagner@suse.de>
…builds build.sh -c clang -s sets only CC, so the build mixes the clang and gcc toolchains, and with clang the shared libraries need b_lundef=false. Set CXX to the clang++ next to the clang in CC, unless CXX is set, and pass -Db_lundef=false. Signed-off-by: Daniel Wagner <dwagner@suse.de>
The libFuzzer setup misses CXX=clang++ and -Db_lundef=false, so it does not build. The device example runs on the argconfig corpus, and both examples write the inputs libFuzzer finds into the source tree; the comment in tests/fuzz/meson.build runs a target on the seeds in the tree directly. And allocator_may_return_null alone does not stop the device target from aborting: libFuzzer reports a device sized allocation as out of memory before ASan can fail it. Add the clang setup to the sanitizer section and use it for the libFuzzer build. Run each target on a copy of its own seeds in the build directory, cap the ASan allocation size for the device target, and say where a crashing input goes. Point the comment to the documentation. Signed-off-by: Daniel Wagner <dwagner@suse.de>
The --e2e-* and --plugin-tests options are only valid with the tests config, which one condition over all their variables checks. Let every config specific option record its config instead, and check them all in one loop. Another config can then have options of its own, and the error names the option which does not fit. Signed-off-by: Daniel Wagner <dwagner@suse.de>
A long fuzzing run needs the clang sanitizer build, a copy of the seeds per target, the right options per target and a place for the results. Add a fuzz config which builds the targets for libFuzzer and runs each of them in turn: --fuzz-seconds n seconds per target (600) --fuzz-jobs n libFuzzer jobs per target (one per CPU) --fuzz-targets list the targets (all) --fuzz-dir dir the results (.build-ci/fuzz) The jobs run as independent processes on a shared corpus (-jobs). The newer -fork mode would do the same, but the libFuzzer of clang 22 crashes in it. The results are summary.txt with the findings, and per target the logs of the jobs, the inputs which found a bug and the corpus. A finding stops its job, a UBSan finding like a crash. The exit status is not zero if a target had a finding. Signed-off-by: Daniel Wagner <dwagner@suse.de>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Sanitizer and libFuzzer builds with clang don't work as documented, and long fuzzing runs need a lot of manual setup.
Build setup. Three setups fail late, with misleading errors. meson now stops at the start of the setup and names the fix:
CC=clang, libnvme's C++ tests are built and linked with gcc'sc++and the gcc sanitizer runtime. Where that runtime isn't installed:ERROR: Linker cc does not support sanitizer arguments. Now: "The C compiler is clang, but the C++ compiler is gcc … e.g. CC=clang CXX=clang++".b_lundef: clang links the sanitizer runtime only into executables, so shared libraries such aslibmock-ifaddrs.sohave undefined__asan_*/__ubsan_*symbols, which-Wl,--no-undefinedrejects. meson only warns about this. Now: "Sanitizer and fuzzing builds with clang need -Db_lundef=false".-Dfuzzing=truewithout a sanitizer: every test program fails to link for lack of the coverage hooks (__sanitizer_cov_*), which come from the sanitizer runtime. Now: "-Dfuzzing=true needs a sanitizer".scripts/build.sh -c clang -salso setsCXX=clang++and-Db_lundef=false.Docs.
Documentation/TESTING.mdgets the clang sanitizer setup, and its libFuzzer instructions are fixed:CXXandb_lundefdeviceexample ran on theargconfigcorpusallocator_may_return_nullalone doesn't stopfuzz-devicefrom aborting, because libFuzzer reports a device-sized allocation as out of memory first;max_allocation_size_mbmakes ASan fail it insteadscripts/build.sh fuzz. A new config builds the targets for libFuzzer and runs each in turn:--fuzz-seconds(600),--fuzz-jobs(one per CPU),--fuzz-targets(all) and--fuzz-dir(.build-ci/fuzz).-jobs). The newer-forkmode crashes in the libFuzzer of clang 22.summary.txt, plus per target the job logs, the inputs which found a bug and the corpus. A UBSan finding counts like a crash, and the exit status is non-zero if a target had a finding.--e2e-*options use as well.Tested with clang 22 and 23:
build.sh fuzzreports a deliberately injected heap overflow (summary, logs, crash inputs, exit status) and finishes cleanly without one