如果我们用以上操作设置x和y的值之后,那么二者type都是Range(-1, 0),看下x&y后的type。
Type OperationTyper::NumberBitwiseAnd(Type lhs, Type rhs) {
...
double min = kMinInt;
// And-ing any two values results in a value no larger than their maximum.
// Even no larger than their minimum if both values are non-negative.
double max =
lmin >= 0 && rmin >= 0 ? std::min(lmax, rmax) : std::max(lmax, rmax);
// And-ing with a non-negative value x causes the result to be between
// zero and x.
if (lmin >= 0) {
min = 0;
max = std::min(max, lmax);
}
if (rmin >= 0) {
min = 0;
max = std::min(max, rmax);
}
return Type::Range(min, max, zone());
}
显然x&y后的type是Range(-1, 0),实际是1,但是二者的所在优化阶段产生了冲突,为了以上的情况能够得以实现,下面还需要其他操作,这里有些细节导致难度加大。
However, one last obstacle remains: the type propagation to the additions and subtracions only happens during the LoadElimination phase; the BitwiseAnd however is only given a type once during the initial Typer phase; we can’t use the typed optimization again as there is no equivalent “SpeculativeNumberAnd”.
So we need to somehow take the bounds information from the later LoadElimination phase and make it available already during the earlier Typer phase.
我们可以使用Math.min(2**32-1, x+(2**32-1)) – (2**32-1),之后可以使得typer知道这里不会有正数结果,这是在最开始的typer阶段就可以确定的,在后面同样用其他手段使得在对应阶段也是这个Range。
之后为了得到Range(0, 0)实际值是-1的变量,我们先使用其和-1进行Max运算,然后再取反并右移31位。
完整Poc在下一续级
#【原创】chrome已提交的两个漏洞分析(六)# |