diff options
author | Jakob Gruber <jgruber@chromium.org> | 2020-04-06 15:48:53 +0200 |
---|---|---|
committer | Michal Klocek <michal.klocek@qt.io> | 2020-04-24 15:17:47 +0000 |
commit | 0173823bbde8b9e8eb27b0d77f9112511b2a83bf (patch) | |
tree | 35bd8e96109d0d7d46c375ae6a8dc3ccf301e582 | |
parent | 9b37796d4fa91be5adbda1a4e95b11618338a305 (diff) | |
download | qtwebengine-chromium-0173823bbde8b9e8eb27b0d77f9112511b2a83bf.tar.gz |
[Backport] CVE-2020-6458
Reserve space for all registers in interpreter
This is a minimal version of https://crrev.com/c/2135642 intended for
backmerges.
Ensure that the interpreter has space for all required registers.
Bug: chromium:1067270
Change-Id: I96e364a34b34822ae21b246d391a17d08e1aa98a
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r-- | chromium/v8/src/regexp/regexp-interpreter.cc | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/chromium/v8/src/regexp/regexp-interpreter.cc b/chromium/v8/src/regexp/regexp-interpreter.cc index adea0cf7c09..d818ab6e7f3 100644 --- a/chromium/v8/src/regexp/regexp-interpreter.cc +++ b/chromium/v8/src/regexp/regexp-interpreter.cc @@ -1045,8 +1045,29 @@ IrregexpInterpreter::Result IrregexpInterpreter::MatchForCallFromJs( return IrregexpInterpreter::RETRY; } - return Match(isolate, regexp_obj, subject_string, registers, registers_length, - start_position, call_origin); + // In generated code, registers are allocated on the stack. The given + // `registers` argument is only guaranteed to hold enough space for permanent + // registers (i.e. for captures), and not for temporary registers used only + // during matcher execution. We match that behavior in the interpreter by + // using a SmallVector as internal register storage. + static constexpr int kBaseRegisterArraySize = 64; // Arbitrary. + const int internal_register_count = + Smi::ToInt(regexp_obj.DataAt(JSRegExp::kIrregexpMaxRegisterCountIndex)); + base::SmallVector<int, kBaseRegisterArraySize> internal_registers( + internal_register_count); + + Result result = + Match(isolate, regexp_obj, subject_string, internal_registers.data(), + internal_register_count, start_position, call_origin); + + // Copy capture registers to the output array. + if (result == IrregexpInterpreter::SUCCESS) { + CHECK_GE(internal_registers.size(), registers_length); + MemCopy(registers, internal_registers.data(), + registers_length * sizeof(registers[0])); + } + + return result; } IrregexpInterpreter::Result IrregexpInterpreter::MatchForCallFromRuntime( |