[22] [JSC] Move FTL stack overflow check to prologue
JIT prologue 상태 불변식을 수정하는 diff이기 때문에 Medium으로 평가되었습니다. Stack overflow의 late path가 callee-save를 pop한 이후,
ThrowStackOverflowAtPrologue로 점프하기 전에 SP를 복원하지 않았습니다. 결과적으로 throw thunk는 부분적으로 구성된 frame을 가리키는 SP 상태에서 실행되었습니다.
Stack overflow patchpoint는 emitFunctionPrologue, frame allocation, callee-save spilling이 모두 완료된 이후 — 즉 lowered function body 안에서 실행되었습니다. 이 상태에서 "at prologue" stack shape을 기대하는 thunk로 점프하기 전에 상태를 되돌리려 했습니다.
Source/JavaScriptCore/ftl/FTLLowerDFGToB3.cpp
JIT exception edge에서의 stack pointer 상태 불일치: SP를 대칭적으로 되돌리지 않은 채 prologue를 지나친 지점에서 out-of-line thunk에 도달한 패턴.
원래 코드에는 이 commit이 닫는 bug 번호를 직접 가리키는 FIXME 주석이 남아 있었습니다. 작성자 스스로 stack check가 Air prologue에 위치해야 한다는 것과, late-path의 emitRestore가 임시방편에 불과했다는 사실을 인식하고 있었던 셈입니다.
이 코드에 도달하려면 FTL 함수 진입 시점에 실제 stack overflow를 강제로 유발해야 합니다. 이때 나타나는 오동작은 memory write primitive보다는 exception machinery 손상이나 crash 형태일 가능성이 높습니다. 다만 diff만으로는 throw thunk 내부에서 발생 가능한 결과의 범위를 완전히 특정하기 어렵습니다.
이 취약점은 exception throw 경로가 의존하는 내부 불변식을 약화시킵니다. 커스텀 Air PrologueGenerator로 check를 이동함으로써 대칭성 요건 자체가 제거되었습니다.
Audit directions
...AtProloguethunk로 점프하는 patchpoint에 연결된 late path.Source/JavaScriptCore/ftl/과jit/에서jumpThunk(...AtPrologue...)로 끝나는 모든addLatePath를 점검하고, callee-save와 SP가 모두 복원되는지 확인합니다....AtPrologue로 명명된 shared thunk. 해당 suffix를 가진CommonJITThunkID항목을 점검하고, 모든 호출 지점에서 stack shape이 일치하는지 검토합니다.- Frame allocation 이후에 위치한 stack overflow check. DFG, baseline, Wasm OMG/BBQ 등 다른 JIT tier에서 frame size의
subPtr이후에 stack limit 비교가 있는지 점검합니다. - Thunk 내의 방어적 정규화.
ThunkGenerators.cpp에서ThrowStackOverflowAtPrologue가 진입 시 FP를 기준으로 SP를 정규화하는지 확인합니다.