From 44b99db9f0da74490999ab2ab79e074efb86b1f3 Mon Sep 17 00:00:00 2001 From: Darius Mercadier Date: Fri, 22 Mar 2024 17:55:04 +0100 Subject: [PATCH] [Backport] CVE-2024-3159: Out of bounds memory access in V8 Manual cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/v8/v8/+/5401859: Merged: [runtime] Recreate enum cache on map update if any previous map had one If any previous map in the transition tree had an enum cache, then we recreate one when updating the map. Bug: 330760873 (cherry picked from commit 807cf7d0b7d96212c98ed2119e07f9b2c6a23f61) Change-Id: Ia9ea4cf17fef60166a0c037318eb539866aac37a Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5401859 Reviewed-by: Igor Sheludko Commit-Queue: Igor Sheludko Auto-Submit: Darius Mercadier Cr-Commit-Position: refs/branch-heads/12.2@{#52} Cr-Branched-From: 6eb5a9616aa6f8c705217aeb7c7ab8c037a2f676-refs/heads/12.2.281@{#1} Cr-Branched-From: 44cf56d850167c6988522f8981730462abc04bcc-refs/heads/main@{#91934} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/553302 Reviewed-by: Michal Klocek --- chromium/v8/src/objects/map-updater.cc | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/chromium/v8/src/objects/map-updater.cc b/chromium/v8/src/objects/map-updater.cc index 2ebfc84d3e3..489a2a613d0 100644 --- a/chromium/v8/src/objects/map-updater.cc +++ b/chromium/v8/src/objects/map-updater.cc @@ -1031,14 +1031,21 @@ MapUpdater::State MapUpdater::ConstructNewMap() { Handle new_map = Map::AddMissingTransitions(isolate_, split_map, new_descriptors); + bool had_any_enum_cache = + split_map->instance_descriptors(isolate_) + .enum_cache() + .keys() + .length() > 0 || + old_descriptors_->enum_cache().keys().length() > 0; + // Deprecated part of the transition tree is no longer reachable, so replace // current instance descriptors in the "survived" part of the tree with // the new descriptors to maintain descriptors sharing invariant. split_map->ReplaceDescriptors(isolate_, *new_descriptors); - // If the old descriptors had an enum cache, make sure the new ones do too. - if (old_descriptors_->enum_cache().keys().length() > 0 && - new_map->NumberOfEnumerableProperties() > 0) { + // If the old descriptors had an enum cache (or if {split_map}'s descriptors + // had one), make sure the new ones do too. + if (had_any_enum_cache && new_map->NumberOfEnumerableProperties() > 0) { FastKeyAccumulator::InitializeFastPropertyEnumCache( isolate_, new_map, new_map->NumberOfEnumerableProperties()); }