diff options
author | Clemens Backes <clemensb@chromium.org> | 2022-12-22 09:43:42 +0100 |
---|---|---|
committer | Michael BrĂ¼ning <michael.bruning@qt.io> | 2023-02-20 16:35:27 +0000 |
commit | c403173c5b565a58e6c9c669a4d55b1acb3cb984 (patch) | |
tree | cf18d2e47bb064e89c249ecbefd2362f44993edc | |
parent | a6b342a50a4f7a5bc8c193a480d2c3f52e9b0956 (diff) | |
download | qtwebengine-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>
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); |