Overview

Critical
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in Fullscreen
DescriptionUse after free in Fullscreen
ComponentFullscreen
Bug ClassUAF
Tracker523119897
Fix commit3c800c80b475 (chromium/src) +5/-0
CISA KEVNot listed
CreditedGoogle
Disclosed2026-06-30

Changed Functions

FunctionChangeNotes
if
chrome/browser/ui/android/exclusive_access/exclusive_access_manager_android.cc
modified

Files Changed

  • chrome/browser/ui/android/exclusive_access/exclusive_access_manager_android.cc
From 3c800c80b475241ebb081b77f401c49c0b3e1a84 Mon Sep 17 00:00:00 2001
From: Muyao Xu <muyaoxu@google.com>
Date: Mon, 15 Jun 2026 17:28:58 -0700
Subject: [PATCH] [Fullscreen] Fix potential UaF in ExclusiveAccessManagerAndroid

This CL ensures the Java layer is notified when the C++ object is
destroyed.

Bug: 523119897
Change-Id: Iceb87e1d207251957346627ef82b0f500531db53
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7947577
Commit-Queue: Muyao Xu <muyaoxu@google.com>
Reviewed-by: Mike Wasserman <msw@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1647206}
---

diff --git a/chrome/browser/ui/android/exclusive_access/exclusive_access_manager_android.cc b/chrome/browser/ui/android/exclusive_access/exclusive_access_manager_android.cc
index c4ac856..de667dd 100644
--- a/chrome/browser/ui/android/exclusive_access/exclusive_access_manager_android.cc
+++ b/chrome/browser/ui/android/exclusive_access/exclusive_access_manager_android.cc
@@ -163,6 +163,11 @@
 }
 
 void ExclusiveAccessManagerAndroid::Destroy(JNIEnv* env) {
+  if (eac_) {
+    // Notify the Java counterpart to drop its native pointer before
+    // the C++ object is destroyed, preventing a use-after-free.
+    eac_->Destroy(env);
+  }
   delete this;
 }
 
Loading diff…

Original Bug Report

reported by rj...@google.com

Potential Use-After-Free in ExclusiveAccessContextAndroid during tab reparenting

Flapjack, an experimental security project, has identified the following potential security issue. If you’re a feature owner CC-ed on this bug, please do your best to review these reports. Please see https://chromium.googlesource.com/chromium/src/+/main/docs/security/ai-generated-security-bugs-faq.md for more information.

Overview: A potential Use-After-Free vulnerability exists in the Android Browser process due to incomplete JNI lifecycle synchronization. When ExclusiveAccessManagerAndroid is destroyed, its associated ExclusiveAccessContextAndroid is freed but fails to nullify its Java counterpart’s native pointer. Subsequent touch events on a surviving Tab can trigger JNI calls using this dangling pointer.

Affected files:

  • chrome/browser/ui/android/exclusive_access/exclusive_access_context_android.cc
  • chrome/android/java/src/org/chromium/chrome/browser/ui/ExclusiveAccessContext.java
  • chrome/browser/ui/android/exclusive_access/exclusive_access_manager_android.cc

Estimated timestamp from git blame: 2026-05-20

Summary

A potential Use-After-Free (UAF) vulnerability exists in the Android implementation of ExclusiveAccessContextAndroid. When the ExclusiveAccessManagerAndroid is destroyed (e.g., during Activity teardown), it frees its ExclusiveAccessContextAndroid member. However, it fails to invoke the Destroy(JNIEnv*) method to notify the Java layer. Consequently, the Java ExclusiveAccessContext retains a dangling pointer to the freed C++ memory and leaks an ActivityTabTabObserver attached to the current Tab.

Because Tab objects frequently outlive the Activity (such as during screen rotation, multi-window moves, or tab reparenting), the leaked observer remains active. If the user touches the preserved tab, the observer’s onTouchDown() callback fires and makes a JNI call (onExclusiveAccessUserInput) using the dangling pointer, resulting in a UAF in the privileged Browser process.

Potential Trigger Steps

Note: These are suggested steps based on code analysis; our tooling agent does not have the ability to run a working Proof of Concept (PoC).

  1. An attacker hosts a malicious webpage and entices a user to visit it.
  2. The webpage requests fullscreen mode (document.documentElement.requestFullscreen()), triggering the creation of the Java ExclusiveAccessManager and its C++ counterparts.
  3. During initialization, a raw C++ pointer is passed to Java as a jlong (mNativeExclusiveAccessContextAndroid), and an ActivityTabTabObserver is registered on the active Tab.
  4. The attacker triggers a configuration change or tab reparenting event that causes the current Activity to be destroyed while preserving the Tab.
  5. ExclusiveAccessManagerAndroid::Destroy deletes itself and its std::unique_ptr<ExclusiveAccessContextAndroid> eac_, freeing the C++ context. However, it misses a call to eac_->Destroy(env).
  6. The Java ExclusiveAccessContext.destroy() is never called. The mNativeExclusiveAccessContextAndroid pointer remains non-zero, and the observer is never unregistered from the Tab.
  7. The attacker uses JavaScript in the surviving Tab to perform heap grooming, replacing the freed ExclusiveAccessContextAndroid with attacker-controlled data.
  8. The attacker prompts the user to interact with the webpage (e.g., touching a button).
  9. The touch event triggers onTouchDown() on the leaked Java observer, which makes a JNI call using the dangling pointer.
  10. The JNI wrapper casts the jlong to a raw C++ pointer and calls ExclusiveAccessContextAndroid::OnExclusiveAccessUserInput(JNIEnv*).
  11. The method accesses the attacker-forged object, dereferences its exclusive_access_bubble_ pointer, and calls the virtual method Show(), allowing the attacker to hijack the vtable and achieve Remote Code Execution (RCE).

Impact

This vulnerability allows for arbitrary Remote Code Execution (RCE) in the privileged Browser process, effectively bypassing the sandbox. MiraclePtr (BackupRefPtr) does not protect against this UAF because the reference crossing the JNI boundary is held as a primitive jlong rather than a raw_ptr, and the C++ side drops all raw_ptr references upon destruction, allowing PartitionAlloc to fully free the memory.

Suggested Fix

Explicitly invoke the Destroy method on the ExclusiveAccessContextAndroid object before it is deleted.

In chrome/browser/ui/android/exclusive_access/exclusive_access_manager_android.cc:

void ExclusiveAccessManagerAndroid::Destroy(JNIEnv* env) {
  if (eac_) {
    eac_->Destroy(env);
  }
  delete this;
}

Alternatively, call Destroy() from within ExclusiveAccessContextAndroid::~ExclusiveAccessContextAndroid(), but ensure a valid JNIEnv is correctly attached or retrieved.

Evaluated with Chrome root at commit: 2155cb00003ec35716a76ed3246eae995f87b7ff


Results so far have been promising, but there can be wrong deductions. Feel free to adjust as follows:

  • If you are familiar with the severity guidelines, you may adjust the severity.
  • If this is a false positive, and there’s no work to be done, please close as WAI.
  • If there is work to do here but not a vulnerability, please change the issue type to Task/Bug/FR.

Data from false positives will be used to improve accuracy over time. And please feel free to reach out to me directly if you have concerns or feedback on the project.

View on issue tracker