← All issues

[16] [JSC] JSLock m_hasOwnerThread has concurrency issue

Severity: Medium | Component: JavaScriptCore JSLock | aed1fdd

JSLock ownership state의 publication symmetry가 복원되는 패치이므로 Medium으로 평가됩니다. 이 race는 lock을 보유하지 않은 thread에서 currentThreadIsHoldingLock()이 true를 반환하게 만들어, 두 thread가 VM에 동시에 진입하는 상황을 유발할 수 있습니다. 다만 racy observation에 도달하려면, stale m_ownerThread가 우연히 현재 thread와 일치하는 타이밍이 필요합니다.

JSLock::lockm_ownerThread를 기록한 뒤 m_hasOwnerThread = true를 설정했으며, 두 쓰기 사이에는 writer 측의 storeStoreFence()가 있었습니다. 그러나 reader는 두 필드를 plain non-atomic load로 읽었고, 이에 대응하는 acquire barrier가 없었습니다. 결과적으로 weak ordering을 허용하는 하드웨어에서는 m_hasOwnerThread == true를 관찰하면서 동시에 stale m_ownerThread를 읽는 상황이 가능했습니다.

Source/JavaScriptCore/runtime/JSLock.cpp / JSLock.h

m_ownerThread = &Thread::currentSingleton();
- WTF::storeStoreFence();
- m_hasOwnerThread = true;
+ m_hasOwnerThread.store(true, std::memory_order_release);
- bool currentThreadIsHoldingLock() { return m_hasOwnerThread && m_ownerThread.get() == &Thread::currentSingleton(); }
+ bool currentThreadIsHoldingLock() { return m_hasOwnerThread.load(std::memory_order_acquire) && m_ownerThread.get() == &Thread::currentSingleton(); }

m_hasOwnerThreadstd::atomic<bool>로 변경되었습니다. Writer는 memory_order_release를 사용하고, ownerThread(), ownerThreadUID(), currentThreadIsHoldingLock()의 reader는 memory_order_acquire를 사용합니다.

비대칭 memory fencing — writer에는 release 순서가 적용되었지만 reader가 unordered non-atomic load를 사용하는 구조에서는, 두 필드 사이의 publication invariant가 깨집니다.

JSLock은 재귀적으로 동작합니다. lock()currentThreadIsHoldingLock()을 확인하여 true이면 underlying mutex를 획득하는 대신 m_lockCount를 증가시킵니다. (m_hasOwnerThread, m_ownerThread) 쌍은 m_lock을 보유하지 않은 상태에서 SamplingProfiler, MachineThreads, Web Thread interop이 접근하는 racy-readable view로 공개됩니다. 동일한 atomic에 대한 release-acquire 쌍은 이전 write를 이후 read와 동기화합니다.

🔒

The memory-ordering and mutual-exclusion implications of this bug, and what an attacker could plausibly do with a one-sided publication on a recursive lock, are explored in depth.

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

🔒

Multiple reusable audit patterns identified around one-sided fencing and lock-ownership publication, with concrete starting points across JSC and WTF.

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