Skip to content

Fix crash on failure to read bytecode (arguments, local variables, etc.)#1146

Merged
saghul merged 1 commit intoquickjs-ng:masterfrom
penneryu:master
Sep 1, 2025
Merged

Fix crash on failure to read bytecode (arguments, local variables, etc.)#1146
saghul merged 1 commit intoquickjs-ng:masterfrom
penneryu:master

Conversation

@penneryu
Copy link
Copy Markdown
Contributor

We have encountered crashes in production related to bytecode reading. When reading specific parts of the bytecode (such as arguments, local variables, and other related data) fails, the subsequent release of the corresponding object may trigger a null pointer crash.

static JSValue JS_ReadFunctionTag(BCReaderState *s)
{    
    bc_read_trace(s, "args=%d vars=%d defargs=%d closures=%d cpool=%d\n",
                  b->arg_count, b->var_count, b->defined_arg_count,
                  b->closure_var_count, b->cpool_count);
    bc_read_trace(s, "stack=%d bclen=%d locals=%d\n",
                  b->stack_size, b->byte_code_len, local_count);

    if (local_count != 0) {
        bc_read_trace(s, "vars {\n");
        bc_read_trace(s, "off flags scope name\n");
        for(i = 0; i < local_count; i++) {
            JSVarDef *vd = &b->vardefs[i];
            if (bc_get_atom(s, &vd->var_name))
                // If this jump to fail, the bytecode object obj.byte_code_len will already have a value, but obj.byte_code_buf will still be null. Jumping to JS_FreeValue will crash at free_function_bytecode.
                goto fail; 
            if (bc_get_leb128_int(s, &vd->scope_level))
                goto fail;
            if (bc_get_leb128_int(s, &vd->scope_next))
                goto fail;
            vd->scope_next--;
            if (bc_get_u8(s, &v8))
image
@saghul
Copy link
Copy Markdown
Contributor

saghul commented Aug 29, 2025

Any chance of adding a test for it?

@penneryu
Copy link
Copy Markdown
Contributor Author

Any chance of adding a test for it?

It’s a bit tricky to add an automated test for this, since reproducing the corrupted bytecode scenario is not straightforward. From what we observed, our crashes seem to be caused by incomplete bytecode files that were downloaded or decompressed on the mobile device.

@bnoordhuis
Copy link
Copy Markdown
Contributor

bnoordhuis commented Aug 29, 2025

The change itself is fine but apropos this:

our crashes seem to be caused by incomplete bytecode files that were downloaded or decompressed on the mobile device

The on-disk bytecode format is not designed to withstand corruption or malice. If you're downloading stuff over the network, you need to put additional integrity checks in place (like download over https only, or checking the hash after downloading, etc.)

In short, you need to make sure you're actually executing what you think you're executing.

@aabbdev
Copy link
Copy Markdown

aabbdev commented Aug 29, 2025

@penneryu It looks like you may have a durability issue. Consider adding a checksum to verify data integrity, or rely on a storage engine with WAL support (e.g. SQLite, RocksDB, LMDB).

@penneryu
Copy link
Copy Markdown
Contributor Author

Thank you very much for all of your suggestions. I will add safety checks for the downloaded files. 🙏

@saghul saghul merged commit c0fd00c into quickjs-ng:master Sep 1, 2025
127 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

4 participants