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

Reply via email to