From 5707cc4f757445b3776a1405f3cc364e5d6cafee Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Fri, 14 Feb 2020 18:33:16 +0100 Subject: [Backport] CVE-2020-6383 - Type confusion in V8 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- chromium/v8/src/compiler/typer.cc | 51 +++++++++++++++++---------------------- 1 file 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) { -- cgit v1.2.1