Skip to content

Conversation

catenacyber
Copy link
Contributor

@catenacyber catenacyber commented Sep 15, 2021

Fixes #6268

As discussed in https://reviews.llvm.org/D104556 since clang supports only one version of profraw files at a time, we need for llvm-based languages such as rust and swift, to use the right version of clang

For rust, this is now clang 13, (as clang 14 introduced some changes)

  • install_rust.sh now installs clang , using checkout_build_install_llvm.sh by giving it an argument of the revision to build (we need also clang13 on the building side and not only llvm-profdata-13, so that multiple languages project produce consistent profraw file)
  • compile script now copies llvm-profdata and llvm-covin $OUT if needed (as is done for llvm-symbolizer)
  • coverage script takes specific llvm-profdata if any

The same change likely needs to be done for swift, but with clang 12 I guess.

@catenacyber
Copy link
Contributor Author

cc @jonathanmetzman @inferno-chromium
Test is to run

python3 infra/helper.py build_image --no-pull base-clang
python3 infra/helper.py build_image --no-pull base-builder
python3 infra/helper.py build_image --no-pull base-builder-rust
python3 infra/helper.py build_image --no-pull base-runner
export PROJECT=suricata
python3 infra/helper.py build_image --no-pull $PROJECT
python3 infra/helper.py build_fuzzers --sanitizer coverage $PROJECT
python3 infra/helper.py coverage --no-corpus-download $PROJECT

# Keep all steps in the same script to decrease the number of intermediate
# layes in docker file.
RUN /root/checkout_build_install_llvm.sh
RUN rm /root/checkout_build_install_llvm.sh
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

checkout_build_install_llvm.sh is now reused by install_rust

