From d9cb8cb1ade0876f2efa7bd3dc9ee82f05567169 Mon Sep 17 00:00:00 2001 From: Advenam Tacet Date: Tue, 4 Jun 2024 18:58:19 +0200 Subject: [PATCH] Add Ruzzy into OSS-Fuzz This commit brings Ruzzy, a coverage-guided fuzzer developed for pure Ruby code and Ruby C extensions, into the OSS-Fuzz project. This addition effectively integrates Ruby fuzzing support into OSS-Fuzz. Similar to Atheris, a Python fuzzer, Ruzzy uses libFuzzer for coverage instrumentation and the fuzzing engine. It offers support for AddressSanitizer and UndefinedBehaviorSanitizer, particularly when fuzzing C extensions. While the current code is functional, additional refinement and bug fixes may be required to ensure reliability. You can find further discussion about this development in issue: https://github.com/google/oss-fuzz/issues/11967 --- infra/base-images/all.sh | 1 + .../base-images/base-builder-ruby/Dockerfile | 58 +++++++++++++++++++ .../base-images/base-builder-ruby/ruzzy-build | 13 +++++ infra/base-images/base-builder/Dockerfile | 3 +- .../base-images/base-builder/install_ruby.sh | 26 +++++++++ infra/base-images/base-runner/Dockerfile | 12 +++- infra/base-images/base-runner/ruzzy | 4 ++ 7 files changed, 115 insertions(+), 2 deletions(-) create mode 100644 infra/base-images/base-builder-ruby/Dockerfile create mode 100755 infra/base-images/base-builder-ruby/ruzzy-build create mode 100755 infra/base-images/base-builder/install_ruby.sh mode change 100755 => 100644 infra/base-images/base-runner/Dockerfile create mode 100755 infra/base-images/base-runner/ruzzy diff --git a/infra/base-images/all.sh b/infra/base-images/all.sh index 8b3571083c26..815137927776 100755 --- a/infra/base-images/all.sh +++ b/infra/base-images/all.sh @@ -22,6 +22,7 @@ docker build -t gcr.io/oss-fuzz-base/base-builder-go "$@" infra/base-images/base docker build -t gcr.io/oss-fuzz-base/base-builder-jvm "$@" infra/base-images/base-builder-jvm docker build -t gcr.io/oss-fuzz-base/base-builder-python "$@" infra/base-images/base-builder-python docker build -t gcr.io/oss-fuzz-base/base-builder-rust "$@" infra/base-images/base-builder-rust +docker build -t gcr.io/oss-fuzz-base/base-builder-ruby "$@" infra/base-images/base-builder-ruby docker build -t gcr.io/oss-fuzz-base/base-builder-swift "$@" infra/base-images/base-builder-swift docker build -t gcr.io/oss-fuzz-base/base-runner "$@" infra/base-images/base-runner docker build -t gcr.io/oss-fuzz-base/base-runner-debug "$@" infra/base-images/base-runner-debug diff --git a/infra/base-images/base-builder-ruby/Dockerfile b/infra/base-images/base-builder-ruby/Dockerfile new file mode 100644 index 000000000000..dc50f2d5b456 --- /dev/null +++ b/infra/base-images/base-builder-ruby/Dockerfile @@ -0,0 +1,58 @@ +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +FROM gcr.io/oss-fuzz-base/base-builder + +# TODO: I think it's not used. +ENV ASAN_OPTIONS="allocator_may_return_null=1:detect_leaks=0:use_sigaltstack=0" + +RUN git clone https://github.com/trailofbits/ruzzy.git $SRC/ruzzy + +RUN install_ruby.sh +ENV PATH="$PATH:/usr/local/rvm/rubies/ruby-3.3.1/bin" + +RUN gem update --system 3.5.11 + +# Install ruzzy +WORKDIR $SRC/ruzzy + +# The MAKE variable allows overwriting the make command at runtime. This forces the +# Ruby C extension to respect ENV variables when compiling, like CC, CFLAGS, etc. +ENV MAKE="make --environment-overrides V=1" + +RUN CC="clang" \ +CXX="clang++" \ +LDSHARED="clang -shared" \ +LDSHAREDXX="clang++ -shared" \ +gem build + +RUN MAKE="make --environment-overrides V=1" \ +CC="clang" \ +CXX="clang++" \ +LDSHARED="clang -shared" \ +LDSHAREDXX="clang++ -shared" \ +CXXFLAGS="-fPIC" \ +CFLAGS="-fPIC" \ +RUZZY_DEBUG=1 gem install --install-dir /install/ruzzy --development --verbose ruzzy-*.gem + + +ENV LDSHARED="$CC -shared" +ENV LDSHAREDXX="$CXX -shared" + +ENV GEM_HOME="$OUT/fuzz-gem" +ENV GEM_PATH="/install/ruzzy" + +COPY ruzzy-build /usr/bin/ruzzy-build diff --git a/infra/base-images/base-builder-ruby/ruzzy-build b/infra/base-images/base-builder-ruby/ruzzy-build new file mode 100755 index 000000000000..8123937091e9 --- /dev/null +++ b/infra/base-images/base-builder-ruby/ruzzy-build @@ -0,0 +1,13 @@ +#!/usr/bin/env bash + +fuzz_target=$(basename "$1") +echo "BASENAME: $fuzz_target ---" +harness_sh=${fuzz_target::-3} + +cp $1 $OUT/$fuzz_target + +echo """#!/usr/bin/env bash + +ruzzy $fuzz_target +""" > $OUT/$harness_sh +chmod +x $OUT/$harness_sh diff --git a/infra/base-images/base-builder/Dockerfile b/infra/base-images/base-builder/Dockerfile index 8dcbdce6cc5c..20b3d0036411 100644 --- a/infra/base-images/base-builder/Dockerfile +++ b/infra/base-images/base-builder/Dockerfile @@ -161,6 +161,7 @@ COPY bazel_build_fuzz_tests \ install_javascript.sh \ install_java.sh \ install_python.sh \ + install_ruby.sh \ install_rust.sh \ install_swift.sh \ python_coverage_helper.py \ @@ -177,4 +178,4 @@ COPY llvmsymbol.diff $SRC COPY detect_repo.py /opt/cifuzz/ COPY bazel.bazelrc /root/.bazelrc -CMD ["compile"] \ No newline at end of file +CMD ["compile"] diff --git a/infra/base-images/base-builder/install_ruby.sh b/infra/base-images/base-builder/install_ruby.sh new file mode 100755 index 000000000000..66af9f6b1ef8 --- /dev/null +++ b/infra/base-images/base-builder/install_ruby.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# Copyright 2021 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +################################################################################ + +apt update +# TODO: we should install a specific version of ruby +apt install -y lsb-release software-properties-common gnupg2 binutils xz-utils libyaml-dev +gpg2 --keyserver keyserver.ubuntu.com --recv-keys 409B6B1796C275462A1703113804BB82D39DC0E3 7D2BAF1CF37B13E2069D6956105BD0E739499BDB +curl -sSL https://get.rvm.io | bash + +. /etc/profile.d/rvm.sh + +rvm install ruby-3.3.1 diff --git a/infra/base-images/base-runner/Dockerfile b/infra/base-images/base-runner/Dockerfile old mode 100755 new mode 100644 index 234ac9a01096..d702cbc477f4 --- a/infra/base-images/base-runner/Dockerfile +++ b/infra/base-images/base-runner/Dockerfile @@ -18,11 +18,12 @@ # Keeping the rust toolchain in the image wastes 1 GB. FROM gcr.io/oss-fuzz-base/base-image as temp-runner-binary-builder -RUN apt-get update && apt-get install -y cargo +RUN apt-get update && apt-get install -y cargo libyaml-dev RUN cargo install rustfilt # Using multi-stage build to copy some LLVM binaries needed in the runner image. FROM gcr.io/oss-fuzz-base/base-clang AS base-clang +FROM gcr.io/oss-fuzz-base/base-builder-ruby AS base-ruby # Real image that will be used later. FROM gcr.io/oss-fuzz-base/base-image @@ -87,6 +88,15 @@ RUN wget https://repo1.maven.org/maven2/org/jacoco/org.jacoco.cli/0.8.7/org.jaco COPY install_javascript.sh / RUN /install_javascript.sh && rm /install_javascript.sh +# Copy built ruby and ruzzy from builder +COPY --from=base-ruby /usr/local/rvm /usr/local/rvm +COPY --from=base-ruby /install/ruzzy /install/ruzzy +COPY ruzzy /usr/bin/ruzzy +ENV PATH="$PATH:/usr/local/rvm/rubies/ruby-3.3.1/bin" +# RubyGems installation directory +ENV GEM_HOME="$OUT/fuzz-gem" +ENV GEM_PATH="/install/ruzzy" + # Do this last to make developing these files easier/faster due to caching. COPY bad_build_check \ coverage \ diff --git a/infra/base-images/base-runner/ruzzy b/infra/base-images/base-runner/ruzzy new file mode 100755 index 000000000000..c80dde172a99 --- /dev/null +++ b/infra/base-images/base-runner/ruzzy @@ -0,0 +1,4 @@ +#!/usr/bin/env bash + +LD_PRELOAD=$(ruby -e 'require "ruzzy"; print Ruzzy::ASAN_PATH') \ + ruby $@