[18] [WebCore] Bound grid masonry span and exclude excluded-from-normal-layout from subgrid
두 가지 연관된 결함이 함께 수정되어 Medium으로 평가되었습니다. RenderGrid::isSubgrid()는 이제 isExcludedFromNormalLayout()을 확인합니다. 이를 통해 fieldset <legend>가 자신을 배치하지 않은 부모 grid에게 subgrid라고 응답하던 문제가 제거되었습니다. gridAreaForIndefiniteGridAxisItem()은 auto-placement span을 m_gridAxisTracksCount로 clamp합니다. 두 경우 모두 release 빌드에서 unsigned underflow가 발생하며, 그 결과 near-UINT_MAX 값이 layout 인덱싱에 유입됩니다. JS에서 관찰 가능한 read/write primitive는 존재하지 않습니다.
RenderGrid::isSubgrid()는 일반 레이아웃에서 제외된 자식 요소에 대해 false를 반환합니다. gridAreaForIndefiniteGridAxisItem()는 gridAxisLines - itemSpanLength를 계산하기 전에 std::min(itemSpanLength, m_gridAxisTracksCount)로 span 크기를 clamp합니다.
Source/WebCore/rendering/RenderGrid.cpp
Grid masonry/subgrid layout에서 전제 조건 검사 누락으로 인한 unsigned underflow — near-UINT_MAX 값의 track 인덱싱 유입.
Patch Details
isSubgrid()는 일반 레이아웃에서 제외된 자식 요소를 subgrid 판정 대상에서 제거합니다. gridAreaForIndefiniteGridAxisItem()는 gridAxisLines에서 차감하기 전에 span을 clamp합니다.
Background
CSS Grid Level 3는 masonry layout을 도입합니다(display: grid와 함께 grid-template-rows: subgrid 또는 grid-lanes 계열을 사용). fieldset의 <legend>는 fieldset이 특별하게 렌더링하는 요소로, fieldset의 grid-item 집합에서 제외됩니다. 그러나 grid-template-rows: subgrid가 적용된 경우에도 isSubgrid()에 true를 반환하는 문제가 있었습니다. 참고로 gridAxisLines = m_gridAxisTracksCount + 1입니다.
Analysis
(a) 패치 이전 isSubgrid()는 isExcludedFromNormalLayout()을 고려하지 않았습니다. legend가 layout을 요청하면 부모 grid에 자신의 위치를 묻는 흐름이 발생합니다. 그런데 부모의 m_gridItemArea에 legend가 포함되어 있지 않습니다. 이 때문에 debug 빌드에서는 ASSERT(m_gridItemArea.contains(item))가 발동되고, release 빌드에서는 unsigned underflow가 발생했습니다.
(b) 패치 이전 gridAreaForIndefiniteGridAxisItem()는 style에서 auto-placement span을 계산할 때 상한을 두지 않았습니다. grid-row: span 10이 단일 grid-axis track에 적용되면 itemSpanLength가 gridAxisLines를 초과합니다. 이후 gridAxisLines - itemSpanLength 연산에서 unsigned counter의 underflow가 발생했습니다.
underflow된 값은 near-UINT_MAX placement로서 track 인덱싱에 다시 유입됩니다. 이 값을 처리하는 하위 코드는 memory-copy primitive가 아니라 layout 연산입니다. 가장 현실적으로 예상되는 영향은 공격자가 조작한 HTML/CSS로 인한 renderer crash입니다.
이는 trust boundary를 침해하는 것이 아니라 renderer process의 가용성을 저해하는 수준입니다.
Audit directions
- 다른 layout-mode predicate와의
isExcludedFromNormalLayout()상호작용 (isFlexItem,isOrthogonalWritingMode, masonry/lane 변형 포함). - Grid/masonry/subgrid 코드 전반의 layout 인덱스에 대한 unsigned 산술 연산 —
m_gridAxisTracksCount와gridAxisLines를 사용하는 코드에서 유사한 clamp 누락이 있는지 점검해야 합니다. - Flexbox와 multicol에서의 auto-placement span 계산 — 동일한 패턴의 존재 여부를 확인해야 합니다.