summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShu-yu Guo <syg@chromium.org>2022-05-03 13:26:32 -0700
committerMichael Brüning <michael.bruning@qt.io>2022-07-25 14:22:46 +0000
commitaab054ee7160f3eca2e0c33fe7d617660e945fba (patch)
tree6d3ba1531b552a86116961d87b60e25bf41d62ee
parent95bda789ea62fe9ef2aeff10ab0aa4b81ed8e718 (diff)
downloadqtwebengine-chromium-aab054ee7160f3eca2e0c33fe7d617660e945fba.tar.gz
[Backport] CVE-2022-2158: Type Confusion in V8
Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/v8/v8/+/3676863: Set unregister_token to undefined when unregistering (cherry picked from commit dd3289d7945dac855d1287cf4ea248883e908d54) Bug: chromium:1321078 No-Try: true No-Presubmit: true No-Tree-Checks: true Change-Id: I426327ffc3d7eebdb562c01a87039a93dfb79a88 Commit-Queue: Shu-yu Guo <syg@chromium.org> Cr-Original-Commit-Position: refs/heads/main@{#80349} Reviewed-by: Dominik Inführ <dinfuehr@chromium.org> Commit-Queue: Roger Felipe Zanoni da Silva <rzanoni@google.com> Reviewed-by: Victor-Gabriel Savu <vsavu@google.com> Cr-Commit-Position: refs/branch-heads/9.6@{#68} Cr-Branched-From: 0b7bda016178bf438f09b3c93da572ae3663a1f7-refs/heads/9.6.180@{#1} Cr-Branched-From: 41a5a247d9430b953e38631e88d17790306f7a4c-refs/heads/main@{#77244} Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--chromium/v8/src/heap/mark-compact.cc5
-rw-r--r--chromium/v8/src/objects/js-weak-refs-inl.h21
-rw-r--r--chromium/v8/src/objects/js-weak-refs.h8
-rw-r--r--chromium/v8/src/objects/objects.cc2
4 files changed, 22 insertions, 14 deletions
diff --git a/chromium/v8/src/heap/mark-compact.cc b/chromium/v8/src/heap/mark-compact.cc
index 0fffb4ea458..a284c11fb62 100644
--- a/chromium/v8/src/heap/mark-compact.cc
+++ b/chromium/v8/src/heap/mark-compact.cc
@@ -2747,14 +2747,11 @@ void MarkCompactCollector::ClearJSWeakRefs() {
// unregister_token field set to undefined when processing the first
// WeakCell. Like above, we're modifying pointers during GC, so record the
// slots.
- HeapObject undefined = ReadOnlyRoots(isolate()).undefined_value();
JSFinalizationRegistry finalization_registry =
JSFinalizationRegistry::cast(weak_cell.finalization_registry());
finalization_registry.RemoveUnregisterToken(
JSReceiver::cast(unregister_token), isolate(),
- [undefined](WeakCell matched_cell) {
- matched_cell.set_unregister_token(undefined);
- },
+ JSFinalizationRegistry::kKeepMatchedCellsInRegistry,
gc_notify_updated_slot);
} else {
// The unregister_token is alive.
diff --git a/chromium/v8/src/objects/js-weak-refs-inl.h b/chromium/v8/src/objects/js-weak-refs-inl.h
index 13ac175cf6e..0e39b00d135 100644
--- a/chromium/v8/src/objects/js-weak-refs-inl.h
+++ b/chromium/v8/src/objects/js-weak-refs-inl.h
@@ -71,16 +71,14 @@ bool JSFinalizationRegistry::Unregister(
// key. Each WeakCell will be in the "active_cells" or "cleared_cells" list of
// its FinalizationRegistry; remove it from there.
return finalization_registry->RemoveUnregisterToken(
- *unregister_token, isolate,
- [isolate](WeakCell matched_cell) {
- matched_cell.RemoveFromFinalizationRegistryCells(isolate);
- },
+ *unregister_token, isolate, kRemoveMatchedCellsFromRegistry,
[](HeapObject, ObjectSlot, Object) {});
}
-template <typename MatchCallback, typename GCNotifyUpdatedSlotCallback>
+template <typename GCNotifyUpdatedSlotCallback>
bool JSFinalizationRegistry::RemoveUnregisterToken(
- JSReceiver unregister_token, Isolate* isolate, MatchCallback match_callback,
+ JSReceiver unregister_token, Isolate* isolate,
+ RemoveUnregisterTokenMode removal_mode,
GCNotifyUpdatedSlotCallback gc_notify_updated_slot) {
// This method is called from both FinalizationRegistry#unregister and for
// removing weakly-held dead unregister tokens. The latter is during GC so
@@ -118,7 +116,16 @@ bool JSFinalizationRegistry::RemoveUnregisterToken(
value = weak_cell.key_list_next();
if (weak_cell.unregister_token() == unregister_token) {
// weak_cell has the same unregister token; remove it from the key list.
- match_callback(weak_cell);
+ switch (removal_mode) {
+ case kRemoveMatchedCellsFromRegistry:
+ weak_cell.RemoveFromFinalizationRegistryCells(isolate);
+ break;
+ case kKeepMatchedCellsInRegistry:
+ // Do nothing.
+ break;
+ }
+ // Clear unregister token-related fields.
+ weak_cell.set_unregister_token(undefined);
weak_cell.set_key_list_prev(undefined);
weak_cell.set_key_list_next(undefined);
was_present = true;
diff --git a/chromium/v8/src/objects/js-weak-refs.h b/chromium/v8/src/objects/js-weak-refs.h
index 250186e7bef..88361ad1c05 100644
--- a/chromium/v8/src/objects/js-weak-refs.h
+++ b/chromium/v8/src/objects/js-weak-refs.h
@@ -53,10 +53,14 @@ class JSFinalizationRegistry : public JSObject {
// it modifies slots in key_map and WeakCells and the normal write barrier is
// disabled during GC, we need to tell the GC about the modified slots via the
// gc_notify_updated_slot function.
- template <typename MatchCallback, typename GCNotifyUpdatedSlotCallback>
+ enum RemoveUnregisterTokenMode {
+ kRemoveMatchedCellsFromRegistry,
+ kKeepMatchedCellsInRegistry
+ };
+ template <typename GCNotifyUpdatedSlotCallback>
inline bool RemoveUnregisterToken(
JSReceiver unregister_token, Isolate* isolate,
- MatchCallback match_callback,
+ RemoveUnregisterTokenMode removal_mode,
GCNotifyUpdatedSlotCallback gc_notify_updated_slot);
// Returns true if the cleared_cells list is non-empty.
diff --git a/chromium/v8/src/objects/objects.cc b/chromium/v8/src/objects/objects.cc
index 99e9ccad058..2bbd2337b18 100644
--- a/chromium/v8/src/objects/objects.cc
+++ b/chromium/v8/src/objects/objects.cc
@@ -6876,7 +6876,7 @@ void JSFinalizationRegistry::RemoveCellFromUnregisterTokenMap(
}
// weak_cell is now removed from the unregister token map, so clear its
- // unregister token-related fields for heap verification.
+ // unregister token-related fields.
weak_cell.set_unregister_token(undefined);
weak_cell.set_key_list_prev(undefined);
weak_cell.set_key_list_next(undefined);