Chrome V8 Hole Exploit
Kinda a cool bug dealing with an improper optimization and the usage of an unexpected object from JS, leading to an out-of-bounds access.
So upfront, I had some issues following this one, so I’ll summarize what I got from it, but I might be misunderstanding something. The issue came down to a combination of two things:
the_hole
object. The hole is a special oddball
type of value in V8. Oddball just meaning it is defined by V8 before any user javascript runs, and can’t be modified by a user. It also, as I understand it is not supposed to really be accessed or user by user javascript. So if one can leak a variable pointing to it and use it, some problems can arise. In this case, when the optimizer is doing a value-range analysis, and the_hole
is part of it, it’ll treat it as undefined. So in the following code:
function test(b) {
let index = Number(b ? the.hole : -1);
index |= 0;
index += 1;
index *= 100
return index
}
Where the.hole
is the_hole
object. When this gets optimized it thinks that the only possible initial value for index
is -1
and will optimize around that fact. When doing array[indexing]
a bounds check is necessarily inserted even if the range analysis indicates its unnecessary, however using array.at(...)
does not have the same bounds check, instead that bounds check is only conditionally inserted. As such because the value-range analysis is incorrect with the hole object, it believes the bounds check is unnecessary and allows for an OOB access.
Honestly, this is a really specific V8 issue, but I thought it was fun in a more general sense too, just the idea of using these sort of edge-case values and not necessarily reasoning about them correctly is an issue any dev can make.