summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJakob Gruber <jgruber@chromium.org>2020-04-06 15:48:53 +0200
committerMichal Klocek <michal.klocek@qt.io>2020-04-24 15:17:47 +0000
commit0173823bbde8b9e8eb27b0d77f9112511b2a83bf (patch)
tree35bd8e96109d0d7d46c375ae6a8dc3ccf301e582
parent9b37796d4fa91be5adbda1a4e95b11618338a305 (diff)
downloadqtwebengine-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.cc25
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(