diff options
author | Georg Neis <neis@chromium.org> | 2020-02-14 18:33:16 +0100 |
---|---|---|
committer | Michael Brüning <michael.bruning@qt.io> | 2020-03-05 09:50:03 +0000 |
commit | 5707cc4f757445b3776a1405f3cc364e5d6cafee (patch) | |
tree | 1275cb3e49be81d72b2e8c59e1ba9ebf35d9f5d4 | |
parent | e4659a4c8a8a7c18f7172fbf5b9f7f224d486aba (diff) | |
download | qtwebengine-chromium-5707cc4f757445b3776a1405f3cc364e5d6cafee.tar.gz |
[Backport] CVE-2020-6383 - Type confusion in V8
Manual backport of patch originally reviewed on
https://chromium-review.googlesource.com/c/v8/v8/+/2056854:
Merged: [turbofan] Fix bug in Typer::TypeInductionVariablePhi
Revision: a2e971c56d1c46f7c71ccaf33057057308cc8484
BUG=chromium:1051017
Change-Id: I97c258009f938b5739312b35ae825a5f9ca22e5e
Reviewed-by: Jüri Valdmann <juri.valdmann@qt.io>
-rw-r--r-- | chromium/v8/src/compiler/typer.cc | 51 |
1 files changed, 22 insertions, 29 deletions
diff --git a/chromium/v8/src/compiler/typer.cc b/chromium/v8/src/compiler/typer.cc index e180d4671ba..da1107a801a 100644 --- a/chromium/v8/src/compiler/typer.cc +++ b/chromium/v8/src/compiler/typer.cc @@ -840,30 +840,24 @@ Type Typer::Visitor::TypeInductionVariablePhi(Node* node) { DCHECK_EQ(IrOpcode::kLoop, NodeProperties::GetControlInput(node)->opcode()); DCHECK_EQ(2, NodeProperties::GetControlInput(node)->InputCount()); - auto res = induction_vars_->induction_variables().find(node->id()); - DCHECK(res != induction_vars_->induction_variables().end()); - InductionVariable* induction_var = res->second; - InductionVariable::ArithmeticType arithmetic_type = induction_var->Type(); Type initial_type = Operand(node, 0); Type increment_type = Operand(node, 2); - const bool both_types_integer = initial_type.Is(typer_->cache_->kInteger) && - increment_type.Is(typer_->cache_->kInteger); - bool maybe_nan = false; - // The addition or subtraction could still produce a NaN, if the integer - // ranges touch infinity. - if (both_types_integer) { - Type resultant_type = - (arithmetic_type == InductionVariable::ArithmeticType::kAddition) - ? typer_->operation_typer()->NumberAdd(initial_type, increment_type) - : typer_->operation_typer()->NumberSubtract(initial_type, - increment_type); - maybe_nan = resultant_type.Maybe(Type::NaN()); - } - - // We only handle integer induction variables (otherwise ranges - // do not apply and we cannot do anything). - if (!both_types_integer || maybe_nan) { + // If we do not have enough type information for the initial value or + // the increment, just return the initial value's type. + if (initial_type.IsNone() || + increment_type.Is(typer_->cache_->kSingletonZero)) { + return initial_type; + } + + // We only handle integer induction variables (otherwise ranges do not apply + // and we cannot do anything). Moreover, we don't support infinities in + // {increment_type} because the induction variable can become NaN through + // addition/subtraction of opposing infinities. + if (!initial_type.Is(typer_->cache_->kInteger) || + !increment_type.Is(typer_->cache_->kInteger) || + increment_type.Min() == -V8_INFINITY || + increment_type.Max() == +V8_INFINITY) { // Fallback to normal phi typing, but ensure monotonicity. // (Unfortunately, without baking in the previous type, monotonicity might // be violated because we might not yet have retyped the incrementing @@ -876,14 +870,13 @@ Type Typer::Visitor::TypeInductionVariablePhi(Node* node) { } return type; } - // If we do not have enough type information for the initial value or - // the increment, just return the initial value's type. - if (initial_type.IsNone() || - increment_type.Is(typer_->cache_->kSingletonZero)) { - return initial_type; - } // Now process the bounds. + auto res = induction_vars_->induction_variables().find(node->id()); + DCHECK(res != induction_vars_->induction_variables().end()); + InductionVariable* induction_var = res->second; + InductionVariable::ArithmeticType arithmetic_type = induction_var->Type(); + double min = -V8_INFINITY; double max = V8_INFINITY; @@ -939,8 +932,8 @@ Type Typer::Visitor::TypeInductionVariablePhi(Node* node) { // The lower bound must be at most the initial value's lower bound. min = std::min(min, initial_type.Min()); } else { - // Shortcut: If the increment can be both positive and negative, - // the variable can go arbitrarily far, so just return integer. + // If the increment can be both positive and negative, the variable can go + // arbitrarily far. return typer_->cache_->kInteger; } if (FLAG_trace_turbo_loop) { |