apt-get remove --purge -y $LLVM_DEP_PACKAGES
apt-get autoremove -y
if [ $# -eq 0 ] ; then
apt-get remove --purge -y $LLVM_DEP_PACKAGES
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do not remove git in base-builder-rust image

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this change.
If it's just a matter of installing git, then install it in the install_rust.sh script. There's tons of other stuff here being installed that should be removed. As is this pretty hacky.

@@ -1,5 +1,5 @@
homepage: "https://suricata-ids.org"
language: c++
language: rust
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so that we get rust llvm-cov

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how this works.
Here's my understanding.
suricata's c++ code is compiled with clang 14. suricata's rust code is compiled with clang 13.
Are the profraw files produced by suricata coverage builds compatible with clang 13 but not clang 14?

@catenacyber
Copy link
Contributor Author

CI is failing because it does not rebuild base-clang

@inferno-chromium
Copy link
Contributor

This version mgmt is getting messy, can we spend time to make things work with clang 13

@catenacyber
Copy link
Contributor Author

This version mgmt is getting messy, can we spend time to make things work with clang 13

Things (that is rust coverage) work with clang 13.
The purpose of this PR is to use clang 13 for rust, while keeping clang 14 for for C/C++

For swift, I think we will need clang 12
Each of these version produce a different version of profraw files (and has a different llvm-profdata which reads only one version)
For multi languages projects (suricata, grpc-swift, etc..), I think we need to use the right clang to have a consistent profraw file.

What would you suggest ?

@jonathanmetzman
Copy link
Contributor

This version mgmt is getting messy, can we spend time to make things work with clang 13

C++ is use clang14, we should strive to get everything working for clang14.

Things (that is rust coverage) work with clang 13.

Does rust not work with clang 14?

The purpose of this PR is to use clang 13 for rust, while keeping clang 14 for for C/C++

For swift, I think we will need clang 12
Each of these version produce a different version of profraw files (and has a different llvm-profdata which reads only one version)

Can you explain why? How long would it take to fix this issue?

For multi languages projects (suricata, grpc-swift, etc..), I think we need to use the right clang to have a consistent profraw file.

What would you suggest ?

My preference is to get everything working for one version of clang and we only use that.
That version of clang probably shouldn't be clang12. It should probably as recent clang as possible. Maybe it can be clang 13 for now.

Copy link
Contributor

@jonathanmetzman jonathanmetzman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this change is going to introduce complexity that we will regret.
I'd really like to be using the same clang version of everywhere to avoid this. How easy will that be to do?

unset CFLAGS
unset CXXFLAGS
# so that compile_libfuzzer can copy, without knowing the clang version
rm /usr/local/lib/clang/*/lib/linux/libclang_rt.fuzzer-*
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This uses an older version of libfuzzer for some of our projects right?
This can be a huge hassle for us and I don't think we want it.

(
unset CFLAGS
unset CXXFLAGS
# so that compile_libfuzzer can copy, without knowing the clang version
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please begin comment with captial and end with peirod.

apt-get remove --purge -y $LLVM_DEP_PACKAGES
apt-get autoremove -y
if [ $# -eq 0 ] ; then
apt-get remove --purge -y $LLVM_DEP_PACKAGES
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please remove this change.
If it's just a matter of installing git, then install it in the install_rust.sh script. There's tons of other stuff here being installed that should be removed. As is this pretty hacky.

cd $OUT

# copy version/language-specific coverage tools if any
cp $OUT/llvm-cov /usr/local/bin || true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not a fan of this. We copy llvm-cov and llvm-profdata into the build for rust and swift and then copy those from build into /usr/local/bin if they exist?
Here's a way I like more (assuming we end up using multiple versions of clang): Copy llvm-cov and llvm-profdata into build for all fuzzers no matter the language, then instead of copying those into /usr/local/bin, use them directly.

@@ -1,5 +1,5 @@
homepage: "https://suricata-ids.org"
language: c++
language: rust
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how this works.
Here's my understanding.
suricata's c++ code is compiled with clang 14. suricata's rust code is compiled with clang 13.
Are the profraw files produced by suricata coverage builds compatible with clang 13 but not clang 14?

@jonathanmetzman
Copy link
Contributor

This change makes rust projects use a different libfuzzer than c++. I think this is a bad idea.

@catenacyber
Copy link
Contributor Author

This got replaced by #6517, forgot to close

@catenacyber
Copy link
Contributor Author

Suricata needs to be labelled as rust project because we need rust std coverage
And there is a hack to get it for projects marked as rust
cf
https://github.com/google/oss-fuzz/blob/master/infra/base-images/base-builder/compile#L166

@catenacyber
Copy link
Contributor Author

This version mgmt is getting messy, can we spend time to make things work with clang 13

C++ is use clang14, we should strive to get everything working for clang14.

#6517 does that

Things (that is rust coverage) work with clang 13.

Does rust not work with clang 14?

Nope
I can make a long explanation...

The purpose of this PR is to use clang 13 for rust, while keeping clang 14 for for C/C++
For swift, I think we will need clang 12
Each of these version produce a different version of profraw files (and has a different llvm-profdata which reads only one version)

Can you explain why? How long would it take to fix this issue?

For multi languages projects (suricata, grpc-swift, etc..), I think we need to use the right clang to have a consistent profraw file.
What would you suggest ?

My preference is to get everything working for one version of clang and we only use that.
That version of clang probably shouldn't be clang12. It should probably as recent clang as possible. Maybe it can be clang 13 for now.

#6517 makes it work with clang 14

@jonathanmetzman
Copy link
Contributor

This version mgmt is getting messy, can we spend time to make things work with clang 13

C++ is use clang14, we should strive to get everything working for clang14.

#6517 does that

Things (that is rust coverage) work with clang 13.

Does rust not work with clang 14?

Nope
I can make a long explanation...

The purpose of this PR is to use clang 13 for rust, while keeping clang 14 for for C/C++
For swift, I think we will need clang 12
Each of these version produce a different version of profraw files (and has a different llvm-profdata which reads only one version)

Can you explain why? How long would it take to fix this issue?

For multi languages projects (suricata, grpc-swift, etc..), I think we need to use the right clang to have a consistent profraw file.
What would you suggest ?

My preference is to get everything working for one version of clang and we only use that.
That version of clang probably shouldn't be clang12. It should probably as recent clang as possible. Maybe it can be clang 13 for now.

#6517 makes it work with clang 14

Is it possible to briefly explain the issue with clang 14 and rust?

@jonathanmetzman
Copy link
Contributor

I want to understand, but I don't want to waste your time explaining this to me.

@catenacyber
Copy link
Contributor Author

Rust and Swift compiler use llvm (I do not fully understand how much)
For coverage information, they use in the end some llvm library (compiler-rt I guess) which generates the profraw file
Current Rust nightly uses llvm 13, upgrading to llvm 14 seems not trivial cf https://rustc-dev-guide.rust-lang.org/backend/updating-llvm.html
Current Swift compiler uses llvm 10 (it uses llvm 13 on MacOS, but 10 on linux)

llvm 12, 13 and 14 generate different profraw file formats, and their llvm-cov/llvm-profdata tools can only read their current file format

  • llvm 13 added binary ids, and bumped version from 5 to 7 : the script adds the field in the header (and says the length of these binary ids is zero)
  • llvm 14 changed some addresses to be relative offsets instead of absolute, and is keeping version at 7 (we go through the list and recompute the relative offsets instead of the absolute ones)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Support for LLVM 13 fuzzing

3 participants