← All issues

[3] [JSC FTL] Fix indexing-type mismatch in OSR exit array materialization during bad time

Severity: High | Component: JSC FTL JIT | eba64ef

FTL OSR exit으로 생성된 script-visible JSArray에서 SlowPutArrayStorage Structure와 contiguous butterfly 사이의 type confusion을 수정하는 diff로, High로 평가합니다. 결과로 만들어진 cell을 ArrayStorage code path로 처리하면 contiguous 메모리 위에서 동작하게 되며, 인접한 heap에 대한 controlled out-of-bounds primitive가 발생합니다.

operationMaterializeObjectInOSR는 rematerialized array의 structure를 originalArrayStructureForIndexingType으로 선택하도록 변경되었습니다. 이를 통해 bad-time 상태와 관계없이 contiguous structure가 유지됩니다. butterfly를 채운 뒤 일관된 상태가 확보되면 switchToSlowPutArrayStorage(vm)을 호출합니다. operationPopulateObjectInOSR에는 migration 이후 hole fixup을 위한 hasAnyArrayStorage 분기가 추가되었습니다.

Source/JavaScriptCore/ftl/FTLOperations.cpp

- Structure* structure = globalObject->arrayStructureForIndexingTypeDuringAllocation(materialization->indexingType());
+ Structure* structure = globalObject->originalArrayStructureForIndexingType(materialization->indexingType());
JSArray* array = JSArray::createWithButterfly(vm, nullptr, structure, butterfly);
...
+ if (globalObject->isHavingABadTime())
+ array->switchToSlowPutArrayStorage(vm);

Sunk array의 FTL OSR materialization 과정에서 SlowPutArrayStorage Structure와 contiguous butterfly 사이에 발생하는 type confusion.

PhantomNewArrayWithButterfly rematerialization 과정에서 더 이상 arrayStructureForIndexingTypeDuringAllocation을 호출하지 않습니다. 대신 originalArrayStructureForIndexingType을 사용합니다. butterfly가 채워진 뒤(contiguous 슬롯, contiguous 방식으로 public/vector length 설정) 전용 transition을 통해 SlowPutArrayStorage로 migration됩니다. operationPopulateObjectInOSR는 contiguous와 ArrayStorage 형태 모두에서 hole을 수정할 수 있게 되었습니다.

FTL OSR exit은 optimizer가 sunk 처리한 객체의 materialization을 재구성합니다. PhantomNewArrayWithButterfly의 경우, runtime은 새 JSArray를 할당하고 Structure를 선택한 뒤 butterfly를 allocate하여 채웁니다. JSC의 "bad time" mode는 Array.prototype 또는 Object.prototype에 indexed accessor가 설치될 때 진입합니다. 이 mode에서는 global object의 기본 array structure가 SlowPutArrayStorage로 전환됩니다. SlowPutArrayStorage는 contiguous와 다른 butterfly header(m_vector, m_numValuesInVector, m_sparseMap)와 슬롯 레이아웃을 사용합니다.

패치 이전에는 arrayStructureForIndexingTypeDuringAllocation으로 structure를 조회했습니다. 이 함수는 해당 indexing type의 현재 기본값을 반환합니다. 즉, bad time 상태일 때는 대체 structure가 반환됩니다. butterfly를 채우는 코드는 contiguous 방식으로 고정되어 있었습니다. butterfly->contiguous().atUnsafe(index)에 값을 기록하고 contiguous 방식의 public/vector length를 설정했습니다. 결과로 생성된 JSArrayStructure를 통해 SlowPutArrayStorage를 나타냈지만, butterfly 자체는 ArrayStorage header 없이 contiguous 형태였습니다.

🔒

The compile-time and exit-time views of an array's layout drift apart under a specific script-reachable global state transition — the analysis works through what that lets an attacker build, end to end.

더 확인하려면 구독해 주세요

🔒

Four reusable audit patterns identified across FTL/DFG deoptimization runtimes, with specific helpers and call sites flagged for variant discovery.

더 확인하려면 구독해 주세요