A Typer Bug
One of my favourites
One of my favourite writeups and bugs is this writeup about exploiting mis-speculation bugs, based on this report by Project Zero.
Conceptually, the bug is actually very simple. In JavaScript, there are two types of zero - 0 and -0. This is because JavaScript implements the IEEE Standard for Floating-Point Arithmetic (IEEE 754), which has signed zeroes, but I still think it's stupid.
The bug is found in the Math.expm1 function, which calculates to the power of a number and then subtracts . The typer, as described in the report, sets the type of Math.expm1 to be Union(PlainNumber, NaN) (found here and here) - that is, regardless of the input to Math.expm1, the output will either be classified as a PlainNumber (any floating-point number except -0) or NaN. The problem, however, is that Math.expm(-0) = -0, so the typer is wrong.
As shown in the PoC, we can abuse this fact to cause mis-speculation. The idea is to compare Math.expm(-0) to -0. While this is actually true, when optimized, Turbofan will use the incorrect type and note that -0 is not a possible output, so it will optimize it away for speed and set the value to false:
function foo() {
return Object.is(Math.expm1(-0), -0);
}
console.log(foo());
%OptimizeFunctionOnNextCall(foo);
console.log(foo()); When you run this in d8:
% d8 --allow-natives-syntax expm1-poc.js
true
falseOnce you get to this point, you have everything you need. The idea is to create something else that would normally trigger a check but the JIT compiler has optimized the check away. For example:
function foo(x) {
let a = [1.1, 2.2];
let b = Object.is(Math.expm1(x), -0);
return a[b * 1337];
}Since b is optimized to be false, which is equivalent to 0, the bounds check is removed and, in theory, we would access OOB at index 1337! From here, it's the same as the classic OOB challenge.
However, the typer is a little smarter than this, and since b can only possibly be 0 it will fold out b entirely and the whole function will just return 1.1. There are several tricks required to stop this folding, but I won't go over them right now - I recommend you check out the rest of the writeup, which is of a CTF challenge based on this bug. The report also contains information on achieving an OOB.
TODO finish this
More Writeups
Last updated
Was this helpful?