diff --git a/projects/spidermonkey-ufi/Dockerfile b/projects/spidermonkey-ufi/Dockerfile new file mode 100644 index 000000000..5217c06ae --- /dev/null +++ b/projects/spidermonkey-ufi/Dockerfile @@ -0,0 +1,26 @@ +# Copyright 2019 Google Inc. +# +# 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 +MAINTAINER cdiehl@mozilla.com +RUN apt-get update && apt-get install -y --no-install-recommends \ + autoconf2.13 \ + python \ + libc++1 \ + libc++abi1 +RUN git clone --depth=1 https://github.com/mozilla/gecko-dev mozilla-central +WORKDIR mozilla-central/js/src/ +COPY build.sh target.c $SRC/ diff --git a/projects/spidermonkey-ufi/build.sh b/projects/spidermonkey-ufi/build.sh new file mode 100755 index 000000000..7356ff6cc --- /dev/null +++ b/projects/spidermonkey-ufi/build.sh @@ -0,0 +1,64 @@ +#!/bin/bash -eu +# Copyright 2019 Google Inc. +# +# 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. +# +################################################################################ + +# Case-sensitive names of internal Firefox fuzzing targets. Edit to add more. +FUZZ_TARGETS=( + StructuredCloneReader + Wasm +) + +# Install dependencies. Note that bootstrap installs cargo, which must be added +# to PATH via source. In a successive run (for a different sanitizer), the +# cargo installation carries over, but bootstrap fails if cargo is not in PATH. +export SHELL=/bin/bash +[[ -f "$HOME/.cargo/env" ]] && source $HOME/.cargo/env +../../mach bootstrap --no-interactive --application-choice browser +source $HOME/.cargo/env + +autoconf2.13 + +# Update internal libFuzzer. +(cd ../../tools/fuzzing/libfuzzer && ./clone_libfuzzer.sh HEAD) + +mkdir -p build_OPT.OBJ +cd build_OPT.OBJ + +../configure \ + --enable-optimize \ + --disable-shared-js \ + --disable-jemalloc \ + --enable-tests \ + --enable-fuzzing \ + --enable-$SANITIZER-sanitizer + +make "-j$(nproc)" + +cp dist/bin/fuzz-tests $OUT + +# Build a wrapper binary for each target to set environment variables. +for FUZZ_TARGET in ${FUZZ_TARGETS[@]} +do + $CC $CFLAGS -O0 \ + -DFUZZ_TARGET=$FUZZ_TARGET \ + $SRC/target.c -o $OUT/$FUZZ_TARGET +done + +# Copy libraries. +mkdir -p $OUT/lib +cp -L /usr/lib/x86_64-linux-gnu/libc++.so.1 $OUT/lib +cp -L /usr/lib/x86_64-linux-gnu/libc++abi.so.1 $OUT/lib + diff --git a/projects/spidermonkey-ufi/project.yaml b/projects/spidermonkey-ufi/project.yaml new file mode 100644 index 000000000..8eb1f0e09 --- /dev/null +++ b/projects/spidermonkey-ufi/project.yaml @@ -0,0 +1,7 @@ +homepage: 'https://searchfox.org/mozilla-central/source/js/src/fuzz-tests/README' +primary_contact: 'choller@mozilla.com' +fuzzing_engines: + - libfuzzer +sanitizers: + - address + diff --git a/projects/spidermonkey-ufi/target.c b/projects/spidermonkey-ufi/target.c new file mode 100644 index 000000000..9f3140a27 --- /dev/null +++ b/projects/spidermonkey-ufi/target.c @@ -0,0 +1,71 @@ +#include +#include +#include +#include +#include + +#define STRINGLIT(S) #S +#define STRINGIFY(S) STRINGLIT(S) + +// Required for oss-fuzz to consider the binary a target. +static const char* magic __attribute__((used)) = "LLVMFuzzerTestOneInput"; + +int main(int argc, char* argv[]) { + char path[PATH_MAX] = {0}; + + // Handle (currently not used) relative binary path. + if (**argv != '/') { + if (!getcwd(path, PATH_MAX - 1)) { + perror("getcwd"); + exit(1); + } + strcat(path, "/"); + } + + if (strlen(path) + strlen(*argv) + 40 >= PATH_MAX) { + fprintf(stderr, "Path length would exceed PATH_MAX\n"); + exit(1); + } + + strcat(path, *argv); + char* solidus = strrchr(path, '/'); + *solidus = 0; // terminate path before last / + + char ld_path[PATH_MAX] = {0}; + strcpy(ld_path, path); + strcat(ld_path, "/lib"); + + // Expects LD_LIBRARY_PATH to also be set by oss-fuzz. + setenv("LD_LIBRARY_PATH", ld_path, 0); + setenv("HOME", "/tmp", 0); + setenv("LIBFUZZER", "1", 1); + setenv("FUZZER", STRINGIFY(FUZZ_TARGET), 1); + + char* options = getenv("ASAN_OPTIONS"); + if (options) { + char* ptr; + char* new_options = strdup(options); + + // https://bugzilla.mozilla.org/1477846 + ptr = strstr(new_options, "detect_stack_use_after_return=1"); + if (ptr) ptr[30] = '0'; + + // https://bugzilla.mozilla.org/1477844 + ptr = strstr(new_options, "detect_leaks=1"); + if (ptr) ptr[13] = '0'; + + setenv("ASAN_OPTIONS", new_options, 1); + free(new_options); + } + + + char js_path[PATH_MAX] = {0}; + strcpy(js_path, path); + strcat(js_path, "/fuzz-tests"); + + int ret = execv(js_path, argv); + if (ret) + perror("execv"); + return ret; +} +