Skip to content

Commit bda0039

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 7ee750f commit bda0039

File tree

1 file changed

+21
-9
lines changed

1 file changed

+21
-9
lines changed

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

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4513,24 +4513,30 @@ Reduction JSCallReducer::ReduceArrayPrototypePop(Node* node) {
45134513
}
45144514

45154515
// Compute the new {length}.
4516-
length = graph()->NewNode(simplified()->NumberSubtract(), length,
4517-
jsgraph()->OneConstant());
4516+
Node* new_length = graph()->NewNode(simplified()->NumberSubtract(),
4517+
length, jsgraph()->OneConstant());
4518+
4519+
// This extra check exists solely to break an exploitation technique
4520+
// that abuses typer mismatches.
4521+
new_length = efalse = graph()->NewNode(
4522+
simplified()->CheckBounds(p.feedback()),
4523+
new_length, length, efalse, if_false);
45184524

45194525
// Store the new {length} to the {receiver}.
45204526
efalse = graph()->NewNode(
45214527
simplified()->StoreField(AccessBuilder::ForJSArrayLength(kind)),
4522-
receiver, length, efalse, if_false);
4528+
receiver, new_length, efalse, if_false);
45234529

45244530
// Load the last entry from the {elements}.
45254531
vfalse = efalse = graph()->NewNode(
45264532
simplified()->LoadElement(AccessBuilder::ForFixedArrayElement(kind)),
4527-
elements, length, efalse, if_false);
4533+
elements, new_length, efalse, if_false);
45284534

45294535
// Store a hole to the element we just removed from the {receiver}.
45304536
efalse = graph()->NewNode(
45314537
simplified()->StoreElement(
45324538
AccessBuilder::ForFixedArrayElement(GetHoleyElementsKind(kind))),
4533-
elements, length, jsgraph()->TheHoleConstant(), efalse, if_false);
4539+
elements, new_length, jsgraph()->TheHoleConstant(), efalse, if_false);
45344540
}
45354541

45364542
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
@@ -4683,19 +4689,25 @@ Reduction JSCallReducer::ReduceArrayPrototypeShift(Node* node) {
46834689
}
46844690

46854691
// Compute the new {length}.
4686-
length = graph()->NewNode(simplified()->NumberSubtract(), length,
4687-
jsgraph()->OneConstant());
4692+
Node* new_length = graph()->NewNode(simplified()->NumberSubtract(),
4693+
length, jsgraph()->OneConstant());
4694+
4695+
// This extra check exists solely to break an exploitation technique
4696+
// that abuses typer mismatches.
4697+
new_length = etrue1 = graph()->NewNode(
4698+
simplified()->CheckBounds(p.feedback()),
4699+
new_length, length, etrue1, if_true1);
46884700

46894701
// Store the new {length} to the {receiver}.
46904702
etrue1 = graph()->NewNode(
46914703
simplified()->StoreField(AccessBuilder::ForJSArrayLength(kind)),
4692-
receiver, length, etrue1, if_true1);
4704+
receiver, new_length, etrue1, if_true1);
46934705

46944706
// Store a hole to the element we just removed from the {receiver}.
46954707
etrue1 = graph()->NewNode(
46964708
simplified()->StoreElement(
46974709
AccessBuilder::ForFixedArrayElement(GetHoleyElementsKind(kind))),
4698-
elements, length, jsgraph()->TheHoleConstant(), etrue1, if_true1);
4710+
elements, new_length, jsgraph()->TheHoleConstant(), etrue1, if_true1);
46994711
}
47004712

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

0 commit comments

Comments
 (0)