7f42272d65321adc372880d6432abee8174c163f [M152] Built-In AI APIs: Check execution_context for console messaging
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— Addsexecution_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
- 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.
- Trigger — The context is destroyed (e.g. iframe/document removal or navigation) after the availability check begins but before its async result returns kUnavailable.
- Primitive — The completion handler dereferences a null execution_context in AddConsoleMessage(), producing a null-pointer crash in the renderer.
- 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
- Setup — Script in a frame calls a Built-In AI availability/create API expected to return unavailable.
- Teardown race — The frame’s execution context is destroyed before the async result arrives (inferred timing window).
- 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.