From ab79f5394af02566115e5aa1d65046a4fd1225cb Mon Sep 17 00:00:00 2001 From: Camillo Bruni Date: Mon, 16 Mar 2020 10:06:45 +0100 Subject: [Backport] CVE-2020-6426: Inappropriate implementation in V8. Manual backport of patch originally reviewed on: https://chromium-review.googlesource.com/c/v8/v8/+/2104887 Merged: [intl] Fix Intl.NumberFormat constructor Revision: 09d14728ca251c955f4634036f8d72a4665e96c6 BUG=chromium:1052647 NOTRY=true NOPRESUBMIT=true NOTREECHECKS=true Change-Id: Iff7dbf9e6e3b071d5a98e61120f5c2aa69affe7f Reviewed-by: Michal Klocek --- chromium/v8/src/builtins/builtins-intl.cc | 77 +++++++++++++++---------------- 1 file changed, 36 insertions(+), 41 deletions(-) diff --git a/chromium/v8/src/builtins/builtins-intl.cc b/chromium/v8/src/builtins/builtins-intl.cc index ff8e96f4f51..d75049fdb29 100644 --- a/chromium/v8/src/builtins/builtins-intl.cc +++ b/chromium/v8/src/builtins/builtins-intl.cc @@ -269,10 +269,8 @@ Object LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate, // [[Construct]] Handle target = args.target(); - Handle locales = args.atOrUndefined(isolate, 1); Handle options = args.atOrUndefined(isolate, 2); - // 2. Let format be ? OrdinaryCreateFromConstructor(newTarget, // "%Prototype%", ...). @@ -285,45 +283,42 @@ Object LegacyFormatConstructor(BuiltinArguments args, Isolate* isolate, ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, format, T::New(isolate, map, locales, options)); // 4. Let this be the this value. - Handle receiver = args.receiver(); - - // 5. If NewTarget is undefined and ? InstanceofOperator(this, %%) - // is true, then - // - // Look up the intrinsic value that has been stored on the context. - // Call the instanceof function - Handle is_instance_of_obj; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, is_instance_of_obj, - Object::InstanceOf(isolate, receiver, constructor)); - - // Get the boolean value of the result - bool is_instance_of = is_instance_of_obj->BooleanValue(isolate); - - if (args.new_target()->IsUndefined(isolate) && is_instance_of) { - if (!receiver->IsJSReceiver()) { - THROW_NEW_ERROR_RETURN_FAILURE( - isolate, - NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, - isolate->factory()->NewStringFromAsciiChecked(method), - receiver)); - } - Handle rec = Handle::cast(receiver); - // a. Perform ? DefinePropertyOrThrow(this, - // %Intl%.[[FallbackSymbol]], PropertyDescriptor{ [[Value]]: format, - // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }). - PropertyDescriptor desc; - desc.set_value(format); - desc.set_writable(false); - desc.set_enumerable(false); - desc.set_configurable(false); - Maybe success = JSReceiver::DefineOwnProperty( - isolate, rec, isolate->factory()->intl_fallback_symbol(), &desc, - Just(kThrowOnError)); - MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception()); - CHECK(success.FromJust()); - // b. b. Return this. - return *receiver; + if (args.new_target()->IsUndefined(isolate)) { + Handle receiver = args.receiver(); + + // 5. If NewTarget is undefined and ? InstanceofOperator(this, %%) + // is true, then Look up the intrinsic value that has been stored on + // the context. + Handle is_instance_of_obj; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, is_instance_of_obj, + Object::InstanceOf(isolate, receiver, constructor)); + + if (is_instance_of_obj->BooleanValue(isolate)) { + if (!receiver->IsJSReceiver()) { + THROW_NEW_ERROR_RETURN_FAILURE( + isolate, + NewTypeError(MessageTemplate::kIncompatibleMethodReceiver, + isolate->factory()->NewStringFromAsciiChecked(method), + receiver)); + } + Handle rec = Handle::cast(receiver); + // a. Perform ? DefinePropertyOrThrow(this, + // %Intl%.[[FallbackSymbol]], PropertyDescriptor{ [[Value]]: format, + // [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }). + PropertyDescriptor desc; + desc.set_value(format); + desc.set_writable(false); + desc.set_enumerable(false); + desc.set_configurable(false); + Maybe success = JSReceiver::DefineOwnProperty( + isolate, rec, isolate->factory()->intl_fallback_symbol(), &desc, + Just(kThrowOnError)); + MAYBE_RETURN(success, ReadOnlyRoots(isolate).exception()); + CHECK(success.FromJust()); + // b. b. Return this. + return *receiver; + } } // 6. Return format. return *format; -- cgit v1.2.1