Commit 66c8de2c authored by Samuel Groß's avatar Samuel Groß Committed by V8 LUCI CQ

Harden Map.prototype.delete and related methods

These can be tricked into corrupting memory when an attacker can leak
the "hole" value due to a bug. This CL simply adds CHECKs to prevent
this. A longer-term solution might be to introduce "special-purpose
holes" so that a leaked "hole" value can no longer be used to confuse
unrelated code like the JSMap implementation because that would then use
a different "hole" value.

Bug: chromium:1315901
Change-Id: Id6c432d39fb97002fa67efe90d34014fc5408ba3
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3593783Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Samuel Groß <saelo@chromium.org>
Cr-Commit-Position: refs/heads/main@{#80201}
parent dbff3045
...@@ -1762,6 +1762,9 @@ TF_BUILTIN(MapPrototypeDelete, CollectionsBuiltinsAssembler) { ...@@ -1762,6 +1762,9 @@ TF_BUILTIN(MapPrototypeDelete, CollectionsBuiltinsAssembler) {
ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE,
"Map.prototype.delete"); "Map.prototype.delete");
// This check breaks a known exploitation technique. See crbug.com/1263462
CSA_CHECK(this, TaggedNotEqual(key, TheHoleConstant()));
const TNode<OrderedHashMap> table = const TNode<OrderedHashMap> table =
LoadObjectField<OrderedHashMap>(CAST(receiver), JSMap::kTableOffset); LoadObjectField<OrderedHashMap>(CAST(receiver), JSMap::kTableOffset);
...@@ -1930,6 +1933,9 @@ TF_BUILTIN(SetPrototypeDelete, CollectionsBuiltinsAssembler) { ...@@ -1930,6 +1933,9 @@ TF_BUILTIN(SetPrototypeDelete, CollectionsBuiltinsAssembler) {
ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE, ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE,
"Set.prototype.delete"); "Set.prototype.delete");
// This check breaks a known exploitation technique. See crbug.com/1263462
CSA_CHECK(this, TaggedNotEqual(key, TheHoleConstant()));
const TNode<OrderedHashSet> table = const TNode<OrderedHashSet> table =
LoadObjectField<OrderedHashSet>(CAST(receiver), JSMap::kTableOffset); LoadObjectField<OrderedHashSet>(CAST(receiver), JSMap::kTableOffset);
...@@ -2878,6 +2884,9 @@ TF_BUILTIN(WeakMapPrototypeDelete, CodeStubAssembler) { ...@@ -2878,6 +2884,9 @@ TF_BUILTIN(WeakMapPrototypeDelete, CodeStubAssembler) {
ThrowIfNotInstanceType(context, receiver, JS_WEAK_MAP_TYPE, ThrowIfNotInstanceType(context, receiver, JS_WEAK_MAP_TYPE,
"WeakMap.prototype.delete"); "WeakMap.prototype.delete");
// This check breaks a known exploitation technique. See crbug.com/1263462
CSA_CHECK(this, TaggedNotEqual(key, TheHoleConstant()));
Return(CallBuiltin(Builtin::kWeakCollectionDelete, context, receiver, key)); Return(CallBuiltin(Builtin::kWeakCollectionDelete, context, receiver, key));
} }
...@@ -2926,6 +2935,9 @@ TF_BUILTIN(WeakSetPrototypeDelete, CodeStubAssembler) { ...@@ -2926,6 +2935,9 @@ TF_BUILTIN(WeakSetPrototypeDelete, CodeStubAssembler) {
ThrowIfNotInstanceType(context, receiver, JS_WEAK_SET_TYPE, ThrowIfNotInstanceType(context, receiver, JS_WEAK_SET_TYPE,
"WeakSet.prototype.delete"); "WeakSet.prototype.delete");
// This check breaks a known exploitation technique. See crbug.com/1263462
CSA_CHECK(this, TaggedNotEqual(value, TheHoleConstant()));
Return(CallBuiltin(Builtin::kWeakCollectionDelete, context, receiver, value)); Return(CallBuiltin(Builtin::kWeakCollectionDelete, context, receiver, value));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment