[Intl] Fix Heap-use-after-free

Fix Heap-use-after-free READ 2 in Intl.Segmenter
when the segments got free during the iteration
We need to keep a copy of the string in the iterator instead
of depending on the one referenced from the segments.

Bug: chromium:1121156, v8:6891
Change-Id: I26ef5baccaa470dc1bd8cc229c737f556d27160e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2376173
Commit-Queue: Frank Tang <ftang@chromium.org>
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#69575}
This commit is contained in:
Frank Tang 2020-08-25 16:27:04 -07:00 committed by Commit Bot
parent 84cf890532
commit db1115e267
5 changed files with 23 additions and 0 deletions

View File

@ -134,6 +134,7 @@ bitfield struct JSSegmentIteratorFlags extends uint31 {
@generateCppClass
extern class JSSegmentIterator extends JSObject {
icu_break_iterator: Foreign; // Managed<icu::BreakIterator>
unicode_string: Foreign; // Managed<icu::UnicodeString>
flags: SmiTagged<JSSegmentIteratorFlags>;
}

View File

@ -22,6 +22,8 @@ TQ_OBJECT_CONSTRUCTORS_IMPL(JSSegmentIterator)
// Base segment iterator accessors.
ACCESSORS(JSSegmentIterator, icu_break_iterator, Managed<icu::BreakIterator>,
kIcuBreakIteratorOffset)
ACCESSORS(JSSegmentIterator, unicode_string, Managed<icu::UnicodeString>,
kUnicodeStringOffset)
inline void JSSegmentIterator::set_granularity(
JSSegmenter::Granularity granularity) {

View File

@ -46,6 +46,13 @@ MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
Handle<Managed<icu::BreakIterator>> managed_break_iterator =
Managed<icu::BreakIterator>::FromRawPtr(isolate, 0, break_iterator);
icu::UnicodeString* string = new icu::UnicodeString();
break_iterator->getText().getText(*string);
Handle<Managed<icu::UnicodeString>> unicode_string =
Managed<icu::UnicodeString>::FromRawPtr(isolate, 0, string);
break_iterator->setText(*string);
// Now all properties are ready, so we can allocate the result object.
Handle<JSObject> result = isolate->factory()->NewJSObjectFromMap(map);
DisallowHeapAllocation no_gc;
@ -55,6 +62,7 @@ MaybeHandle<JSSegmentIterator> JSSegmentIterator::Create(
segment_iterator->set_flags(0);
segment_iterator->set_granularity(granularity);
segment_iterator->set_icu_break_iterator(*managed_break_iterator);
segment_iterator->set_unicode_string(*unicode_string);
return segment_iterator;
}

View File

@ -43,6 +43,7 @@ class JSSegmentIterator
// SegmentIterator accessors.
DECL_ACCESSORS(icu_break_iterator, Managed<icu::BreakIterator>)
DECL_ACCESSORS(unicode_string, Managed<icu::UnicodeString>)
DECL_PRINTER(JSSegmentIterator)

View File

@ -0,0 +1,11 @@
// Copyright 2020 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Flags: --harmony-intl-segmenter --expose-gc
let segmenter = new Intl.Segmenter();
let segments = segmenter.segment(undefined);
for (let seg of segments) {
segments = gc(); // free segments and call gc.
}