← All issues

Sampled mprotect write-guard for DOMWrapperWorld::m_wrappers corruption

d2af128beb0b21

DOMWrapperWorld::m_wrappers는 JS/DOM binding layer의 핵심 hash map입니다. DOM 객체와 살아있는 Weak<JSObject> wrapper handle을 연결합니다. JS가 DOM 노드에 접근할 때마다 cacheWrapper가 항목을 삽입하거나 갱신합니다. GC는 rehash 과정에서 JSC::WeakImpl::clear()를 호출해 stale 항목을 정리하는데, 테이블이 손상된 상태라면 이 시점에 garbage address를 역참조하게 됩니다. 이번 commit은 이런 stray write를 포착하기 위한 sampled instrumentation을 추가했습니다.

Source/WebCore/bindings/js/DOMWrapperWorld.cpp

+void* WrapperMapTableMalloc::allocate(size_t size)
+{
+ size_t pageSize = WTF::pageSize();
+ size_t rounded = (requested + pageSize - 1) & ~(pageSize - 1);
+ void* base = mmap(nullptr, rounded, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0);
+ RELEASE_ASSERT(base != MAP_FAILED);
+ if (auto* world = WrapperMutationScope::currentlyMutatedWorld())
+ world->noteTableBacking(base, rounded);
+ return base;
+}
+
+void DOMWrapperWorld::setWrappersTableWritable(bool writable)
+{
+ if (writable) {
+ if (m_wrappersTableWritableDepth++)
+ return;
+ } else {
+ ASSERT(m_wrappersTableWritableDepth);
+ if (--m_wrappersTableWritableDepth)
+ return;
+ }
+ if (m_wrappersTableBase)
+ RELEASE_ASSERT(!mprotect(m_wrappersTableBase, m_wrappersTableSize,
+ PROT_READ | (writable ? PROT_WRITE : 0)));
+}

새로 추가된 WrapperMapTableMalloc allocator는 hash table의 backing을 page-aligned mmap 메모리에 배치하고, 평소에는 PROT_READ 상태로 유지합니다. cacheWrapper / uncacheWrapper / clearWrappers 호출 중에는 WrapperMutationScope RAII guard가 해당 페이지를 일시적으로 PROT_READ|WRITE로 전환합니다. 이 기능은 시작 시 weakRandomNumber를 통해 약 1/64 프로세스에서 활성화됩니다. 덕분에 mutation scope 밖에서 stray write가 발생하면, 나중에 메모리 손상으로 crash가 이어지는 대신 write 발생 지점에서 즉시 fault가 발생합니다.

WebKit JS/DOM binding layer에서 현재 진행 중인 미해결 production heap corruption이 존재함을 드러냅니다. 동일한 garbage-pointer 패턴이 위상적으로 무관한 hash table(m_wrappers, CodeBlockSet) 양쪽에서 관찰됩니다. 이는 해제된 객체가 hash table backing으로 재사용된 후, dangling pointer에 의해 기록되는 패턴과 일치합니다.

🔒

Cross-process shared memory with three concurrent writers, a removed extrapolation bound, and new floor/ceiling invariants — audit directions included.

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