← All issues

[14] SWServer Invalid Iterator Dereference on Desynchronized Maps

Severity: Low | Component: Service Workers (SWServer) | 09f4248

end() iterator를 역참조하는 crash (Network process DoS)가 관측 가능한 영향이며, 메모리 손상으로의 escalation 근거는 없습니다. Iterator가 가리키는 대상은 HashMap 내부 구조에 의해 결정되며, attacker가 제어하는 데이터가 아닙니다.

SWServer::unregisterServiceWorkerClientInternal() 내 두 위치에 iterator end() 검사를 추가하였습니다. Race condition으로 map 비동기화가 발생했을 때 find()end()를 반환하더라도, 유효하지 않은 iterator를 역참조하지 않도록 방지합니다.

Source/WebCore/workers/service/server/SWServer.cpp

auto clientsByRegistrableDomainIterator = m_clientsByRegistrableDomain.find(clientRegistrableDomain);
ASSERT(clientsByRegistrableDomainIterator != m_clientsByRegistrableDomain.end());
- auto& clientsForRegistrableDomain = clientsByRegistrableDomainIterator->value;
- clientsForRegistrableDomain.remove(clientIdentifier);
- if (clientsForRegistrableDomain.isEmpty())
- m_clientsByRegistrableDomain.remove(clientsByRegistrableDomainIterator);
+ if (clientsByRegistrableDomainIterator != m_clientsByRegistrableDomain.end()) {
+ auto& clientsForRegistrableDomain = clientsByRegistrableDomainIterator->value;
+ clientsForRegistrableDomain.remove(clientIdentifier);
+ if (clientsForRegistrableDomain.isEmpty())
+ m_clientsByRegistrableDomain.remove(clientsByRegistrableDomainIterator);
+ }
auto iterator = protectedThis->m_clientIdentifiersPerOrigin.find(clientOrigin);
ASSERT(iterator != protectedThis->m_clientIdentifiersPerOrigin.end());
- iterator->value.terminateServiceWorkersTimer->startOneShot(protectedThis->m_isProcessTerminationDelayEnabled ? defaultTerminationDelay : defaultFunctionalEventDuration);
+ if (iterator != protectedThis->m_clientIdentifiersPerOrigin.end())
+ iterator->value.terminateServiceWorkersTimer->startOneShot(protectedThis->m_isProcessTerminationDelayEnabled ? defaultTerminationDelay : defaultFunctionalEventDuration);

Race condition에 취약한 map 탐색 경로에서, 역참조 전 iterator 유효성 검사가 누락된 패턴.

Service Worker는 웹 페이지가 등록하는 background 스크립트로, network 요청을 가로챌 수 있습니다. SWServer는 WebKit의 Network process에서 실행되는 서버 측 컴포넌트로, 등록된 client들을 추적합니다. 이 컴포넌트는 m_clientsByRegistrableDomain, m_clientIdentifiersPerOrigin, m_clientsById 등 여러 HashMap을 동기화된 상태로 유지해야 합니다. client가 연결을 끊으면 unregisterServiceWorkerClient()가 각 map에서 해당 항목을 제거합니다. map 상태가 일치하기 전에 동일한 client가 두 번 등록 해제되면 race condition이 발생합니다. commit 메시지에 따르면, unregisterServiceWorkerClient()를 두 번 호출하는 방식으로 이 상황을 재현할 수 있습니다.

패치 이전에는 unregisterServiceWorkerClientInternal()HashMap::find()로 얻은 iterator를 end() 검사 없이 무조건 역참조했습니다. 내부 map들이 race condition으로 동기화 상태를 벗어나는 경우가 있습니다. 예를 들어 동일한 client가 두 번 등록 해제될 때가 이에 해당합니다. 이 경우 find()end()를 반환하고, 이후 역참조는 유효하지 않은 메모리 접근 또는 crash로 이어졌습니다.

🔒

Explores whether this crash can be escalated under realistic conditions

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

🔒

Multiple reusable audit patterns identified, with concrete starting points for variant discovery across WebKit's multi-process client tracking

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