diff options
author | 2022-06-24 16:38:05 -0700 | |
---|---|---|
committer | 2022-06-24 19:38:05 -0400 | |
commit | 45023e3a63a19719e42bbf265db1851ee2ab1eb0 (patch) | |
tree | 201c3b867bb90256caf628bbe27aea9e52fb7a0a | |
parent | d1e407f0f335d167620c48a4bd93ff65aaec7bac (diff) |
XS: implement xst_jsonparse target, and wrap fuzzing binaries (#7910)
XS: implement json_parse target, and wrap fuzzing binaries with a wrapper binary to ignore leaks
-rw-r--r-- | projects/xs/Dockerfile | 1 | ||||
-rwxr-xr-x | projects/xs/build.sh | 29 | ||||
-rw-r--r-- | projects/xs/target.c | 79 |
3 files changed, 108 insertions, 1 deletions
diff --git a/projects/xs/Dockerfile b/projects/xs/Dockerfile index 8264c9ac..4b266df2 100644 --- a/projects/xs/Dockerfile +++ b/projects/xs/Dockerfile @@ -17,5 +17,6 @@ FROM gcr.io/oss-fuzz-base/base-builder RUN git clone --depth=1 https://github.com/Moddable-OpenSource/moddable moddable WORKDIR moddable +COPY target.c $SRC/ COPY build.sh $SRC/ COPY xst.options $SRC/ diff --git a/projects/xs/build.sh b/projects/xs/build.sh index 65d022c4..518ac90f 100755 --- a/projects/xs/build.sh +++ b/projects/xs/build.sh @@ -17,9 +17,36 @@ export MODDABLE=$PWD export ASAN_OPTIONS="detect_leaks=0" +FUZZ_TARGETS=( + xst + xst_jsonparse +) + +# 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 + +# Stash actual binaries in subdirectory so they aren't picked up by target discovery +mkdir -p $OUT/real + +# build main target cd "$MODDABLE/xs/makefiles/lin" FUZZING=1 OSSFUZZ=1 make debug cd "$MODDABLE" -cp ./build/bin/lin/debug/xst $OUT/ +cp ./build/bin/lin/debug/xst $OUT/real/xst cp $SRC/xst.options $OUT/ + +# build jsonparse target +cd "$MODDABLE/xs/makefiles/lin" +make -f xst.mk clean +FUZZING=1 OSSFUZZ=1 OSSFUZZ_JSONPARSE=1 make debug + +cd "$MODDABLE" +cp ./build/bin/lin/debug/xst $OUT/real/xst_jsonparse + +cp $SRC/xst.options $OUT/xst_jsonparse.options diff --git a/projects/xs/target.c b/projects/xs/target.c new file mode 100644 index 00000000..55ac2cde --- /dev/null +++ b/projects/xs/target.c @@ -0,0 +1,79 @@ +/* +# +# 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. +# +################################################################################ +*/ + +#include <limits.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#define STRINGLIT(S) #S +#define STRINGIFY(S) STRINGLIT(S) + +// Heavily inspired by firefox's wrapper located at +// https://github.com/google/oss-fuzz/blob/master/projects/firefox/target.c + +// 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 / + + setenv("FUZZER", STRINGIFY(FUZZ_TARGET), 1); + + // Temporary (or permanent?) work-arounds for fuzzing interface bugs. + char* options = getenv("ASAN_OPTIONS"); + if (options) { + char* ptr; + char* new_options = strdup(options); + // ptr = strstr(new_options, "detect_stack_use_after_return=1"); + // if (ptr) ptr[30] = '0'; + ptr = strstr(new_options, "detect_leaks=1"); + if (ptr) ptr[13] = '0'; + setenv("ASAN_OPTIONS", new_options, 1); + free(new_options); + } + + char real_fuzz_bin[PATH_MAX] = {0}; + strcpy(real_fuzz_bin, path); + strcat(real_fuzz_bin, "/real/"); + strcat(real_fuzz_bin, STRINGIFY(FUZZ_TARGET)); + fprintf(stderr, "Invoking %s with detect_leaks=0\n", real_fuzz_bin); + + int ret = execv(real_fuzz_bin, argv); + if (ret) + perror("execv"); + return ret; +} |