summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGeorg Neis <neis@chromium.org>2021-04-20 18:19:42 +0200
committerMichael BrĂ¼ning <michael.bruning@qt.io>2021-05-14 09:07:40 +0000
commit7ea027a7d8e05d14e02d93b91a7bf70a23d90b23 (patch)
treea902fa72c3149625b847bc7c1ed7d305d3ca5f5a
parentc16b1652b5fb848c20bc2ca63127d2017e598680 (diff)
downloadqtwebengine-chromium-7ea027a7d8e05d14e02d93b91a7bf70a23d90b23.tar.gz
[Backport] CVE-2021-30513: Type Confusion in V8.
Manual backport of patch originally reviewed on https://chromium-review.googlesource.com/c/v8/v8/+/2840452: [compiler] Fix more truncation bugs in SimplifiedLowering Bug: chromium:1200490 Change-Id: I3555b6d99bdb4b4e7c302a43a82c17e8bff84ebe Reviewed-by: Nico Hartmann <nicohartmann@chromium.org> Commit-Queue: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#74097} Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/v8/src/compiler/simplified-lowering.cc66
1 files changed, 39 insertions, 27 deletions
diff --git a/chromium/v8/src/compiler/simplified-lowering.cc b/chromium/v8/src/compiler/simplified-lowering.cc
index e2f34f08796..e031ef0ed91 100644
--- a/chromium/v8/src/compiler/simplified-lowering.cc
+++ b/chromium/v8/src/compiler/simplified-lowering.cc
@@ -707,13 +707,11 @@ class RepresentationSelector {
info->set_restriction_type(restriction_type);
break;
case RETYPE:
- DCHECK(info->restriction_type().Is(restriction_type));
DCHECK(restriction_type.Is(info->restriction_type()));
info->set_output(representation);
break;
case LOWER:
DCHECK_EQ(info->representation(), representation);
- DCHECK(info->restriction_type().Is(restriction_type));
DCHECK(restriction_type.Is(info->restriction_type()));
break;
}
@@ -1263,18 +1261,28 @@ class RepresentationSelector {
return jsgraph_->simplified();
}
- void LowerToCheckedInt32Mul(Node* node, Truncation truncation,
- Type input0_type, Type input1_type) {
- // If one of the inputs is positive and/or truncation is being applied,
- // there is no need to return -0.
- CheckForMinusZeroMode mz_mode =
- truncation.IdentifiesZeroAndMinusZero() ||
- IsSomePositiveOrderedNumber(input0_type) ||
- IsSomePositiveOrderedNumber(input1_type)
- ? CheckForMinusZeroMode::kDontCheckForMinusZero
- : CheckForMinusZeroMode::kCheckForMinusZero;
-
- NodeProperties::ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
+ void VisitForCheckedInt32Mul(Node* node, Truncation truncation,
+ Type input0_type, Type input1_type,
+ UseInfo input_use) {
+ DCHECK_EQ(node->opcode(), IrOpcode::kSpeculativeNumberMultiply);
+ // A -0 input is impossible or will cause a deopt.
+ DCHECK(BothInputsAre(node, Type::Signed32()) ||
+ !input_use.truncation().IdentifiesZeroAndMinusZero());
+ CheckForMinusZeroMode mz_mode;
+ Type restriction;
+ if (IsSomePositiveOrderedNumber(input0_type) ||
+ IsSomePositiveOrderedNumber(input1_type)) {
+ mz_mode = CheckForMinusZeroMode::kDontCheckForMinusZero;
+ restriction = Type::Signed32();
+ } else if (truncation.IdentifiesZeroAndMinusZero()) {
+ mz_mode = CheckForMinusZeroMode::kDontCheckForMinusZero;
+ restriction = Type::Signed32OrMinusZero();
+ } else {
+ mz_mode = CheckForMinusZeroMode::kCheckForMinusZero;
+ restriction = Type::Signed32();
+ }
+ VisitBinop(node, input_use, MachineRepresentation::kWord32, restriction);
+ if (lower()) ChangeOp(node, simplified()->CheckedInt32Mul(mz_mode));
}
void ChangeToInt32OverflowOp(Node* node) {
@@ -1453,12 +1461,22 @@ class RepresentationSelector {
MachineRepresentation::kWord32);
if (lower()) DeferReplacement(node, lowering->Int32Mod(node));
} else if (BothInputsAre(node, Type::Unsigned32OrMinusZeroOrNaN())) {
+ Type const restriction =
+ truncation.IdentifiesZeroAndMinusZero() &&
+ TypeOf(node->InputAt(0)).Maybe(Type::MinusZero())
+ ? Type::Unsigned32OrMinusZero()
+ : Type::Unsigned32();
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
- MachineRepresentation::kWord32, Type::Unsigned32());
+ MachineRepresentation::kWord32, restriction);
if (lower()) ChangeToUint32OverflowOp(node);
} else {
+ Type const restriction =
+ truncation.IdentifiesZeroAndMinusZero() &&
+ TypeOf(node->InputAt(0)).Maybe(Type::MinusZero())
+ ? Type::Signed32OrMinusZero()
+ : Type::Signed32();
VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
- MachineRepresentation::kWord32, Type::Signed32());
+ MachineRepresentation::kWord32, restriction);
if (lower()) ChangeToInt32OverflowOp(node);
}
return;
@@ -1804,23 +1822,17 @@ class RepresentationSelector {
// If both inputs and feedback are int32, use the overflow op.
if (hint == NumberOperationHint::kSignedSmall ||
hint == NumberOperationHint::kSigned32) {
- VisitBinop(node, UseInfo::TruncatingWord32(),
- MachineRepresentation::kWord32, Type::Signed32());
- if (lower()) {
- LowerToCheckedInt32Mul(node, truncation, input0_type,
- input1_type);
- }
+ VisitForCheckedInt32Mul(node, truncation, input0_type,
+ input1_type,
+ UseInfo::TruncatingWord32());
return;
}
}
if (hint == NumberOperationHint::kSignedSmall ||
hint == NumberOperationHint::kSigned32) {
- VisitBinop(node, CheckedUseInfoAsWord32FromHint(hint),
- MachineRepresentation::kWord32, Type::Signed32());
- if (lower()) {
- LowerToCheckedInt32Mul(node, truncation, input0_type, input1_type);
- }
+ VisitForCheckedInt32Mul(node, truncation, input0_type, input1_type,
+ CheckedUseInfoAsWord32FromHint(hint));
return;
}