diff options
author | Georg Neis <neis@chromium.org> | 2021-04-20 18:19:42 +0200 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2021-05-14 09:07:40 +0000 |
commit | 7ea027a7d8e05d14e02d93b91a7bf70a23d90b23 (patch) | |
tree | a902fa72c3149625b847bc7c1ed7d305d3ca5f5a | |
parent | c16b1652b5fb848c20bc2ca63127d2017e598680 (diff) | |
download | qtwebengine-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.cc | 66 |
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; } |