summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Neis <neis@chromium.org>2021-04-18 09:46:25 +0200
committerMichael BrĂ¼ning <michael.bruning@qt.io>2021-05-07 09:05:28 +0000
commitbda00397362bf03ff7b8d88fa54625524f604c7e (patch)
tree37d51b5ce0ae7c8a29fd3d52f53e0dc79aa28efc
parent7ee750fffd694a69a1394ce592b6443e2513026f (diff)
downloadqtwebengine-chromium-bda00397362bf03ff7b8d88fa54625524f604c7e.tar.gz
[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 TBR=glazunov@chromium.org BUG=chromium:1198696 NOTRY=true NOPRESUBMIT=true NOTREECHECKS=true Change-Id: I1840ffabbed3a3caab75b0abea1d37d9ed446d3f Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Georg Neis <neis@chromium.org> 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 <allan.jensen@qt.io>
-rw-r--r--chromium/v8/src/compiler/js-call-reducer.cc30
1 files changed, 21 insertions, 9 deletions
diff --git a/chromium/v8/src/compiler/js-call-reducer.cc b/chromium/v8/src/compiler/js-call-reducer.cc
index c966c4fc788..a8dfd99b948 100644
--- a/chromium/v8/src/compiler/js-call-reducer.cc
+++ b/chromium/v8/src/compiler/js-call-reducer.cc
@@ -4513,24 +4513,30 @@ Reduction JSCallReducer::ReduceArrayPrototypePop(Node* node) {
}
// Compute the new {length}.
- length = graph()->NewNode(simplified()->NumberSubtract(), length,
- jsgraph()->OneConstant());
+ Node* new_length = graph()->NewNode(simplified()->NumberSubtract(),
+ length, jsgraph()->OneConstant());
+
+ // This extra check exists solely to break an exploitation technique
+ // that abuses typer mismatches.
+ new_length = efalse = graph()->NewNode(
+ simplified()->CheckBounds(p.feedback()),
+ new_length, length, efalse, if_false);
// Store the new {length} to the {receiver}.
efalse = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForJSArrayLength(kind)),
- receiver, length, efalse, if_false);
+ receiver, new_length, efalse, if_false);
// Load the last entry from the {elements}.
vfalse = efalse = graph()->NewNode(
simplified()->LoadElement(AccessBuilder::ForFixedArrayElement(kind)),
- elements, length, efalse, if_false);
+ elements, new_length, efalse, if_false);
// Store a hole to the element we just removed from the {receiver}.
efalse = graph()->NewNode(
simplified()->StoreElement(
AccessBuilder::ForFixedArrayElement(GetHoleyElementsKind(kind))),
- elements, length, jsgraph()->TheHoleConstant(), efalse, if_false);
+ elements, new_length, jsgraph()->TheHoleConstant(), efalse, if_false);
}
control = graph()->NewNode(common()->Merge(2), if_true, if_false);
@@ -4683,19 +4689,25 @@ Reduction JSCallReducer::ReduceArrayPrototypeShift(Node* node) {
}
// Compute the new {length}.
- length = graph()->NewNode(simplified()->NumberSubtract(), length,
- jsgraph()->OneConstant());
+ Node* new_length = graph()->NewNode(simplified()->NumberSubtract(),
+ length, jsgraph()->OneConstant());
+
+ // This extra check exists solely to break an exploitation technique
+ // that abuses typer mismatches.
+ new_length = etrue1 = graph()->NewNode(
+ simplified()->CheckBounds(p.feedback()),
+ new_length, length, etrue1, if_true1);
// Store the new {length} to the {receiver}.
etrue1 = graph()->NewNode(
simplified()->StoreField(AccessBuilder::ForJSArrayLength(kind)),
- receiver, length, etrue1, if_true1);
+ receiver, new_length, etrue1, if_true1);
// Store a hole to the element we just removed from the {receiver}.
etrue1 = graph()->NewNode(
simplified()->StoreElement(
AccessBuilder::ForFixedArrayElement(GetHoleyElementsKind(kind))),
- elements, length, jsgraph()->TheHoleConstant(), etrue1, if_true1);
+ elements, new_length, jsgraph()->TheHoleConstant(), etrue1, if_true1);
}
Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1);