summaryrefslogtreecommitdiffstats
path: root/chromium
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 16:38:19 +0000
commit534bb1ef422f31aaab817bde5908370efaae5083 (patch)
treeb092e85c25f5438527a0868ad28a11a4a360b4db /chromium
parent39847ddc5cf40b0a1cfa1f00b304c71e0462a6ee (diff)
[Backport] CVE-2022-2158: Type Confusion in V8
Manual backport of patch originally reviewed on https://chromium-review.googlesource.com/c/v8/v8/+/3676863: [M96-LTS][weakrefs] 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>
Diffstat (limited to 'chromium')
-rw-r--r--chromium/v8/src/heap/mark-compact.cc4
-rw-r--r--chromium/v8/src/objects/js-weak-refs-inl.h21
-rw-r--r--chromium/v8/src/objects/js-weak-refs.h8
3 files changed, 21 insertions, 12 deletions
diff --git a/chromium/v8/src/heap/mark-compact.cc b/chromium/v8/src/heap/mark-compact.cc
index d263a01c7db..e7b31f50e47 100644
--- a/chromium/v8/src/heap/mark-compact.cc
+++ b/chromium/v8/src/heap/mark-compact.cc
@@ -2571,9 +2571,7 @@ void MarkCompactCollector::ClearJSWeakRefs() {
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);
// The following is necessary because in the case that weak_cell has
// already been popped and removed from the FinalizationRegistry, the call
diff --git a/chromium/v8/src/objects/js-weak-refs-inl.h b/chromium/v8/src/objects/js-weak-refs-inl.h
index 8b1bb6eaec4..5313d742bd9 100644
--- a/chromium/v8/src/objects/js-weak-refs-inl.h
+++ b/chromium/v8/src/objects/js-weak-refs-inl.h
@@ -69,16 +69,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
@@ -116,7 +114,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 2aa0a4ff2db..d64f138435c 100644
--- a/chromium/v8/src/objects/js-weak-refs.h
+++ b/chromium/v8/src/objects/js-weak-refs.h
@@ -51,10 +51,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.