From 1b11c2dbe815ee240f4b16bdb61de089d8d9a549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marja=20H=C3=B6ltt=C3=A4?= Date: Tue, 14 Nov 2023 14:45:27 +0100 Subject: [PATCH] [Backport] CVE-2023-6702: Type Confusion in V8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Manual cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/v8/v8/+/5110982: Merged: [promises, async stack traces] Fix the case when the closure has run We were using the closure pointing to NativeContext as a marker that the closure has run, but async stack trace code was confused about it. (cherry picked from commit bde3d360097607f36cd1d17cbe8412b84eae0a7f) Bug: chromium:1501326 Change-Id: I30d438f3b2e3fdd7562ea9a79dde4561ce9b0083 Cr-Original-Commit-Position: refs/heads/main@{#90949} Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5110982 Commit-Queue: Marja Hölttä Reviewed-by: Shu-yu Guo Reviewed-by: Igor Sheludko Auto-Submit: Marja Hölttä Cr-Commit-Position: refs/branch-heads/12.0@{#18} Cr-Branched-From: ed7b4caf1fb8184ad9e24346c84424055d4d430a-refs/heads/12.0.267@{#1} Cr-Branched-From: 210e75b19db4352c9b78dce0bae11c2dc3077df4-refs/heads/main@{#90651} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/526277 Reviewed-by: Michal Klocek --- chromium/v8/src/execution/isolate.cc | 23 ++++++++++++++++++++--- 1 file changed, 20 insertions(+), 3 deletions(-) diff --git a/chromium/v8/src/execution/isolate.cc b/chromium/v8/src/execution/isolate.cc index e7232e5c1fd..71d8d64a682 100644 --- a/chromium/v8/src/execution/isolate.cc +++ b/chromium/v8/src/execution/isolate.cc @@ -1020,7 +1020,13 @@ void CaptureAsyncStackTrace(Isolate* isolate, Handle promise, isolate); builder->AppendPromiseCombinatorFrame(function, combinator); - // Now peak into the Promise.all() resolve element context to + if (IsNativeContext(*context)) { + // NativeContext is used as a marker that the closure was already + // called. We can't access the reject element context any more. + return; + } + + // Now peek into the Promise.all() resolve element context to // find the promise capability that's being resolved when all // the concurrent promises resolve. int const index = @@ -1039,7 +1045,13 @@ void CaptureAsyncStackTrace(Isolate* isolate, Handle promise, context->native_context()->promise_all_settled(), isolate); builder->AppendPromiseCombinatorFrame(function, combinator); - // Now peak into the Promise.allSettled() resolve element context to + if (IsNativeContext(*context)) { + // NativeContext is used as a marker that the closure was already + // called. We can't access the reject element context any more. + return; + } + + // Now peek into the Promise.allSettled() resolve element context to // find the promise capability that's being resolved when all // the concurrent promises resolve. int const index = @@ -1057,7 +1069,12 @@ void CaptureAsyncStackTrace(Isolate* isolate, Handle promise, isolate); builder->AppendPromiseCombinatorFrame(function, combinator); - // Now peak into the Promise.any() reject element context to + if (IsNativeContext(*context)) { + // NativeContext is used as a marker that the closure was already + // called. We can't access the reject element context any more. + return; + } + // Now peek into the Promise.any() reject element context to // find the promise capability that's being resolved when any of // the concurrent promises resolve. int const index = PromiseBuiltins::kPromiseAnyRejectElementCapabilitySlot;