From d6e06841443a40c99efd209bce6c96c8a7659c34 Mon Sep 17 00:00:00 2001 From: Georg Neis Date: Fri, 11 Sep 2020 16:37:47 +0200 Subject: [Backport] CVE-2020-15965: Out of bounds write in V8 Manual backport of patch originally reviewed on https://chromium-review.googlesource.com/c/v8/v8/+/2404452: [compiler] Fix bug in SimplifiedLowering's overflow computation It's unsound to ignore -0 inputs: -0 - INT32_MIN is outside of INT32 range. Bug: chromium:1126249 Change-Id: I3b92f16c1201705780acb0359975329aa2ca34d1 Reviewed-by: Michal Klocek --- chromium/v8/src/compiler/simplified-lowering.cc | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/chromium/v8/src/compiler/simplified-lowering.cc b/chromium/v8/src/compiler/simplified-lowering.cc index ac5611f5ef5..ffc45ad59a5 100644 --- a/chromium/v8/src/compiler/simplified-lowering.cc +++ b/chromium/v8/src/compiler/simplified-lowering.cc @@ -213,10 +213,16 @@ class InputUseInfos { #endif // DEBUG bool CanOverflowSigned32(const Operator* op, Type left, Type right, - Zone* type_zone) { - // We assume the inputs are checked Signed32 (or known statically - // to be Signed32). Technically, the inputs could also be minus zero, but - // that cannot cause overflow. + TypeCache const& type_cache, Zone* type_zone) { + // We assume the inputs are checked Signed32 (or known statically to be + // Signed32). Technically, the inputs could also be minus zero, which we treat + // as 0 for the purpose of this function. + if (left.Maybe(Type::MinusZero())) { + left = Type::Union(left, type_cache.kSingletonZero, type_zone); + } + if (right.Maybe(Type::MinusZero())) { + right = Type::Union(right, type_cache.kSingletonZero, type_zone); + } left = Type::Intersect(left, Type::Signed32(), type_zone); right = Type::Intersect(right, Type::Signed32(), type_zone); if (left.IsNone() || right.IsNone()) return false; @@ -1348,7 +1354,8 @@ class RepresentationSelector { if (lower()) { if (truncation.IsUsedAsWord32() || !CanOverflowSigned32(node->op(), left_feedback_type, - right_feedback_type, graph_zone())) { + right_feedback_type, type_cache_, + graph_zone())) { ChangeToPureOp(node, Int32Op(node)); } else { -- cgit v1.2.1