[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가 제어하는 데이터가 아닙니다.
Patch Details
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 유효성 검사가 누락된 패턴.
Background
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()를 두 번 호출하는 방식으로 이 상황을 재현할 수 있습니다.
Analysis
패치 이전에는 unregisterServiceWorkerClientInternal()이 HashMap::find()로 얻은 iterator를 end() 검사 없이 무조건 역참조했습니다. 내부 map들이 race condition으로 동기화 상태를 벗어나는 경우가 있습니다. 예를 들어 동일한 client가 두 번 등록 해제될 때가 이에 해당합니다. 이 경우 find()가 end()를 반환하고, 이후 역참조는 유효하지 않은 메모리 접근 또는 crash로 이어졌습니다.
Aaaaaaaaaa Aaaaaaa Aaaaaaaaa Aaaaaaa Aaaa Aaaaaaaa Aaaa Aa Aaa Aaa Aa Aaa Aaaaaa Aaaaaa Aaaaa Aaa Aaaa Aaa Aaaa Aaa a a Aa Aaaaaa Aaaa Aaaa Aa Aaa Aaaaa Aaaaaa Aa Aaaaa Aaaa Aaaaaaaaaa Aaa Aa Aaa Aaa Aa Aaa Aa Aaaaaa
a Aaaaaaaaaaaaaa Aaaaaaa Aaaaaaaa Aaaa Aaaaaaa a Aaaa Aaaaaa Aaaa Aaaa Aa Aaa Aaaaaaa Aaa Aaaaaa
Aaaaaaaaa Aaaaaaa Aaaaaa Aaa Aaa Aaa Aaa Aaaa Aa Aa Aa Aaaaa Aaaaaa Aa Aaaaa Aaa Aaaa Aaaa Aaaaaaaaa Aaaa a Aaaaa Aaa Aaa Aaa a Aaaaa Aaa Aa a Aaaa Aaaaa Aaaaaa Aaa Aaa Aaaaaaa Aaaa Aaa Aa Aa Aaaaa Aaaa a Aaa Aaaaaaa Aaaaaaaaaaaaa Aaaaaa Aaaaa Aaaaaa Aaa Aa Aaaaa
🔒Explores whether this crash can be escalated under realistic conditions
더 확인하려면 구독해 주세요
Audit directions
a Aaaaa Aa Aaaaa Aaaaaaaaaa Aa Aaa Aa Aaaaa Aaaaaaaaa Aaa Aaaaa Aaaaaaa Aaaaa Aaaaaaaaaaaa Aaaaaaa Aa Aa Aaaaa Aa Aaaaaaaaaaaaaaaaa Aaa Aaaa Aaaa Aaaaaaaaaaaaaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aaaaaaaaaaaaaaaaaaaaaaa Aaaaaaa Aaa Aaaaaaaaaa Aa Aaa Aaaa Aaaa Aaa a Aaaaa
a Aaaaaaaa Aaaaaaaaa Aaaaa Aa Aa Aaaaa Aaa Aaaa Aaaa Aaaaa Aaa Aaaa Aaaaaaa Aaaaaa Aa Aaaaaaaaaa Aaaaaa Aa Aaaa Aaa Aaaa a a Aaa Aa Aaaaaa Aa Aa a Aa Aaa Aaaa Aaaaaaaaaaaaaa Aaa Aaaaaaaaaa Aa Aaaaaaa Aa Aaaa Aa Aaa Aa Aaa Aaa Aaaa Aaaa
🔒Multiple reusable audit patterns identified, with concrete starting points for variant discovery across WebKit's multi-process client tracking
더 확인하려면 구독해 주세요