← WebKit — 2026-W39
e0b1fddaa46813e6b7165037198bb7c34768c1f6 [GTK][WPE] Crash on exit in PlatformDisplay::terminateEGLDisplay
severity low
class Race
confidence 0.45
signal score 8.59
Source/WebCore/platform
Primitive: data race between thread-local GLContext/SkiaGLContext destructors and main-thread EGL display termination at process exit
Triage note: Adds m_terminationLock + atomic<EGLDisplay> and runIfNotTerminated() to GLDisplay so GLContext::~GLContext and SkiaGLContext::~SkiaGLContext do not call eglMakeCurrent/eglDestroyContext on a display the main thread is concurrently terminating in destroySharedDisplay(); a genuine shutdown concurrency fix (use-after-terminate of EGL resources) but GTK/WPE exit-path only and hard to weaponize.
Triage note: Adds m_terminationLock + atomic<EGLDisplay> and runIfNotTerminated() to GLDisplay so GLContext::~GLContext and SkiaGLContext::~SkiaGLContext do not call eglMakeCurrent/eglDestroyContext on a display the main thread is concurrently terminating in destroySharedDisplay(); a genuine shutdown concurrency fix (use-after-terminate of EGL resources) but GTK/WPE exit-path only and hard to weaponize.
Structural signals: smartptr_member_added (+3.0), security_assert (+3.0), null_guard (+2.59), msg_medium (+2.0), large_churn (-2.0)
Commit message
[GTK][WPE] Crash on exit in PlatformDisplay::terminateEGLDisplay
https://bugs.webkit.org/show_bug.cgi?id=305909
rdar://problem/168564545
Reviewed by Carlos Garcia Campos.
The EGL display was terminated in an atexit handler while other threads could
still use it. In the GPU process, the WebGL thread could still be using the
sharing context when the handler destroyed it. In the web process, a thread
that exits destroys its Skia context at the same time, and because Mesa frees
the display in its own atexit handler, that thread writes into freed memory
and corrupts the heap, which is bug 315577.
Destroy the display on the main thread before exiting instead, after the GPU
process has closed its web process connections and stopped the WebGL thread,
and after the web process has closed its pages. The display is terminated
before it is deleted, so that the native display of a subclass, like the
libwpe backend, is still alive when EGL terminates. A thread that destroys its
context while the display is terminated now waits for it, and does nothing
once the display is gone.
* Source/WebCore/platform/graphics/PlatformDisplay.cpp:
(WebCore::PlatformDisplay::setSharedDisplay):
(WebCore::PlatformDisplay::sharedDisplayIfExists):
(WebCore::PlatformDisplay::destroySharedDisplay):
(WebCore::PlatformDisplay::PlatformDisplay):
(WebCore::PlatformDisplay::terminateEGLDisplay):
(WebCore::PlatformDisplay::~PlatformDisplay): Deleted.
* Source/WebCore/platform/graphics/PlatformDisplay.h:
* Source/WebCore/platform/graphics/egl/GLContext.cpp:
(WebCore::GLContext::~GLContext):
* Source/WebCore/platform/graphics/egl/GLDisplay.cpp:
(WebCore::GLDisplay::terminate):
(WebCore::GLDisplay::runIfNotTerminated):
* Source/WebCore/platform/graphics/egl/GLDisplay.h:
* Source/WebCore/platform/graphics/skia/PlatformDisplaySkia.cpp:
(WebCore::SkiaGLContext::~SkiaGLContext):
* Source/WebKit/GPUProcess/GPUConnectionToWebProcess.h:
(WebKit::GPUConnectionToWebProcess::close):
* Source/WebKit/GPUProcess/GPUProcess.h:
* Source/WebKit/GPUProcess/glib/GPUProcessGLib.cpp:
(WebKit::GPUProcess::stopRunLoop):
* Source/WebKit/Shared/AuxiliaryProcess.cpp:
(WebKit::AuxiliaryProcess::didClose):
* Source/WebKit/WebProcess/WebProcess.cpp:
(WebKit::WebProcess::initializeConnection):
* Source/WebKit/WebProcess/WebProcess.h:
* Source/WebKit/WebProcess/glib/WebProcessGLib.cpp:
(WebKit::WebProcess::stopRunLoop):
Canonical link: https://commits.webkit.org/321775@main
Before / after
Loading diff…
On This Page