Chrome · Mojo
CVE-2026-8580
UAF in Mojo
Overview
Medium
Severity
9.6
CVSS
No
Exploited ITW
Fixed
Fix Status
Background
- `WatcherImpl`
- the Android/JNI-backed C++ class (in the anonymous namespace of
watcher_impl.cc) that wraps amojo::SimpleWatcherto watch a Mojo handle and deliver readiness notifications back to Java. - `SimpleWatcher`
- the Mojo utility that observes a handle and invokes a bound callback when the handle’s signals change, used by
WatcherImplvia itswatcher_member. - `ADVANCED_MEMORY_SAFETY_CHECKS()` (AMSC)
- a class-scope macro (from
base/memory/advanced_memory_safety_checks.h) that routes allocations of the annotated type through PartitionAlloc’s advanced memory-safety checks, turning certain use-after-free/overflow conditions into detectable, mitigated faults. - Use-after-free
- accessing an object (here a
WatcherImpl) after it has been freed, typically via a callback or notification that outlives the object’s lifetime.
Root Cause Analysis
The patch adds
#include "base/memory/advanced_memory_safety_checks.h" and places the ADVANCED_MEMORY_SAFETY_CHECKS() macro inside the WatcherImpl class declaration, with a TODO(https://crbug.com/496639647): Remove this macro. comment. It does not alter any function body, branch, check, or lifetime-management logic in watcher_impl.cc, so the exact sequence that leaves a WatcherImpl dangling — the root-cause use-after-free — is not visible in this diff. The change is a defense-in-depth hardening measure: by opting WatcherImpl into PartitionAlloc’s advanced checks, a use-after-free on a freed WatcherImpl instance is made far more likely to be caught/mitigated rather than silently exploitable. The TODO to later remove the macro signals this is a stopgap applied ahead of a proper lifetime fix, consistent with the advisory describing a use-after-free in Mojo. This neither tightens nor relaxes a validation check; it changes how the type is allocated.Key insight
The single change is a class-scope allocator hardening annotation, not a logic correction:
ADVANCED_MEMORY_SAFETY_CHECKS() mitigates exploitation of a use-after-free on WatcherImpl without the diff revealing where the dangling reference originates.Attack Path
- Set up a watch
Java code uses the Mojo system API to create a watcher, instantiating a
WatcherImplthat registers itswatcher_(SimpleWatcher) on a Mojo handle on Android. - Destroy the watcher while work is pending
Through the Java/JNI lifecycle, the
WatcherImplis freed while a handle-readiness notification or bound callback referencing it is still outstanding(inferred), since the diff does not show the precise ordering that frees the object. - Dangling access
The pending notification/callback dereferences the freed
WatcherImpl, producing the use-after-free the advisory describes. - Mitigation engages
Post-patch,
WatcherImplallocations go through PartitionAlloc’s advanced memory-safety checks, so such an access is intended to fault/be mitigated rather than yield a usable primitive(inferred).
Impact Assessment
The bug is a use-after-free of a
WatcherImpl object on Android, in whichever process hosts the Mojo Java system bindings for the watched handle; the vendor advisory rates it medium severity and does not report in-the-wild exploitation. This patch only applies a hardening mitigation (ADVANCED_MEMORY_SAFETY_CHECKS()), so the preconditions for triggering the free, whether a compromised renderer is required, and any escalation to a read/write primitive or code execution are not established by the diff and are (inferred).Changed Functions
| Function | Change | Notes |
|---|---|---|
WatcherImplmojo/public/java/system/watcher_impl.cc |
modified |
Files Changed
mojo/public/java/system/watcher_impl.cc
Audit Directions
- Callback outliving ownerReview Mojo watcher/observer wrappers (especially JNI-bridged ones) for objects whose
SimpleWatchercallback or posted task can fire after the wrapper is destroyed; confirm callbacks are bound weakly or cancelled on teardown. - Hardening-as-fix markersTreat
ADVANCED_MEMORY_SAFETY_CHECKS()additions with aTODO: Remove this macroas flags for an unresolved lifetime bug; track the referenced bug for the eventual root-cause fix and audit sibling classes for the same pattern. - Cross-language lifetime boundariesScrutinize Android Java↔C++ Mojo bindings where object destruction is driven from the Java side while native callbacks remain registered, a common source of use-after-free.
Patch
From 57fbced46b4bb4ffb3c938e335e027427e0c1203 Mon Sep 17 00:00:00 2001
From: mikt <mikt@google.com>
Date: Tue, 31 Mar 2026 00:16:30 -0700
Subject: [PATCH] Add AMSC macro to mojo::android::WatcherImpl
Bug: 496639647
Change-Id: Ifdd8dea7702b6639a8d4f9701e9e8f155a52c492
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7707718
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
Commit-Queue: Mikihito Matsuura <mikt@google.com>
Cr-Commit-Position: refs/heads/main@{#1607682}
---
diff --git a/mojo/public/java/system/watcher_impl.cc b/mojo/public/java/system/watcher_impl.cc
index caed52da..fde62e8 100644
--- a/mojo/public/java/system/watcher_impl.cc
+++ b/mojo/public/java/system/watcher_impl.cc
@@ -8,6 +8,7 @@
#include "base/android/jni_android.h"
#include "base/android/scoped_java_ref.h"
#include "base/functional/bind.h"
+#include "base/memory/advanced_memory_safety_checks.h"
#include "base/task/sequenced_task_runner.h"
#include "mojo/public/cpp/system/handle.h"
#include "mojo/public/cpp/system/simple_watcher.h"
@@ -23,6 +24,9 @@
namespace {
class WatcherImpl {
+ // TODO(https://crbug.com/496639647): Remove this macro.
+ ADVANCED_MEMORY_SAFETY_CHECKS();
+
public:
WatcherImpl()
: watcher_(FROM_HERE,
Loading diff…
Original Bug Report
The reporter's bug is still restricted on the tracker. Chrome de-restricts security bugs ~30–90 days after the fix ships; a later run will backfill it here.
References
On This Page