Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix crash in deserializer #602

Merged
merged 1 commit into from
Oct 17, 2024
Merged

Conversation

bnoordhuis
Copy link
Contributor

Check inside the deserializer that const atoms are indeed const, don't trust the input. The serializer only writes type 0 records for const atoms but the byte stream may have been corrupted or manipulated.

Overlooked during review of c25aad7 ("Add ability to (de)serialize symbols")

Found with libfuzzer and it found it really fast. Great tool.


It already found more. For future reference:

diff --git a/tests/test_bjson.js b/tests/test_bjson.js
index 5807ab1..f0c16f2 100644
--- a/tests/test_bjson.js
+++ b/tests/test_bjson.js
@@ -231,6 +231,10 @@ function bjson_test_fuzz()
 {
     const corpus = [
         "EBAAAAAABGA=",
+        // hang
+        "EObm5oIt",
+        // crash
+        "EAARABMGBgYGBgYGBgYGBv////8QABEALxH/vy8R/78=",
     ];
     for (const input of corpus) {
         const buf = base64decode(input)

JSContext *ctx = JS_NewContext(rt);
if (!ctx)
exit(1);
JSValueConst val = JS_ReadObject(ctx, buf, len, /*flags*/0);
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just dread what libfuzzer is going to find when we pass JS_READ_OBJ_BYTECODE here...

@@ -1,6 +1,45 @@
import * as bjson from "bjson";
import { assert } from "./assert.js";

function base64decode(s) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is O(n*m) with respect to the length of the input (lots of indexOf calls) but performance hardly matters here. I could turn it into O(n) with a lookup table if the fuzzer ever finds a bug that takes a huge input.

Copy link
Contributor

@saghul saghul left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice one! Do you plan on looking into the fuzzing stuff that landed on bellard/ ?

Makefile Outdated Show resolved Hide resolved
Check inside the deserializer that const atoms are indeed const, don't
trust the input. The serializer only writes type 0 records for const
atoms but the byte stream may have been corrupted or manipulated.

Overlooked during review of c25aad7 ("Add ability to (de)serialize
symbols")

Found with libfuzzer and it found it _really_ fast. Great tool.
@bnoordhuis bnoordhuis merged commit a1d1bce into quickjs-ng:master Oct 17, 2024
18 of 19 checks passed
@bnoordhuis bnoordhuis deleted the fix-crash branch October 17, 2024 06:45
@bnoordhuis
Copy link
Contributor Author

Do you plan on looking into the fuzzing stuff that landed on bellard

I completely missed that, looks like that landed around the time I was out sick. I may crib from it, fuzz-testing the regex engine was next on my list.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants