Skip to content

avoid out-of-bounds opcode read in JS_ReadFunctionBytecode#519

Open
uwezkhan wants to merge 1 commit into
bellard:masterfrom
uwezkhan:bytecode-opcode-bounds
Open

avoid out-of-bounds opcode read in JS_ReadFunctionBytecode#519
uwezkhan wants to merge 1 commit into
bellard:masterfrom
uwezkhan:bytecode-opcode-bounds

Conversation

@uwezkhan

Copy link
Copy Markdown

JS_ReadFunctionBytecode walks the serialized opcode stream and, for the atom formats, reads a 4-byte operand at get_u32(bc_buf + pos + 1) and rewrites it with put_u32. The loop only checks pos < bc_len, not that the whole opcode fits, so a function whose byte_code ends in a truncated atom opcode reads and relocates up to four bytes past the bytecode allocation. JS_ReadObject with JS_READ_OBJ_BYTECODE reaches this; ASan reports a heap-buffer-overflow READ of size 4 on a 17-byte blob whose 1-byte byte_code is a single OP_push_atom_value. bc_byte_swap has the same unchecked walk on big-endian targets.

Before, the reader trusted the opcode size to stay within byte_code_len and stepped pos past the end only after touching the operand. After, each iteration rejects an opcode that would extend past bc_len before any operand is read, and rewinds b->byte_code_len to the validated prefix so atom cleanup frees only what was already relocated, matching the existing truncated-atom error path. The check sits in the reader because the operand bytes come straight from the input buffer and no caller can make a short opcode whole. Tradeoff: a deliberately truncated final opcode now fails the load with a SyntaxError instead of being silently tolerated.

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.

1 participant