diff options
author | Shu-yu Guo <syg@chromium.org> | 2022-05-03 13:26:32 -0700 |
---|---|---|
committer | Michael Brüning <michael.bruning@qt.io> | 2022-07-25 16:38:19 +0000 |
commit | 534bb1ef422f31aaab817bde5908370efaae5083 (patch) | |
tree | b092e85c25f5438527a0868ad28a11a4a360b4db /chromium | |
parent | 39847ddc5cf40b0a1cfa1f00b304c71e0462a6ee (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.cc | 4 | ||||
-rw-r--r-- | chromium/v8/src/objects/js-weak-refs-inl.h | 21 | ||||
-rw-r--r-- | chromium/v8/src/objects/js-weak-refs.h | 8 |
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. |