diff options
author | Catena cyber <35799796+catenacyber@users.noreply.github.com> | 2020-03-06 19:40:49 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-03-06 10:40:49 -0800 |
commit | f76ab1ea94f159c74e21b92350cf10c7c0605fcc (patch) | |
tree | 959af48be603da62bf31a64f35d59e983e2c2dc6 /projects/quickjs | |
parent | df15f281f943584626d1f4248276580c1961afcb (diff) |
[quickjs] Add project (#3473)
Diffstat (limited to 'projects/quickjs')
-rw-r--r-- | projects/quickjs/Dockerfile | 23 | ||||
-rwxr-xr-x | projects/quickjs/build.sh | 38 | ||||
-rw-r--r-- | projects/quickjs/fuzz_compile.c | 83 | ||||
-rw-r--r-- | projects/quickjs/fuzz_eval.c | 68 | ||||
-rw-r--r-- | projects/quickjs/fuzz_regexp.c | 79 | ||||
-rw-r--r-- | projects/quickjs/project.yaml | 7 |
6 files changed, 298 insertions, 0 deletions
diff --git a/projects/quickjs/Dockerfile b/projects/quickjs/Dockerfile new file mode 100644 index 00000000..1e4a7d86 --- /dev/null +++ b/projects/quickjs/Dockerfile @@ -0,0 +1,23 @@ +# Copyright 2018 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 fabrice@bellard.org +RUN apt-get update && apt-get install -y make +RUN git clone --depth 1 https://github.com/horhof/quickjs quickjs +WORKDIR $SRC/ +COPY build.sh $SRC/ +COPY fuzz*.c $SRC/ diff --git a/projects/quickjs/build.sh b/projects/quickjs/build.sh new file mode 100755 index 00000000..8f0e10cc --- /dev/null +++ b/projects/quickjs/build.sh @@ -0,0 +1,38 @@ +#!/bin/bash -eu +# Copyright 2018 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. +# +################################################################################ + +# build quickjs +cd quickjs +# Makefile should not override CFLAGS +sed -i -e 's/CFLAGS=/CFLAGS+=/' Makefile +if [ "$ARCHITECTURE" = 'i386' ]; then + export CFLAGS="$CFLAGS -m32" +fi +CONFIG_CLANG=y make libquickjs.a +zip -r $OUT/fuzz_eval_seed_corpus.zip tests/*.js +zip -r $OUT/fuzz_eval_seed_corpus.zip examples/*.js +zip -r $OUT/fuzz_compile_seed_corpus.zip tests/*.js +zip -r $OUT/fuzz_compile_seed_corpus.zip examples/*.js + +cd .. +$CC $CFLAGS -Iquickjs -c fuzz_eval.c -o fuzz_eval.o +$CXX $CXXFLAGS fuzz_eval.o -o $OUT/fuzz_eval quickjs/libquickjs.a $LIB_FUZZING_ENGINE +$CC $CFLAGS -Iquickjs -c fuzz_compile.c -o fuzz_compile.o +$CXX $CXXFLAGS fuzz_compile.o -o $OUT/fuzz_compile quickjs/libquickjs.a $LIB_FUZZING_ENGINE +$CC $CFLAGS -Iquickjs -c fuzz_regexp.c -o fuzz_regexp.o +$CXX $CXXFLAGS fuzz_regexp.o -o $OUT/fuzz_regexp quickjs/libquickjs.a $LIB_FUZZING_ENGINE + diff --git a/projects/quickjs/fuzz_compile.c b/projects/quickjs/fuzz_compile.c new file mode 100644 index 00000000..28f8e419 --- /dev/null +++ b/projects/quickjs/fuzz_compile.c @@ -0,0 +1,83 @@ +/* Copyright 2020 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. + */ + +#include "quickjs-libc.h" + +#include <stdint.h> +#include <stdio.h> + +static int initialized = 0; +JSRuntime *rt; +JSContext *ctx; +static int nbinterrupts = 0; + +// handle timeouts from infinite loops +static int interrupt_handler(JSRuntime *rt, void *opaque) +{ + nbinterrupts++; + return (nbinterrupts > 100); +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (initialized == 0) { + rt = JS_NewRuntime(); + // 64 Mo + JS_SetMemoryLimit(rt, 0x4000000); + //TODO JS_SetMaxStackSize ? + ctx = JS_NewContextRaw(rt); + JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL); + JS_AddIntrinsicBaseObjects(ctx); + JS_AddIntrinsicDate(ctx); + JS_AddIntrinsicEval(ctx); + JS_AddIntrinsicStringNormalize(ctx); + JS_AddIntrinsicRegExp(ctx); + JS_AddIntrinsicJSON(ctx); + JS_AddIntrinsicProxy(ctx); + JS_AddIntrinsicMapSet(ctx); + JS_AddIntrinsicTypedArrays(ctx); + JS_AddIntrinsicPromise(ctx); + JS_AddIntrinsicBigInt(ctx); + JS_SetInterruptHandler(JS_GetRuntime(ctx), interrupt_handler, NULL); + js_std_add_helpers(ctx, 0, NULL); + initialized = 1; + } + + if (Size > 0) { + if (Data[Size-1] != 0) { + return 0; + } + JSValue obj; + obj = JS_Eval(ctx, (const char *)Data, Size, "<none>", JS_EVAL_FLAG_COMPILE_ONLY | JS_EVAL_TYPE_GLOBAL | JS_EVAL_TYPE_MODULE); + //TODO target with JS_ParseJSON + if (JS_IsException(obj)) { + return 0; + } + size_t bytecode_size; + uint8_t* bytecode = JS_WriteObject(ctx, &bytecode_size, obj, JS_WRITE_OBJ_BYTECODE); + JS_FreeValue(ctx, obj); + if ( !bytecode ) { + return 0; + } + obj = JS_ReadObject(ctx, bytecode, bytecode_size, JS_READ_OBJ_BYTECODE); + JS_FreeValue(ctx, obj); + nbinterrupts = 0; + //this needs patching so as not to exit on JS exception + js_std_eval_binary(ctx, bytecode, bytecode_size, 0); + js_std_loop(ctx); + js_free(ctx, bytecode); + } + + return 0; +} diff --git a/projects/quickjs/fuzz_eval.c b/projects/quickjs/fuzz_eval.c new file mode 100644 index 00000000..d0aa92fc --- /dev/null +++ b/projects/quickjs/fuzz_eval.c @@ -0,0 +1,68 @@ +/* Copyright 2020 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. + */ + +#include "quickjs-libc.h" + +#include <stdint.h> +#include <stdio.h> + +static int initialized = 0; +JSRuntime *rt; +JSContext *ctx; +static int nbinterrupts = 0; + +// handle timeouts from infinite loops +static int interrupt_handler(JSRuntime *rt, void *opaque) +{ + nbinterrupts++; + return (nbinterrupts > 100); +} + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (initialized == 0) { + rt = JS_NewRuntime(); + // 64 Mo + JS_SetMemoryLimit(rt, 0x4000000); + //TODO JS_SetMaxStackSize ? + ctx = JS_NewContextRaw(rt); + JS_SetModuleLoaderFunc(rt, NULL, js_module_loader, NULL); + JS_AddIntrinsicBaseObjects(ctx); + JS_AddIntrinsicDate(ctx); + JS_AddIntrinsicEval(ctx); + JS_AddIntrinsicStringNormalize(ctx); + JS_AddIntrinsicRegExp(ctx); + JS_AddIntrinsicJSON(ctx); + JS_AddIntrinsicProxy(ctx); + JS_AddIntrinsicMapSet(ctx); + JS_AddIntrinsicTypedArrays(ctx); + JS_AddIntrinsicPromise(ctx); + JS_AddIntrinsicBigInt(ctx); + JS_SetInterruptHandler(JS_GetRuntime(ctx), interrupt_handler, NULL); + js_std_add_helpers(ctx, 0, NULL); + initialized = 1; + } + + if (Size > 0) { + if (Data[Size-1] != 0) { + return 0; + } + nbinterrupts = 0; + JS_Eval(ctx, (const char *)Data, Size, "<none>", JS_EVAL_TYPE_GLOBAL); + //TODO targets with JS_ParseJSON, JS_ReadObject + js_std_loop(ctx); + } + + return 0; +} diff --git a/projects/quickjs/fuzz_regexp.c b/projects/quickjs/fuzz_regexp.c new file mode 100644 index 00000000..f4045635 --- /dev/null +++ b/projects/quickjs/fuzz_regexp.c @@ -0,0 +1,79 @@ +/* Copyright 2020 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. + */ + +#include "libregexp.h" +#include "quickjs-libc.h" + +#include <stdint.h> +#include <stdio.h> + +#define CAPTURE_COUNT_MAX 255 + +FILE *outfile=NULL; +JSRuntime *rt; +JSContext *ctx; + +int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + if (outfile == NULL) { + outfile = fopen("/dev/null", "w"); + rt = JS_NewRuntime(); + // 64 Mo + JS_SetMemoryLimit(rt, 0x4000000); + //TODO JS_SetMaxStackSize ? + ctx = JS_NewContextRaw(rt); + } + int len, ret, i; + uint8_t *bc; + char error_msg[64]; + const uint8_t *input; + uint8_t *capture[CAPTURE_COUNT_MAX * 2]; + int capture_count; + size_t Size1=Size; + + //Splits buffer into 2 sub buffers delimited by null character + for (i=0; i<Size; i++) { + if (Data[i] == 0) { + Size1=i; + break; + } + } + if (Size1 == Size) { + //missing delimiter + return 0; + } + bc = lre_compile(&len, error_msg, sizeof(error_msg), (const char *) Data, + Size1, 0, ctx); + if (!bc) { + return 0; + } + input = Data+Size1+1; + ret = lre_exec(capture, bc, input, 0, Size-(Size1+1), 0, ctx); + if (ret == 1) { + capture_count = lre_get_capture_count(bc); + for(i = 0; i < 2 * capture_count; i++) { + uint8_t *ptr; + ptr = capture[i]; + fprintf(outfile, "%d: ", i); + if (!ptr) + fprintf(outfile, "<nil>"); + else + fprintf(outfile, "%u", (int)(ptr - (uint8_t *)input)); + fprintf(outfile, "\n"); + } + } + free(bc); + + return 0; +} diff --git a/projects/quickjs/project.yaml b/projects/quickjs/project.yaml new file mode 100644 index 00000000..cb525450 --- /dev/null +++ b/projects/quickjs/project.yaml @@ -0,0 +1,7 @@ +homepage: "https://bellard.org/quickjs/" +primary_contact: "fabrice@bellard.org" +auto_ccs : +- "p.antoine@catenacyber.fr" + +sanitizers: +- address |