Skip to content

Commit 19b53b4

Browse files
GeorgNeismibrunin
authored andcommitted
[Backport] CVE-2021-21231: Insufficient data validation in V8
Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/v8/v8/+/2833911: Merged: [turbofan] Harden ArrayPrototypePop and ArrayPrototypeShift Revision: d4aafa4022b718596b3deadcc3cdcb9209896154 [email protected] BUG=chromium:1198696 NOTRY=true NOPRESUBMIT=true NOTREECHECKS=true Change-Id: I1840ffabbed3a3caab75b0abea1d37d9ed446d3f Reviewed-by: Georg Neis <[email protected]> Commit-Queue: Georg Neis <[email protected]> Cr-Commit-Position: refs/branch-heads/9.0@{#39} Cr-Branched-From: bd0108b4c88e0d6f2350cb79b5f363fbd02f3eb7-refs/heads/9.0.257@{#1} Cr-Branched-From: 349bcc6a075411f1a7ce2d866c3dfeefc2efa39d-refs/heads/master@{#73001} Reviewed-by: Allan Sandfeld Jensen <[email protected]>
1 parent a2df831 commit 19b53b4

File tree

1 file changed

+24
-9
lines changed

1 file changed

+24
-9
lines changed

chromium/v8/src/compiler/js-call-reducer.cc

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5251,24 +5251,31 @@ Reduction JSCallReducer::ReduceArrayPrototypePop(Node* node) {
52515251
}
52525252

52535253
// Compute the new {length}.
5254-
length = graph()->NewNode(simplified()->NumberSubtract(), length,
5255-
jsgraph()->OneConstant());
5254+
Node* new_length = graph()->NewNode(simplified()->NumberSubtract(),
5255+
length, jsgraph()->OneConstant());
5256+
5257+
// This extra check exists solely to break an exploitation technique
5258+
// that abuses typer mismatches.
5259+
new_length = efalse = graph()->NewNode(
5260+
simplified()->CheckBounds(p.feedback(),
5261+
CheckBoundsFlag::kAbortOnOutOfBounds),
5262+
new_length, length, efalse, if_false);
52565263

52575264
// Store the new {length} to the {receiver}.
52585265
efalse = graph()->NewNode(
52595266
simplified()->StoreField(AccessBuilder::ForJSArrayLength(kind)),
5260-
receiver, length, efalse, if_false);
5267+
receiver, new_length, efalse, if_false);
52615268

52625269
// Load the last entry from the {elements}.
52635270
vfalse = efalse = graph()->NewNode(
52645271
simplified()->LoadElement(AccessBuilder::ForFixedArrayElement(kind)),
5265-
elements, length, efalse, if_false);
5272+
elements, new_length, efalse, if_false);
52665273

52675274
// Store a hole to the element we just removed from the {receiver}.
52685275
efalse = graph()->NewNode(
52695276
simplified()->StoreElement(
52705277
AccessBuilder::ForFixedArrayElement(GetHoleyElementsKind(kind))),
5271-
elements, length, jsgraph()->TheHoleConstant(), efalse, if_false);
5278+
elements, new_length, jsgraph()->TheHoleConstant(), efalse, if_false);
52725279
}
52735280

52745281
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
@@ -5444,19 +5451,27 @@ Reduction JSCallReducer::ReduceArrayPrototypeShift(Node* node) {
54445451
}
54455452

54465453
// Compute the new {length}.
5447-
length = graph()->NewNode(simplified()->NumberSubtract(), length,
5448-
jsgraph()->OneConstant());
5454+
Node* new_length = graph()->NewNode(simplified()->NumberSubtract(),
5455+
length, jsgraph()->OneConstant());
5456+
5457+
// This extra check exists solely to break an exploitation technique
5458+
// that abuses typer mismatches.
5459+
new_length = etrue1 = graph()->NewNode(
5460+
simplified()->CheckBounds(p.feedback(),
5461+
CheckBoundsFlag::kAbortOnOutOfBounds),
5462+
new_length, length, etrue1, if_true1);
54495463

54505464
// Store the new {length} to the {receiver}.
54515465
etrue1 = graph()->NewNode(
54525466
simplified()->StoreField(AccessBuilder::ForJSArrayLength(kind)),
5453-
receiver, length, etrue1, if_true1);
5467+
receiver, new_length, etrue1, if_true1);
54545468

54555469
// Store a hole to the element we just removed from the {receiver}.
54565470
etrue1 = graph()->NewNode(
54575471
simplified()->StoreElement(AccessBuilder::ForFixedArrayElement(
54585472
GetHoleyElementsKind(kind))),
5459-
elements, length, jsgraph()->TheHoleConstant(), etrue1, if_true1);
5473+
elements, new_length, jsgraph()->TheHoleConstant(), etrue1,
5474+
if_true1);
54605475
}
54615476

54625477
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);

0 commit comments

Comments
 (0)