[8] GetByStatus walks prototype chain for direct/private property opcodes
Severity: Medium | Component: JSC bytecode IC status + DFG | b07dca9
DFG가 prototype-walk 가정 하에 GetByIdDirect/GetPrivateNameById를 특수화할 수 있었던 JIT IC status helper를 수정한 패치입니다. non-own slot에서 controlled property fetch로 이어지는지 여부는 downstream lowering에 달려 있으며, diff만으로는 확인되지 않습니다. 이러한 점에서 Medium으로 평가합니다.
GetByStatus를 계산하는 과정에서는, prototype walk를 수행하기 전에 먼저 direct property access인지 확인해야 합니다. direct access는 prototype을 참조해서는 안 되기 때문입니다.
Source/JavaScriptCore/bytecode/GetByStatus.cpp
-GetByStatus GetByStatus::computeFor(JSGlobalObject* globalObject, const StructureSet& set, CacheableIdentifier identifier)
+GetByStatus GetByStatus::computeFor(JSGlobalObject* globalObject, const StructureSet& set, CacheableIdentifier identifier, GetByStatus::LookupMode mode)
{
- // 이 코드는 GetByIdDirect에서도 사용됩니다. 이 함수는 direct property만 조회하므로,
- // prototype chain을 지원하려면 GetById와 GetByIdDirect를 별도로 처리해야 합니다.
...
- if (auto result = attempToFold())
- return result.value();
+ // prototype walk는 일반 access인 경우에만 수행해야 합니다.
+ // direct access에서는 prototype을 참조하지 않습니다.
+ if (mode == GetByStatus::LookupMode::Normal) {
+ if (auto result = attempToFold())
+ return result.value();
+ }
Source/JavaScriptCore/dfg/DFGNode.h
+ GetByStatus::LookupMode propertyLookupMode()
+ {
+ switch (op()) {
+ case GetByIdDirect:
+ case GetByIdDirectFlush:
+ case GetPrivateNameById:
+ return GetByStatus::LookupMode::Direct;
+ case GetById:
+ case GetByIdFlush:
+ case GetByIdMegamorphic:
+ return GetByStatus::LookupMode::Normal;
+ default:
+ RELEASE_ASSERT_NOT_REACHED();
+ }
+ }
Patch Details
GetByStatus에 새로운 LookupMode enum(Normal/Direct)이 추가되었고, computeFor의 파라미터로도 포함되었습니다. computeFor 내부의 prototype walk(attempToFold() 블록)는 이제 mode == LookupMode::Normal인 경우에만 실행됩니다. Node::propertyLookupMode()가 추가되어 DFG opcode를 적절한 mode에 매핑합니다. DFGAbstractInterpreterInlines.h::executeEffects와 DFGConstantFoldingPhase::foldConstants는 node로부터 mode를 결정하도록 수정되었습니다. DFGByteCodeParser의 op_get_from_scope는 Normal로 고정됩니다. global property lookup은 global object의 prototype chain을 순회해야 하기 때문입니다. 함수가 direct property만 조회한다고 기술한 낡은 주석은 제거되었습니다.
JIT IC status 계산 과정의 speculation-soundness 위반: prototype 순회를 금지하는 opcode에 공유 helper가 prototype-chain 의미론을 적용하는 패턴.
Background
GetByStatus는 GetById 계열 bytecode가 런타임에서 수행한 동작의 요약입니다. 관찰된 structure, offset, prototype walk 정보를 담아, DFG가 load를 inline할지, 결과를 constant-fold할지, 아니면 generic IC로 전환할지를 결정하는 근거가 됩니다. GetById는 ECMAScript [[Get]]을 완전히 수행하며 prototype chain을 순회합니다. 반면 GetByIdDirect는 own property에만 접근하며, 해당 property가 own property가 아닌 경우 반드시 undefined를 반환해야 합니다. GetPrivateNameById는 private class field를 읽는 opcode로, receiver의 brand를 키로 사용하며 스펙상 own property만 접근하도록 제한됩니다. computeFor 내부의 attempToFold는 prototype chain을 순회해 property를 탐색하고, 발견 시 Simple variant로 fold하는 역할을 맡습니다. DFG의 AbstractInterpreter와 ConstantFoldingPhase는 반환된 GetByStatus를 바탕으로 IR을 특수화합니다.
Analysis
GetByStatus::computeFor는 항상 attempToFold()를 호출했으며, 이 함수는 prototype chain을 순회합니다. 문제는 DFG pass에서 모든 GetBy* node에 대해 예외 없이 호출되었다는 점입니다. GetByIdDirect, GetByIdDirectFlush, GetPrivateNameById처럼 런타임 의미론상 own property만 접근해야 하는 opcode도 마찬가지였습니다. 낡은 주석은 이 함수가 direct property만 조회한다고 기술하고 있었는데, 작성 당시에는 정확한 설명이었습니다. 하지만 attempToFold가 나중에 추가되면서 사실과 달라졌습니다.
Aaaaaa Aaaa Aaaaaaaaaaaaaaa Aaaaa Aaaaaaaaaaa Aaaaaaaa Aaa Aaaaaaa Aaaa a Aaaaaa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaa Aaaaaaaaa Aaa Aaaaa Aaaa Aaaaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaa Aaaaaaaa Aaaaaa Aa Aaaa Aa Aaaaaaaa Aaaaaaaaaaaaaaaaa Aaaa Aa Aaaaa Aaa Aaaaa a Aa Aaa Aaa Aaaa Aaaaa Aaaaaaaaaaaaaaaa Aaa Aaa Aaaa Aaaaaaaaaaaa Aaaa a Aaaa Aaaaaaaaa Aaaaa Aa Aa Aaaaaa Aaaaaaaaaaaaaaaaaaaaa Aaa Aaaaaaa Aaaaaa Aaaaaaaaaaaaaa Aaaa Aaa Aaaa Aaaaa Aaaaaaaaaa Aaaaaaaaaa Aaa Aaaaaaaaa Aaaaaa Aaaaa Aaa Aa Aaa Aaaaaa Aaaaaaaaaaaaaa Aaaaa Aaaa Aaaa Aaaaaaa Aaaaaaa Aaaaaaaaaa Aaaaaaaa Aaaaaaaa Aa Aaa Aaaaaa
a Aaaa Aaa Aaaaaaaa Aa Aaa Aa Aaa Aaaaaaaaaaaa Aaaaaaaaaa Aaaaaaaa Aaa Aa Aaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaa Aa Aa Aaaaaaa a Aaa Aaaaa Aa Aa Aaa Aaaa Aaaaaaaaa Aaa Aa Aaaaaaaaa Aaaaa Aaaa Aaaaaaaa Aaaaaaaaaaaa Aaa a Aaa Aaaaaaa Aa Aaa Aaa Aaaaaaaaaaa Aaaa Aaa Aaa Aaaa Aaaa Aa a Aaaaaa Aa Aaa Aa Aa Aaa Aaa Aaaa Aaaa Aaaaa Aaaaaaaaaaaaaaa Aaa Aaa a Aaaa Aa Aaa Aaaa Aa Aaa Aa Aaaaaa Aaaaaa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaaaa Aaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaa Aaa Aaaaaaaaaaaaa Aaa Aa Aaa Aa Aaaaaa Aaa Aaaaaaaa Aaaaaaa Aaa Aa Aaaa Aaaaaa Aaaa Aaaaa Aaaa Aaaa
🔒The speculation-soundness implications of conflating own-property and prototype-walking semantics in a shared JIT helper, and the conditions under which this can escalate beyond a pure correctness bug
더 확인하려면 구독해 주세요
Audit directions
a Aaaa Aa Aaaa Aa Aaaaaa Aaa Aaaaa Aa Aaaa Aaaa Aa Aaaaaaaaa Aaaaaaa Aaaaa Aaaaa Aa Aaa Aaaaaa Aa Aa a Aaaaaaaaaaaaaa Aaaaaaaaaaaaa Aaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaa a Aaa Aaa Aaa Aaa Aaaa Aaaa Aa Aaaaa Aaaa Aaaa Aa Aaaaaaaaaaaaaaaaa Aaa Aaaaaaaaaaaaaaaaa Aaa Aa Aaaa Aaaa Aaaa Aa Aaaaaaaaaaaa Aaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaa Aa Aaaaa
a Aaaa Aaaaaaaa Aaaaaaa Aaaaaaaa Aaa Aaaa Aaaaaaaaaaaa Aaaaaaaaa Aaaa Aaaa Aa Aaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaa Aaaa Aaaaaa a Aaaaaaaaa Aaaaaa Aaaa Aa Aaa Aaaa Aaaa Aaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaa Aa Aaa Aaaaa Aaa Aaaaaaaaaaaa Aaaaaaa Aaaaaaa Aaaaa Aaaa Aaaa
a Aaaaaaaaa Aaa a Aaaaa Aa Aaa Aaaa Aa Aaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaa Aaaaaaaa Aaaaa Aaaaaaaa Aaaa Aaaa Aa a Aaaaa Aaaaaa a Aaaaa Aaaaaaaa a Aaaaa Aaaa Aa Aaa Aaaaa Aa Aaa Aaa Aa Aaaaa Aaaa Aaaa
a Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa a Aaaaa Aa Aaa Aaa a Aa Aa Aaaaaaaa Aaaaaaa Aaaaa Aaaa Aaaa Aaaaaaaa Aa Aaaaaa Aa a Aa Aaaaaa Aaa Aaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaa Aaaaaaaaa Aaaaaa Aaaaaa Aaaaaaaaaaaaaaaaaa Aaaaaaaaaaaa Aa Aaaaaaaaaaaa Aaaaaaaaaaa Aaaaaaa a Aaaaaaa Aaaa Aa Aa Aa Aa Aaa Aaa a Aa Aa Aaaa Aa Aaaa Aaaa
🔒Several reusable audit patterns identified across JSC's IC status computation layer, with concrete starting points for finding variants in sibling status helpers
더 확인하려면 구독해 주세요