High chrome UAF 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
ImpactUse after free in Google Lens
DescriptionUse after free in Google Lens
ComponentGoogle Lens
Bug ClassUAF
Tracker498322453
Fix commit4af1bce9f2ec (chromium/src) +11/-9
CISA KEVNot listed
CreditedGoogle
Disclosed2026-05-12

Files Changed

  • chrome/browser/ui/lens/lens_overlay_query_controller.cc
  • chrome/browser/ui/lens/lens_overlay_query_controller.h
From 4af1bce9f2ecb4ad514d3fc4e3f170f707180ced Mon Sep 17 00:00:00 2001
From: Duncan Mercer <mercerd@google.com>
Date: Thu, 02 Apr 2026 12:29:55 -0700
Subject: [PATCH] [Lens Overlay] Fix Use-After-Free in query controller

Pass PageContent by value to background threads to ensure lifetime
safety. Also fix task cancellation bypass and state reset.

Fixed: 498322453
Change-Id: If2282782cf97630604f5e6220666035f0294c989
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7723469
Reviewed-by: Juan Mojica <juanmojica@google.com>
Commit-Queue: Duncan Mercer <mercerd@google.com>
Cr-Commit-Position: refs/heads/main@{#1609432}
---

diff --git a/chrome/browser/ui/lens/lens_overlay_query_controller.cc b/chrome/browser/ui/lens/lens_overlay_query_controller.cc
index 24a417ab..789cffd0 100644
--- a/chrome/browser/ui/lens/lens_overlay_query_controller.cc
+++ b/chrome/browser/ui/lens/lens_overlay_query_controller.cc
@@ -297,7 +297,6 @@
 // Returns the lens::Payload to be sent after uploading chunked data using the
 // repeated Content field instead of the deprecated payload fields.
 lens::Payload CreatePageContentPayloadForChunks(
-    base::span<const lens::PageContent> page_content,
     lens::MimeType primary_content_type,
     GURL page_url,
     std::optional<std::string> page_title,
@@ -328,7 +327,7 @@
 // Returns the lens::Payload using the repeated Content field instead of the
 // deprecated payload fields.
 lens::Payload CreatePageContentPayload(
-    base::span<const lens::PageContent> page_contents,
+    std::vector<lens::PageContent> page_contents,
     GURL page_url,
     std::optional<std::string> page_title) {
   lens::Payload payload;
@@ -505,6 +504,7 @@
   page_url_ = GURL();
   page_title_ = std::nullopt;
   partial_content_ = base::span<const std::u16string>();
+  page_content_request_in_progress_ = false;
 }
 
 void LensOverlayQueryController::SendUpdatedPageContent(
@@ -1270,13 +1270,13 @@
     return;
   }
 
+  compression_task_tracker_->TryCancelAll();
+
   if (underlying_page_contents_.empty() ||
       underlying_page_contents_.front().bytes_.empty()) {
     //  No need to send the request without underlying content bytes.
     return;
   }
-
-  compression_task_tracker_->TryCancelAll();
   page_contents_request_start_time_ = base::TimeTicks::Now();
   page_content_request_in_progress_ = true;
   chunk_upload_in_progress_ = false;
@@ -1318,9 +1318,11 @@
   } else {
     // Post CreatePageContentPayload to a task off the main thread so
     // compression does not throttle the main thread.
+    std::vector<lens::PageContent> contents_copy(
+        underlying_page_contents_.begin(), underlying_page_contents_.end());
     compression_task_tracker_->PostTaskAndReplyWithResult(
         compression_task_runner_.get(), FROM_HERE,
-        base::BindOnce(&CreatePageContentPayload, underlying_page_contents_,
+        base::BindOnce(&CreatePageContentPayload, std::move(contents_copy),
                        page_url_, page_title_),
         base::BindOnce(
             &LensOverlayQueryController::PrepareAndFetchPageContentRequestPart2,
@@ -1416,9 +1418,8 @@
     base::SequencedTaskRunner::GetCurrentDefault()->PostTaskAndReplyWithResult(
         FROM_HERE,
         base::BindOnce(&CreatePageContentPayloadForChunks,
-                       underlying_page_contents_, primary_content_type_,
-                       page_url_, page_title_, total_chunks,
-                       retrying_page_content_upload_),
+                       primary_content_type_, page_url_, page_title_,
+                       total_chunks, retrying_page_content_upload_),
         base::BindOnce(
             &LensOverlayQueryController::PrepareAndFetchPageContentRequestPart2,
             weak_ptr_factory_.GetWeakPtr(), request_id));
diff --git a/chrome/browser/ui/lens/lens_overlay_query_controller.h b/chrome/browser/ui/lens/lens_overlay_query_controller.h
index 20302998..a9877b2 100644
--- a/chrome/browser/ui/lens/lens_overlay_query_controller.h
+++ b/chrome/browser/ui/lens/lens_overlay_query_controller.h
@@ -199,7 +199,8 @@
       lens::mojom::SemanticEvent event);
 
   bool IsPageContentUploadInProgress() const {
-    return page_content_endpoint_fetcher_.get() != nullptr;
+    return page_content_request_in_progress_ ||
+           page_content_endpoint_fetcher_.get() != nullptr;
   }
 
   // Returns whether the query controller is off.
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.