[20] [WebCore] Fix INT32_MIN UB in BackForwardController distance arithmetic
BackForwardController::canGoBackOrForward 및 WebBackForwardList::itemAtDeltaFromCurrentIndex의 INT32_MIN 산술 경로를 보강한 패치입니다. 패치 이전에는 INT32_MIN에서 static_cast<unsigned>(-distance)가 UB에 해당하며 underflow guard를 우회할 수 있었습니다. 다만 다운스트림 영향은 back-forward list 배열 인덱싱 범위 안에 한정되며, 제어 가능한 memory primitive를 제공하지는 않습니다.
부호 있는 negation이 안전한 widened 산술 연산으로 교체되었습니다. delta/distance 계산에는 더 넓은 타입이 사용되거나, negation 수행 전 INT32_MIN guard가 삽입됩니다.
Source/WebCore/history/BackForwardController.cpp
공격자가 backForwardItemAtIndexForWebContent IPC를 통해 INT32_MIN을 전달할 수 있는 underflow guard 내의 signed integer overflow.
Patch Details
negation에 INT32_MIN guard가 추가되었습니다. 이 guard는 WebBackForwardList::itemAtDeltaFromCurrentIndex에도 동일하게 적용됩니다.
Background
backForwardItemAtIndexForWebContent는 UI process의 IPC handler입니다. WebContent process가 현재 인덱스로부터의 delta를 전송하면, handler가 back/forward stack을 순회합니다.
Analysis
패치 이전에는 음수 distance 분기에서 negation이 부호 있는 산술 연산으로 수행되었습니다. static_cast<unsigned>(-distance)는 먼저 -distance를 int로 평가한 뒤 캐스팅합니다. distance == INT32_MIN인 경우 -INT32_MIN은 양수 int로 표현할 수 없어, signed integer overflow — 즉 UB — 가 발생합니다.
컴파일러는 signed overflow가 발생하지 않는다고 가정하므로, bounds guard가 최적화 과정에서 제거될 가능성이 있습니다. 2의 보수 아키텍처에서는 negation이 INT32_MIN으로 wrap-around되고, 캐스팅 후 0x80000000(약 21억)이 됩니다. 이 값은 backCount() / m_currentIndex에 따라 bounds check를 잘못 통과하거나 실패할 수 있습니다. 결과적으로 back/forward stack에 대한 out-of-bounds 배열 읽기가 발생하며, WebBackForwardListItem 벡터를 인덱싱하는 코드에 영향이 나타납니다.
UI process에서 IPC로 도달 가능한 bounds check를 약화시키는 문제입니다.
Audit directions
- 부호 있는 delta를 받는 모든 IPC entry point: 유사한
INT32_MINnegation 패턴을 점검해야 합니다. IPC receiver에서static_cast<unsigned>(-를 검색하는 것이 효과적입니다. - UI process 내에서 공격자가 제어 가능한 부호 있는 정수를 다루는 bounded-arithmetic helper.
- IPC 경계에서
CheckedArithmetic도입: 부호 있는 delta를 받는 모든 receiver가 적용 대상입니다.