← Chrome — 2026-W33

7f42272d65321adc372880d6432abee8174c163f  [M152] Built-In AI APIs: Check execution_context for console messaging

severity low class DoS CVSS 3.1 signal score 3.8 third_party/blink/renderer/modules/ AI review CONFIRMED
Structural signals: area:third_party/blink/renderer/modules/ (+2.5), surgical (+1.3)

The bug at a glance

A null-pointer dereference of execution_context when a page/context is destroyed during an async model-availability check causes a renderer-process crash; it is a stability/DoS bug with no memory-corruption or cross-origin impact.

A page can start a Built-In AI availability check (e.g. CanCreateLanguageModel) and then destroy its execution context before the async result arrives; the warning-logging path then dereferences a null ExecutionContext, crashing the renderer.

Root cause

HandleModelAvailabilityCheckResult() is invoked as the async completion of a model-availability check. When the result is kUnavailable it calls execution_context->AddConsoleMessage() to log a warning. If the execution context was torn down during the outstanding async call, execution_context is null and the AddConsoleMessage() call dereferences a null pointer. The fix guards the call with if (execution_context && availability == kUnavailable), and a unit test confirms a null context now returns kUnavailable without crashing.

Key code

Null-check execution_context before logging the availability warning

-  if (availability == Availability::kUnavailable) {
+  if (execution_context && availability == Availability::kUnavailable) {
     execution_context->AddConsoleMessage(

Patch walkthrough

  • third_party/blink/renderer/modules/ai/availability.cc — Adds execution_context && to the condition guarding AddConsoleMessage(), preventing a null-pointer dereference when the context was destroyed during the async availability check.
  • third_party/blink/renderer/modules/ai/availability.h — Adds MODULES_EXPORT to the availability helper declarations so they can be unit-tested; no behavior change.
  • third_party/blink/renderer/modules/ai/availability_test.cc — New unit test exercises HandleModelAvailabilityCheckResult with a null execution_context, verifying it returns kUnavailable without dereferencing null.
  • third_party/blink/renderer/modules/BUILD.gn — Adds availability_test.cc to the build; test-only.

Background

Built-In AI APIs — Blink web-platform APIs (LanguageModel, Translator, language detection) exposed to script that asynchronously query on-device model availability.

ExecutionContext — Blink object representing a document/worker global; it can be torn down while async callbacks are still outstanding, leaving dangling/null references.

AddConsoleMessage — ExecutionContext method that logs a developer-facing console warning; calling it on a null context dereferences null.

Vulnerability window

  1. Reachability — Reachable from ordinary web content in a build where the Built-In AI APIs are available, by calling an availability/create API from script.
  2. Trigger — The context is destroyed (e.g. iframe/document removal or navigation) after the availability check begins but before its async result returns kUnavailable.
  3. Primitive — The completion handler dereferences a null execution_context in AddConsoleMessage(), producing a null-pointer crash in the renderer.
  4. Escalation — No escalation beyond renderer-process crash/DoS; not a memory-corruption primitive (inferred).

Proof of concept

Conceptually: from a sub-frame, invoke a Built-In AI availability check that will resolve to unavailable, then synchronously remove/navigate the frame so its ExecutionContext is destroyed before the async callback runs; the warning-logging path then dereferences the now-null context. Timing-dependent and crash-only.

Exploitation

  1. Setup — Script in a frame calls a Built-In AI availability/create API expected to return unavailable.
  2. Teardown race — The frame’s execution context is destroyed before the async result arrives (inferred timing window).
  3. Crash — AddConsoleMessage() on the null context crashes the renderer (denial of service).

Detection & hunting

For defenders and detection engineers:

  • grep for execution_context->AddConsoleMessage( in async/callback paths without a preceding null check — Audit availability/completion handlers that capture an ExecutionContext across an async boundary.
  • Crash reports: null-deref in blink::HandleModelAvailabilityCheckResult / availability.cc — Correlate renderer crashes with AI API usage and context destruction.

Audit directions

  • modules/ai Handle*AvailabilityCheckResult family (Translator, language detection) — Verify each callback null-checks execution_context before use, since all were exported together.
  • Other Blink async mojo callbacks that touch ExecutionContext — Look for use of a captured ExecutionContext pointer after a potential context teardown.

Before / after

Loading diff…