-
Notifications
You must be signed in to change notification settings - Fork 2.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Rust coverage report (for Suricata) #4697
Conversation
yes i think we would need add rustfilt on clusterfuzz bots ? do you have example on workflow, like is rustfilt done first ? |
No example yet, but I guess I could try on ecc-diff-fuzzer which has both C++ and Rust |
I hope it can be run in any order and both rustbelt and c++filt leave untouched the symbols they do not recognize I will wait for rustc to be merged before trying this |
7363616
to
c232b4a
Compare
@inferno-chromium this seems to work now that rustc and Suricata got updated I will leave some comments in the code What remains to do is to add rust in the authorized languages for coverage in python helper scripts (including CI) |
# we need this until https://github.com/rust-lang/cargo/issues/5450 or similar is merged | ||
# because cargo uses relative paths for the current crate | ||
# and absolute paths for its dependencies | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hack is to use this cargo which come first in PATH
So we can change RUSTFLAGS
for this execution
then execute /rust/bin/cargo
@@ -27,6 +27,8 @@ RUN apt-get update && apt-get install -y wget sudo && \ | |||
rm cmake-$CMAKE_VERSION-Linux-x86_64.sh && \ | |||
SUDO_FORCE_REMOVE=yes apt-get remove --purge -y wget sudo | |||
|
|||
RUN apt-get install -y zlib1g-dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is needed because rustc uses zlib compression for the coverage section, and llvm-cov needs to decode it
################################################################################ | ||
|
||
# simply pipe | ||
rustfilt | c++filt -n |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to work for ecc-diff-fuzzer which has rust and C++
Tested with
ecc-diff-fuzzer gives a warning but report looks ok
|
Ci failure seems unrelated |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks so much, some comments, once addressed, excited about rust cov support.
@@ -149,7 +149,8 @@ RUN mkdir honggfuzz && \ | |||
rm -rf $SRC/oss-fuzz.tar.gz | |||
|
|||
COPY compile compile_afl compile_dataflow compile_libfuzzer compile_honggfuzz \ | |||
compile_go_fuzzer precompile_honggfuzz srcmap write_labels.py /usr/local/bin/ | |||
compile_go_fuzzer cargo precompile_honggfuzz srcmap \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: indent right to compile in previous line.
nit: move cargo to start, alpha order
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
infra/base-images/base-builder/cargo
Outdated
# because cargo uses relative paths for the current crate | ||
# and absolute paths for its dependencies | ||
|
||
export PATH=/rust/bin:/usr/bin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe just PATH="/rust/bin:$PATH" , removing current value might be problematic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok testing it
@@ -52,6 +53,13 @@ ENV UBSAN_OPTIONS="print_stacktrace=1:print_summary=1:silence_unsigned_overflow= | |||
ENV FUZZER_ARGS="-rss_limit_mb=2560 -timeout=25" | |||
ENV AFL_FUZZER_ARGS="-m none" | |||
|
|||
# Install Rust and cargo-fuzz for libFuzzer instrumentation. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be all there, so now just need rustfilt install add.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it in base-builder but not base-runner...
Running
docker run --rm --privileged -i -e FUZZING_ENGINE=libfuzzer -e SANITIZER=address -e RUN_FUZZER_MODE=interactive -v /path/to/whatever:/out -t gcr.io/oss-fuzz-base/base-runner /bin/bash
and then I get
cargo
bash: cargo: command not found
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok fine to add then. i don't know the reason for this cargo not found.
@@ -37,6 +37,7 @@ RUN apt-get update && apt-get install -y \ | |||
python3 \ | |||
python3-pip \ | |||
wget \ | |||
curl \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be there already now.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same: I see it in base-builder but not base-runner...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should it be moved to base-image or some other generic image ?
infra/base-images/base-builder/cargo
Outdated
# limitations under the License. | ||
# | ||
################################################################################ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add a file description in comment.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
# limitations under the License. | ||
# | ||
################################################################################ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Add file description here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
@@ -27,6 +27,8 @@ RUN apt-get update && apt-get install -y wget sudo && \ | |||
rm cmake-$CMAKE_VERSION-Linux-x86_64.sh && \ | |||
SUDO_FORCE_REMOVE=yes apt-get remove --purge -y wget sudo | |||
|
|||
RUN apt-get install -y zlib1g-dev |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why install this in base-clang, we avoid installing any packages as they can become dependencies of a compiled binary and might not exist in CF fuzzing time (since it has just archive). Since this is needed only for rust projects, probably add the install in coverage file itself when project language is rust.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need llvm to be compiled with zlib support, more precisely llvm-profdata
needs zlib support to read what is the output for the rust code part (because the rust compiler uses the zlib compression feature)
cf https://llvm.org/docs/CoverageMappingFormat.html (look for zlib in there)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if this is needed in llvm tools, add it here - https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-clang/checkout_build_install_llvm.sh#L20 [with a comment] so that it can be removed automatically after llvm tools are compiled.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed
infra/base-images/base-builder/cargo
Outdated
export PATH=/rust/bin:/usr/bin | ||
if [ "$SANITIZER" = "coverage" ] && [ $1 = "build" ] | ||
then | ||
abspath=`cargo metadata --no-deps --format-version 1 | jq -r '.workspace_root'` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe better var name than abspath, what is this abspath for?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is the absolute path of the source code of the crate getting built.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe crate_src_abspath?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok good
@@ -115,7 +119,7 @@ BUILD_CMD="bash -eux $SRC/build.sh" | |||
|
|||
# We need to preserve source code files for generating a code coverage report. | |||
# We need exact files that were compiled, so copy both $SRC and $WORK dirs. | |||
COPY_SOURCES_CMD="cp -rL --parents $SRC $WORK /usr/include /usr/local/include $GOPATH $OUT" | |||
COPY_SOURCES_CMD="cp -rL --parents $SRC $WORK /usr/include /usr/local/include $GOPATH /rust $OUT" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
will this fail if /rust does not exist?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Likely yes
Should I use an environment variable like $GOPATH
and set it appropriately ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yes right.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok
Thanks for taking the time to review it :-) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Replied to initial comments.
7dc9b02
to
1a82106
Compare
Testing with the changes, I get the following error for Suricata
This does not seem to be caused by LLVM version5 for covmap introduced at the end of December by https://reviews.llvm.org/D84467 as I get the same error with I shall test with different versions of the rust compiler... |
Thanks! |
In facts, it looks like it is working for ecc-diff-fuzzer, and for some dummy test program, but not for Suricata...
I will work for a proper fix |
Does it work for other rust projects, just curious ? |
Status so far :
So I can find the functions who do not get named with
Suricata is at commit 62e665c8482c90b30f6edfa7b0f0eabf8a4fcc79 The functions who do not have names are from Rust, and hinted as inline...
I did not manage to reproduce this with a simpler rust program using num_integer |
@catenacyber - Thanks for pinging me about this. I haven't seen this error before. Let's try to find out if this is a configuration issue, unsupported compiler option (in combination with Once we narrow it down, we should file an issue in rust-lang/rust, whether it's a bug to fix in code, or better warnings and/or documentation about unsupported configurations. I know you said you could not reproduce the error with a simpler program, but that is going to be the best way to narrow down the issue. Perhaps you could make a copy of your code and start eliminating things in chunks that don't change the outcome (still producing the error after eliminating libraries/crates). But there is one clue. You said this happens with functions marked as IIRC one fairly recent change (merged Jan 7) was to issue a warning when compiling with a MIR optimization level that enables inlining, and to automatically disable MIR inlining, when the I wonder if the error you are seeing is related to the underlying limitation. The best guidance for this is to ensure none of your code is compiled with a MIR optimization level that enables inlining. (Essentially, you shouldn't use So if you aren't enabling inlining explicitly, anywhere in your build, then I believe the If this doesn't provide the answers, we'll need a smaller example and specific code and build flags to reproduce it. Thanks! |
Thanks @richkadel for your answer pointing me in the right direction. My simple reproducer is
with Cargo.toml having
Compiling with But if I compile with So there is no bug with More info :
@richkadel what can we do next ? should I file a Rust issue with this ? |
@catenacyber - Just confirming a few things:
If none of those options are enabled in your program, I wonder if they could be enabled in any dependent libraries you are linking with. If you find the cause and can change a If you can't find and/or fix it without changing rustc (or cargo) then yes please file an issue. Thank you for investigating this! |
(FYI, in case it's not clear, in |
As suricata's build runs
Changing the option seems enough for my small reproducer, but it is not enough for my real use case Another thing I just noticed is that the problematic functions, in addition to be hinted inline, are also called by inline functions themselves, being in traits implementations... |
I have some new errors like
So, looks like more debugging work is needed |
This looks very much like you still have some optimization flags in your rustc commands. |
@richkadel I investigated this problem and I found the difference : This seems to be because |
b66ba56
to
3b858fc
Compare
@inferno-chromium I just tested this PR : it works with mp4parse-rust and rust-regex One point is getting more hacky :
By the way, the projects do not seem to use the sanitizer argument of |
That is an interesting find for sure. Thanks. If that's reproducible with a simple program like the one in your bug report about |
I guess that is something like...
Not sure that |
@catenacyber - OK that seems easy. What is the |
for optimized ie --release (opoosite to -D for debug) |
Can you remove that flag? All optimization flags are suspicious when instrumenting for coverage. |
@richkadel I will report this bug if I manage to reproduce it correctly in rustc @inferno-chromium for me, this PR is ready for review (and merge if it looks ok) |
@catenacyber - I'm sorry. I think we're miscommunicating. Can you try running |
@oliverchang - can you please do the final review round. |
Sorry there have been some recent changes, can you please rebase and leave comment, will merge first thing monday. |
I rebased and fixed the conflicts, so you can merge tomorrow |
I dont think we can have this custom llvm patch. Reason being some day it will randomly not apply and base-builder image will just break. Can you file a upstream llvm bug with this patch and we can see if someone can help with getting it landed. Can you remove it from here, then we can land this. |
I removed the llvm patch. |
# do not optimize with --release, leading to Malformed instrumentation profile data | ||
cargo build --bins | ||
# copies the build output in the expected target directory | ||
cd target |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think that this is causing a build failure for wasmtime because we include the fuzz
directory as part of the main workspace meaning that the target
directory doesn't show up under the fuzz
directory.
Perhaps this could use something like:
cargo metadata --format-version 1 --no-deps | jq '.target_directory'
to extract the target directory for the fuzz project?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another alternative, if the goal is simply to not optimize, is to set CARGO_PROFILE_RELEASE_OPT_LEVEL=0
and that should disable all optimizations without having to override Cargo?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @alexcrichton for debugging this cf #5366
Another alternative, if the goal is simply to not optimize
The goal is more than to not optimize
Indeed, we cannot optimize until rust-lang/rust#82144 is fixed
But, if I remember correctly, -Zinstrument-coverage
seems incompatible with other cargo options set by cargo fuzz
(like the llvm sancov pass, which would make sense)
So we turn cargo fuzz build
into cargo build
to be transparent to the existing build scripts
Another solution could be to have cargo fuzz
accept a so-called coverage sanitizer which would set -Zinstrument-coverage
What do you think ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think ideally yeah it'd be best to codify this in cargo fuzz
itself which could automatically apply the defaults of not optimizing and anything else necessary (like removing those extra passes)
All rust projects are ok for coverage build except wasmtime and libra |
Libra's build was broken before coverage merge |
cc @inferno-chromium and @Dor1s
Fixes #4637
This will work when rust-lang/rust#79365 gets merged into rust nightly compiler and gets shipped into oss-fuzz docker images (or if you recompile rustc)
This is a draft PR.
The right one will not use a custom patch for Suricata, but wait until OISF/suricata#5595 is merged
Last, there is a question about the demangler
As some project may have both C++ and Rust, I think that the demangler should be a custom one basically doing
rustfilt | c++filt -n
Do you have thoughts on that ?