aboutsummaryrefslogtreecommitdiff
path: root/projects/quickjs
diff options
context:
space:
mode:
Diffstat (limited to 'projects/quickjs')
-rw-r--r--projects/quickjs/Dockerfile22
-rwxr-xr-xprojects/quickjs/build.sh32
-rw-r--r--projects/quickjs/fuzz_compile.c104
-rw-r--r--projects/quickjs/fuzz_eval.c73
-rw-r--r--projects/quickjs/fuzz_regexp.c79
-rw-r--r--projects/quickjs/project.yaml13
6 files changed, 323 insertions, 0 deletions
diff --git a/projects/quickjs/Dockerfile b/projects/quickjs/Dockerfile
new file mode 100644
index 000000000..3e72ada2e
--- /dev/null
+++ b/projects/quickjs/Dockerfile
@@ -0,0 +1,22 @@
+# 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.
+#
+################################################################################
+
+FROM gcr.io/oss-fuzz-base/base-builder
+RUN apt-get update && apt-get install -y make
+RUN git clone --depth 1 https://github.com/bellard/quickjs quickjs
+WORKDIR $SRC/quickjs
+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 000000000..3ab680244
--- /dev/null
+++ b/projects/quickjs/build.sh
@@ -0,0 +1,32 @@
+#!/bin/bash -eu
+# 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.
+#
+################################################################################
+
+# build quickjs
+# Makefile should not override CFLAGS
+sed -i -e 's/CFLAGS=/CFLAGS+=/' Makefile
+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 ..
+FUZZ_TARGETS="fuzz_eval fuzz_compile fuzz_regexp"
+for f in $FUZZ_TARGETS; do
+ $CC $CFLAGS -Iquickjs -c $f.c -o $f.o
+ $CXX $CXXFLAGS $f.o -o $OUT/$f quickjs/libquickjs.a $LIB_FUZZING_ENGINE
+done
diff --git a/projects/quickjs/fuzz_compile.c b/projects/quickjs/fuzz_compile.c
new file mode 100644
index 000000000..4c1537cfc
--- /dev/null
+++ b/projects/quickjs/fuzz_compile.c
@@ -0,0 +1,104 @@
+/* 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 "cutils.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-1, "<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);
+ if (JS_IsException(obj)) {
+ js_free(ctx, bytecode);
+ return 0;
+ }
+ nbinterrupts = 0;
+ /* this is based on
+ * js_std_eval_binary(ctx, bytecode, bytecode_size, 0);
+ * modified so as not to exit on JS exception
+ */
+ JSValue val;
+ if (JS_VALUE_GET_TAG(obj) == JS_TAG_MODULE) {
+ if (JS_ResolveModule(ctx, obj) < 0) {
+ JS_FreeValue(ctx, obj);
+ js_free(ctx, bytecode);
+ return 0;
+ }
+ js_module_set_import_meta(ctx, obj, FALSE, TRUE);
+ }
+ val = JS_EvalFunction(ctx, obj);
+ if (JS_IsException(val)) {
+ js_std_dump_error(ctx);
+ } else {
+ js_std_loop(ctx);
+ }
+ JS_FreeValue(ctx, val);
+ 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 000000000..6ba443f4d
--- /dev/null
+++ b/projects/quickjs/fuzz_eval.c
@@ -0,0 +1,73 @@
+/* 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) {
+ //is it more efficient to malloc(Size+1) and memcpy ?
+ if (Data[Size-1] != 0) {
+ return 0;
+ }
+ nbinterrupts = 0;
+ //the final 0 does not count (as in strlen)
+ JSValue val = JS_Eval(ctx, (const char *)Data, Size-1, "<none>", JS_EVAL_TYPE_GLOBAL);
+ //TODO targets with JS_ParseJSON, JS_ReadObject
+ if (!JS_IsException(val)) {
+ js_std_loop(ctx);
+ JS_FreeValue(ctx, val);
+ }
+ }
+
+ return 0;
+}
diff --git a/projects/quickjs/fuzz_regexp.c b/projects/quickjs/fuzz_regexp.c
new file mode 100644
index 000000000..f40456350
--- /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 000000000..7bc6d0988
--- /dev/null
+++ b/projects/quickjs/project.yaml
@@ -0,0 +1,13 @@
+homepage: "https://bellard.org/quickjs/"
+language: c
+primary_contact: "fabrice.bellard@gmail.com"
+auto_ccs :
+- "p.antoine@catenacyber.fr"
+vendor_ccs :
+- "apascovici@google.com"
+
+sanitizers:
+- address
+
+blackbox: true # also use a blackbox fuzzer for this project.
+main_repo: 'https://github.com/horhof/quickjs'