Branch: refs/heads/main
Home: https://github.com/WebKit/WebKit
Commit: 040ef6e21ffac03b6d6098e0e12354bdb5469ad1
https://github.com/WebKit/WebKit/commit/040ef6e21ffac03b6d6098e0e12354bdb5469ad1
Author: David Kilzer <[email protected]>
Date: 2026-06-29 (Mon, 29 Jun 2026)
Changed paths:
A LayoutTests/fast/canvas/canvas-getContext-reentrant-expected.txt
A LayoutTests/fast/canvas/canvas-getContext-reentrant.html
M Source/WebCore/html/HTMLCanvasElement.cpp
M Source/WebCore/html/OffscreenCanvas.cpp
Log Message:
-----------
Crash in CanvasRenderingContext::deref after reentrant getContext()
<https://bugs.webkit.org/show_bug.cgi?id=313175>
<rdar://175164594>
Reviewed by Said Abou-Hallawa.
`HTMLCanvasElement::getContext()` and `OffscreenCanvas::getContext()`
check `m_context` at the top, then call
`convert<IDLDictionary<...>>()` on the settings argument. Dictionary
conversion invokes JS property getters, which can re-enter
`getContext()` on the same canvas and assign `m_context`. The outer
call then proceeds to `createContext2d()`/`createContextWebGL()`/
`createContextBitmapRenderer()`, which overwrites `m_context` with a
new `unique_ptr`, destroying the inner context while its JS wrapper
is still alive. `CanvasRenderingContext` forwards `ref()`/`deref()`
to its owning `CanvasBase`, so the wrapper's ref does not keep the
context alive; on GC sweep the wrapper's `deref()` reads `m_canvas`
from a freed `this`.
Re-check `m_context` (and `m_detached` for `OffscreenCanvas`) after
dictionary conversion. If a re-entrant call set `m_context`, return
the existing context when the type matches and null otherwise,
matching the existing early-return semantics.
Also upgrade `ASSERT(!m_context)` to
`ASSERT_WITH_SECURITY_IMPLICATION(!m_context)` in all four
`createContext*()` methods. These asserts guard the same invariant
this bug violates -- that `m_context` is assigned at most once --
and a violation is security-relevant.
Test: fast/canvas/canvas-getContext-reentrant.html
* LayoutTests/fast/canvas/canvas-getContext-reentrant-expected.txt: Add.
* LayoutTests/fast/canvas/canvas-getContext-reentrant.html: Add.
* Source/WebCore/html/HTMLCanvasElement.cpp:
(WebCore::HTMLCanvasElement::getContext):
(WebCore::HTMLCanvasElement::createContext2d):
(WebCore::HTMLCanvasElement::createContextWebGL):
(WebCore::HTMLCanvasElement::createContextBitmapRenderer):
(WebCore::HTMLCanvasElement::createContextWebGPU):
* Source/WebCore/html/OffscreenCanvas.cpp:
(WebCore::OffscreenCanvas::getContext):
Originally-landed-as: 305413.763@safari-7624-branch (40941e46f2d4).
rdar://180436486
Canonical link: https://commits.webkit.org/316107@main
To unsubscribe from these emails, change your notification settings at
https://github.com/WebKit/WebKit/settings/notifications