From fb4600192c9b688c2d6b6105fb17eee6359501da Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 17 Oct 2024 20:28:46 +0200 Subject: [PATCH 1/2] Restrict atom count in deserializer to 1 million Otherwise it's too easy to tie up too many resources (cpu, memory) by crafting inputs with a very large atom count (up to 4 billion.) This may need some finetuning. If the limit proves too restrictive for very large snapshots, we can make it relative to the size of the input. --- quickjs.c | 7 ++++++- tests/test_bjson.js | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/quickjs.c b/quickjs.c index 90e97292e..4f4fc957a 100644 --- a/quickjs.c +++ b/quickjs.c @@ -35571,8 +35571,13 @@ static int JS_ReadObjectAtoms(BCReaderState *s) } if (bc_get_leb128(s, &s->idx_to_atom_count)) return -1; + if (s->idx_to_atom_count > 1000*1000) { + JS_ThrowInternalError(s->ctx, "unreasonable atom count: %u", + s->idx_to_atom_count); + return -1; + } - bc_read_trace(s, "%d atom indexes {\n", s->idx_to_atom_count); + bc_read_trace(s, "%u atom indexes {\n", s->idx_to_atom_count); if (s->idx_to_atom_count != 0) { s->idx_to_atom = js_mallocz(s->ctx, s->idx_to_atom_count * diff --git a/tests/test_bjson.js b/tests/test_bjson.js index c1f72bbd7..940967602 100644 --- a/tests/test_bjson.js +++ b/tests/test_bjson.js @@ -231,6 +231,7 @@ function bjson_test_fuzz() { var corpus = [ "EBAAAAAABGA=", + "EObm5oIt", ]; for (var input of corpus) { var buf = base64decode(input); From 61056dcae18bc1eb62dc7223acf889022d9e19d5 Mon Sep 17 00:00:00 2001 From: Ben Noordhuis Date: Thu, 17 Oct 2024 20:39:43 +0200 Subject: [PATCH 2/2] Fix crash in deserializer on bad regexp --- quickjs.c | 7 ++++++- tests/test_bjson.js | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/quickjs.c b/quickjs.c index 4f4fc957a..2587a6408 100644 --- a/quickjs.c +++ b/quickjs.c @@ -35361,7 +35361,12 @@ static JSValue JS_ReadRegExp(BCReaderState *s) return JS_EXCEPTION; } - assert(!bc->is_wide_char); + if (bc->is_wide_char) { + js_free_string(ctx->rt, pattern); + js_free_string(ctx->rt, bc); + return JS_ThrowInternalError(ctx, "bad regexp bytecode"); + } + if (is_be()) lre_byte_swap(bc->u.str8, bc->len, /*is_byte_swapped*/TRUE); diff --git a/tests/test_bjson.js b/tests/test_bjson.js index 940967602..6a2ee2cbf 100644 --- a/tests/test_bjson.js +++ b/tests/test_bjson.js @@ -232,6 +232,7 @@ function bjson_test_fuzz() var corpus = [ "EBAAAAAABGA=", "EObm5oIt", + "EAARABMGBgYGBgYGBgYGBv////8QABEALxH/vy8R/78=", ]; for (var input of corpus) { var buf = base64decode(input);