summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClemens Backes <clemensb@chromium.org>2022-12-22 09:43:42 +0100
committerMichael BrĂ¼ning <michael.bruning@qt.io>2023-02-20 16:35:27 +0000
commitc403173c5b565a58e6c9c669a4d55b1acb3cb984 (patch)
treecf18d2e47bb064e89c249ecbefd2362f44993edc
parenta6b342a50a4f7a5bc8c193a480d2c3f52e9b0956 (diff)
downloadqtwebengine-chromium-c403173c5b565a58e6c9c669a4d55b1acb3cb984.tar.gz
[Backport] CVE-2023-0696: Type Confusion in V8
Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/v8/v8/+/4204087: Merged: [wasm] Fix printing of wasm-to-js frames After https://crrev.com/c/3859787 those frames would be printed like standard Wasm frames, but in the place of the WasmInstanceObject, they have a WasmApiFunctionRef object instead. So special-case the {WasmToJsFrame::instance()} to load the instance properly. Also special-case the {position()} accessor for imported functions. R=victorgomes@chromium.org (cherry picked from commit e17eee4894be67f715a7b2d7f17d8b69724f1cf8) Bug: chromium:1402270 Change-Id: I0a287afbf14dd64edb859c6407ce7c0a3d159023 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4204087 Reviewed-by: Darius Mercadier <dmercadier@chromium.org> Reviewed-by: Victor Gomes <victorgomes@chromium.org> Commit-Queue: Clemens Backes <clemensb@chromium.org> Reviewed-by: Maya Lekova <mslekova@chromium.org> Cr-Commit-Position: refs/branch-heads/11.0@{#24} Cr-Branched-From: 06097c6f0c5af54fd5d6965d37027efb72decd4f-refs/heads/11.0.226@{#1} Cr-Branched-From: 6bf3344f5d9940de1ab253f1817dcb99c641c9d3-refs/heads/main@{#84857} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/461064 Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
-rw-r--r--chromium/v8/src/compiler/backend/arm/code-generator-arm.cc4
-rw-r--r--chromium/v8/src/compiler/backend/arm64/code-generator-arm64.cc3
-rw-r--r--chromium/v8/src/compiler/backend/ia32/code-generator-ia32.cc4
-rw-r--r--chromium/v8/src/compiler/backend/x64/code-generator-x64.cc8
-rw-r--r--chromium/v8/src/diagnostics/objects-printer.cc1
-rw-r--r--chromium/v8/src/execution/frames.cc11
-rw-r--r--chromium/v8/src/execution/frames.h5
7 files changed, 30 insertions, 6 deletions
diff --git a/chromium/v8/src/compiler/backend/arm/code-generator-arm.cc b/chromium/v8/src/compiler/backend/arm/code-generator-arm.cc
index 4c5accd7a8f..d8a77d70bbd 100644
--- a/chromium/v8/src/compiler/backend/arm/code-generator-arm.cc
+++ b/chromium/v8/src/compiler/backend/arm/code-generator-arm.cc
@@ -3699,6 +3699,10 @@ void CodeGenerator::AssembleConstructFrame() {
if (call_descriptor->IsWasmFunctionCall() ||
call_descriptor->IsWasmImportWrapper() ||
call_descriptor->IsWasmCapiFunction()) {
+ // For import wrappers and C-API functions, this stack slot is only used
+ // for printing stack traces in V8. Also, it holds a WasmApiFunctionRef
+ // instead of the instance itself, which is taken care of in the frames
+ // accessors.
__ Push(kWasmInstanceRegister);
}
if (call_descriptor->IsWasmCapiFunction()) {
diff --git a/chromium/v8/src/compiler/backend/arm64/code-generator-arm64.cc b/chromium/v8/src/compiler/backend/arm64/code-generator-arm64.cc
index 60d19c79307..8ad2c88c127 100644
--- a/chromium/v8/src/compiler/backend/arm64/code-generator-arm64.cc
+++ b/chromium/v8/src/compiler/backend/arm64/code-generator-arm64.cc
@@ -3225,6 +3225,9 @@ void CodeGenerator::AssembleConstructFrame() {
Register scratch = temps.AcquireX();
__ Mov(scratch,
StackFrame::TypeToMarker(info()->GetOutputStackFrameType()));
+ // This stack slot is only used for printing stack traces in V8. Also,
+ // it holds a WasmApiFunctionRef instead of the instance itself, which
+ // is taken care of in the frames accessors.
__ Push(scratch, kWasmInstanceRegister);
int extra_slots =
call_descriptor->kind() == CallDescriptor::kCallWasmImportWrapper
diff --git a/chromium/v8/src/compiler/backend/ia32/code-generator-ia32.cc b/chromium/v8/src/compiler/backend/ia32/code-generator-ia32.cc
index 5afd119ff50..d13310cfcc2 100644
--- a/chromium/v8/src/compiler/backend/ia32/code-generator-ia32.cc
+++ b/chromium/v8/src/compiler/backend/ia32/code-generator-ia32.cc
@@ -4026,6 +4026,10 @@ void CodeGenerator::AssembleConstructFrame() {
if (call_descriptor->IsWasmFunctionCall() ||
call_descriptor->IsWasmImportWrapper() ||
call_descriptor->IsWasmCapiFunction()) {
+ // For import wrappers and C-API functions, this stack slot is only used
+ // for printing stack traces in V8. Also, it holds a WasmApiFunctionRef
+ // instead of the instance itself, which is taken care of in the frames
+ // accessors.
__ push(kWasmInstanceRegister);
}
if (call_descriptor->IsWasmCapiFunction()) {
diff --git a/chromium/v8/src/compiler/backend/x64/code-generator-x64.cc b/chromium/v8/src/compiler/backend/x64/code-generator-x64.cc
index e3f759f5700..0e02c63ace6 100644
--- a/chromium/v8/src/compiler/backend/x64/code-generator-x64.cc
+++ b/chromium/v8/src/compiler/backend/x64/code-generator-x64.cc
@@ -4841,10 +4841,10 @@ void CodeGenerator::AssembleConstructFrame() {
if (call_descriptor->IsWasmFunctionCall() ||
call_descriptor->IsWasmImportWrapper() ||
call_descriptor->IsWasmCapiFunction()) {
- // We do not use this stack value in import wrappers and capi functions.
- // We push it anyway to satisfy legacy assumptions about these frames'
- // size and order.
- // TODO(manoskouk): Consider fixing this.
+ // For import wrappers and C-API functions, this stack slot is only used
+ // for printing stack traces in V8. Also, it holds a WasmApiFunctionRef
+ // instead of the instance itself, which is taken care of in the frames
+ // accessors.
__ pushq(kWasmInstanceRegister);
}
if (call_descriptor->IsWasmCapiFunction()) {
diff --git a/chromium/v8/src/diagnostics/objects-printer.cc b/chromium/v8/src/diagnostics/objects-printer.cc
index ce4d15b2c27..71604afa7a0 100644
--- a/chromium/v8/src/diagnostics/objects-printer.cc
+++ b/chromium/v8/src/diagnostics/objects-printer.cc
@@ -2137,6 +2137,7 @@ void WasmApiFunctionRef::WasmApiFunctionRefPrint(std::ostream& os) {
os << "\n - isolate_root: " << reinterpret_cast<void*>(isolate_root());
os << "\n - native_context: " << Brief(native_context());
os << "\n - callable: " << Brief(callable());
+ os << "\n - instance: " << Brief(instance());
os << "\n - suspend: " << suspend();
os << "\n";
}
diff --git a/chromium/v8/src/execution/frames.cc b/chromium/v8/src/execution/frames.cc
index 0ca10a21e19..c18ce06a87f 100644
--- a/chromium/v8/src/execution/frames.cc
+++ b/chromium/v8/src/execution/frames.cc
@@ -2500,7 +2500,7 @@ void WasmFrame::Print(StringStream* accumulator, PrintMode mode,
return;
}
wasm::WasmCodeRefScope code_ref_scope;
- accumulator->Add("Wasm [");
+ accumulator->Add(is_wasm_to_js() ? "Wasm-to-JS [" : "Wasm [");
accumulator->PrintName(script().name());
Address instruction_start = wasm_code()->instruction_start();
base::Vector<const uint8_t> raw_func_name =
@@ -2631,6 +2631,15 @@ void WasmDebugBreakFrame::Print(StringStream* accumulator, PrintMode mode,
if (mode != OVERVIEW) accumulator->Add("\n");
}
+WasmInstanceObject WasmToJsFrame::wasm_instance() const {
+ // WasmToJsFrames hold the {WasmApiFunctionRef} object in the instance slot.
+ // Load the instance from there.
+ const int offset = WasmFrameConstants::kWasmInstanceOffset;
+ Object func_ref_obj(Memory<Address>(fp() + offset));
+ WasmApiFunctionRef func_ref = WasmApiFunctionRef::cast(func_ref_obj);
+ return WasmInstanceObject::cast(func_ref.instance());
+}
+
void JsToWasmFrame::Iterate(RootVisitor* v) const {
CodeLookupResult lookup_result = GetContainingCode(isolate(), pc());
CHECK(lookup_result.IsFound());
diff --git a/chromium/v8/src/execution/frames.h b/chromium/v8/src/execution/frames.h
index c72b7acef4b..f6cf5360ce9 100644
--- a/chromium/v8/src/execution/frames.h
+++ b/chromium/v8/src/execution/frames.h
@@ -1035,7 +1035,7 @@ class WasmFrame : public TypedFrame {
void Iterate(RootVisitor* v) const override;
// Accessors.
- V8_EXPORT_PRIVATE WasmInstanceObject wasm_instance() const;
+ virtual V8_EXPORT_PRIVATE WasmInstanceObject wasm_instance() const;
V8_EXPORT_PRIVATE wasm::NativeModule* native_module() const;
wasm::WasmCode* wasm_code() const;
int function_index() const;
@@ -1101,6 +1101,9 @@ class WasmToJsFrame : public WasmFrame {
public:
Type type() const override { return WASM_TO_JS; }
+ int position() const override { return 0; }
+ WasmInstanceObject wasm_instance() const override;
+
protected:
inline explicit WasmToJsFrame(StackFrameIteratorBase* iterator);