mirror of
https://git.freebsd.org/ports.git
synced 2025-05-13 15:51:51 -04:00
Patched with security patches up to Chromium version: 121.0.6167.160 While here, remove unneed extra-patch. All supported versions of FreeBSD have mempcpy(3). MFH: 2024Q1 Security: bbcb1584-c068-11ee-bdd6-4ccc6adda413, dc9e5237-c197-11ee-86bb-a8a1599412c6, 19047673-c680-11ee-86bb-a8a1599412c6
2509 lines
117 KiB
Text
2509 lines
117 KiB
Text
Add security patches to this file.
|
||
|
||
Addresses the following security issues:
|
||
- CVE-2023-6347
|
||
- CVE-2023-6510
|
||
- Security bug 1488199
|
||
- CVE-2023-6345
|
||
- CVE-2023-6702
|
||
- Security bug 1505632
|
||
- CVE-2024-0222
|
||
- CVE-2024-0333
|
||
- CVE-2024-0518
|
||
- CVE-2024-0519
|
||
- Security bug 1506535
|
||
- CVE-2023-7024
|
||
- CVE-2024-0224
|
||
- Security bug 1511689
|
||
- CVE-2024-0807
|
||
- CVE-2024-0808
|
||
- Security bug 1519980
|
||
- CVE-2024-1077
|
||
- CVE-2024-1060
|
||
- CVE-2024-1283
|
||
|
||
From 8ca846140881c9480b18bc9645b38fb9ea565ea3 Mon Sep 17 00:00:00 2001
|
||
From: Ken Rockot <rockot@google.com>
|
||
Date: Thu, 16 Nov 2023 23:23:22 +0000
|
||
Subject: [PATCH] [Backport] CVE-2023-6347: Use after free in Mojo
|
||
|
||
Cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5038080:
|
||
Reland: Fix IPC Channel pipe teardown
|
||
|
||
This is a reland with the new test temporarily disabled on Android
|
||
until it can run without disrupting other tests.
|
||
|
||
(cherry picked from commit cd4c1f165c16c6d8161b5372ef7f61c715e01a42)
|
||
|
||
Fixed: 1494461
|
||
Change-Id: If1d83c2dce62020f78dd50abc460973759002a1a
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5015115
|
||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||
Reviewed-by: Robert Sesek <rsesek@chromium.org>
|
||
Cr-Original-Commit-Position: refs/heads/main@{#1221953}
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5038080
|
||
Auto-Submit: Ken Rockot <rockot@google.com>
|
||
Commit-Queue: Daniel Cheng <dcheng@chromium.org>
|
||
Reviewed-by: Daniel Cheng <dcheng@chromium.org>
|
||
Cr-Commit-Position: refs/branch-heads/6045@{#1383}
|
||
Cr-Branched-From: 905e8bdd32d891451d94d1ec71682e989da2b0a1-refs/heads/main@{#1204232}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/522256
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
chromium/ipc/ipc_mojo_bootstrap.cc | 43 ++++++++++++++++++++++--------
|
||
1 file changed, 32 insertions(+), 11 deletions(-)
|
||
|
||
diff --git a/chromium/ipc/ipc_mojo_bootstrap.cc b/chromium/ipc/ipc_mojo_bootstrap.cc
|
||
index 616382cb8f9c..9a9eeef84755 100644
|
||
--- src/3rdparty/chromium/ipc/ipc_mojo_bootstrap.cc.orig
|
||
+++ src/3rdparty/chromium/ipc/ipc_mojo_bootstrap.cc
|
||
@@ -702,13 +702,12 @@ class ChannelAssociatedGroupController
|
||
// handle.
|
||
DCHECK(!endpoint->client());
|
||
DCHECK(endpoint->peer_closed());
|
||
- MarkClosedAndMaybeRemove(endpoint);
|
||
+ MarkClosed(endpoint);
|
||
} else {
|
||
- MarkPeerClosedAndMaybeRemove(endpoint);
|
||
+ MarkPeerClosed(endpoint);
|
||
}
|
||
}
|
||
-
|
||
- DCHECK(endpoints_.empty());
|
||
+ endpoints_.clear();
|
||
|
||
GetMemoryDumpProvider().RemoveController(this);
|
||
}
|
||
@@ -755,15 +754,19 @@ class ChannelAssociatedGroupController
|
||
base::AutoLock locker(lock_);
|
||
encountered_error_ = true;
|
||
|
||
+ std::vector<uint32_t> endpoints_to_remove;
|
||
std::vector<scoped_refptr<Endpoint>> endpoints_to_notify;
|
||
for (auto iter = endpoints_.begin(); iter != endpoints_.end();) {
|
||
Endpoint* endpoint = iter->second.get();
|
||
++iter;
|
||
|
||
- if (endpoint->client())
|
||
+ if (endpoint->client()) {
|
||
endpoints_to_notify.push_back(endpoint);
|
||
+ }
|
||
|
||
- MarkPeerClosedAndMaybeRemove(endpoint);
|
||
+ if (MarkPeerClosed(endpoint)) {
|
||
+ endpoints_to_remove.push_back(endpoint->id());
|
||
+ }
|
||
}
|
||
|
||
for (auto& endpoint : endpoints_to_notify) {
|
||
@@ -772,6 +775,10 @@ class ChannelAssociatedGroupController
|
||
if (endpoint->client())
|
||
NotifyEndpointOfError(endpoint.get(), false /* force_async */);
|
||
}
|
||
+
|
||
+ for (uint32_t id : endpoints_to_remove) {
|
||
+ endpoints_.erase(id);
|
||
+ }
|
||
}
|
||
|
||
void NotifyEndpointOfError(Endpoint* endpoint, bool force_async) {
|
||
@@ -806,19 +813,33 @@ class ChannelAssociatedGroupController
|
||
NotifyEndpointOfError(endpoint, false /* force_async */);
|
||
}
|
||
|
||
- void MarkClosedAndMaybeRemove(Endpoint* endpoint) {
|
||
+ // Marks `endpoint` as closed and returns true if and only if its peer was
|
||
+ // also already closed.
|
||
+ bool MarkClosed(Endpoint* endpoint) {
|
||
lock_.AssertAcquired();
|
||
endpoint->set_closed();
|
||
- if (endpoint->closed() && endpoint->peer_closed())
|
||
- endpoints_.erase(endpoint->id());
|
||
+ return endpoint->peer_closed();
|
||
}
|
||
|
||
- void MarkPeerClosedAndMaybeRemove(Endpoint* endpoint) {
|
||
+ // Marks `endpoint` as having a closed peer and returns true if and only if
|
||
+ // `endpoint` itself was also already closed.
|
||
+ bool MarkPeerClosed(Endpoint* endpoint) {
|
||
lock_.AssertAcquired();
|
||
endpoint->set_peer_closed();
|
||
endpoint->SignalSyncMessageEvent();
|
||
- if (endpoint->closed() && endpoint->peer_closed())
|
||
+ return endpoint->closed();
|
||
+ }
|
||
+
|
||
+ void MarkClosedAndMaybeRemove(Endpoint* endpoint) {
|
||
+ if (MarkClosed(endpoint)) {
|
||
endpoints_.erase(endpoint->id());
|
||
+ }
|
||
+ }
|
||
+
|
||
+ void MarkPeerClosedAndMaybeRemove(Endpoint* endpoint) {
|
||
+ if (MarkPeerClosed(endpoint)) {
|
||
+ endpoints_.erase(endpoint->id());
|
||
+ }
|
||
}
|
||
|
||
Endpoint* FindOrInsertEndpoint(mojo::InterfaceId id, bool* inserted) {
|
||
From 4d095ba080045a255cb93ecadb9f3358fdc7cd80 Mon Sep 17 00:00:00 2001
|
||
From: Jordan Bayles <jophba@chromium.org>
|
||
Date: Fri, 6 Oct 2023 23:50:59 +0000
|
||
Subject: [PATCH] [Backport] CVE-2023-6510: Use after free in Media Capture
|
||
|
||
Manual backport of patch originally reviewed on
|
||
Fix UaF in WebContentsFrameTracker
|
||
|
||
This patch fixes a use-after-free by moving to a base::WeakPtr
|
||
instead of a raw_ptr. Looking at the callstack in the referenced bug, what is clearly happening is that the frame tracker is deleted AFTER the capture device. I believe that this is due to the MouseCursorOverlayController being deleted through the DeleteOnUIThread destructor, which, if you are already on the UI thread, is synchronous:
|
||
|
||
https://source.chromium.org/chromium/chromium/src/+/main:content/public/browser/browser_thread.h;l=141?q=BrowserThread::DeleteOnThread&ss=chromium%2Fchromium%2Fsrc
|
||
|
||
In comparison, the WebContentsFrameTracker is implemented using base::SequenceBound, which ends up calling an internal destruct method that ALWAYS posts back a task:
|
||
|
||
https://source.chromium.org/chromium/chromium/src/+/main:base/threading/sequence_bound_internal.h;drc=f5bdc89c7395ed24f1b8d196a3bdd6232d5bf771;l=122
|
||
|
||
So, this bug is ultimately caused by the simple fact that base::SequenceBound does NOT have an optimization to not post a deletion task if we are already running on that sequence. There may be a good followup task here to change either DeleteOnThread or base::SequenceBound to have the same behavior, however I think this change a good first step.
|
||
|
||
Bug: 1480152
|
||
Change-Id: Iee2d41e66b10403d6c78547bcbe84d2454236d5b
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4908770
|
||
Reviewed-by: Mark Foltz <mfoltz@chromium.org>
|
||
Commit-Queue: Jordan Bayles <jophba@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#1206698}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/523700
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../web_contents_video_capture_device.cc | 19 ++++++++++++-------
|
||
1 file changed, 12 insertions(+), 7 deletions(-)
|
||
|
||
diff --git a/chromium/content/browser/media/capture/web_contents_video_capture_device.cc b/chromium/content/browser/media/capture/web_contents_video_capture_device.cc
|
||
index 0093df22c2b2..6100fe816784 100644
|
||
--- src/3rdparty/chromium/content/browser/media/capture/web_contents_video_capture_device.cc.orig
|
||
+++ src/3rdparty/chromium/content/browser/media/capture/web_contents_video_capture_device.cc
|
||
@@ -41,7 +41,7 @@ class WebContentsVideoCaptureDevice::FrameTracker
|
||
int main_render_frame_id)
|
||
: device_(std::move(device)),
|
||
device_task_runner_(base::ThreadTaskRunnerHandle::Get()),
|
||
- cursor_controller_(cursor_controller) {
|
||
+ cursor_controller_(cursor_controller->GetWeakPtr()) {
|
||
DCHECK(device_task_runner_);
|
||
DCHECK(cursor_controller_);
|
||
|
||
@@ -184,7 +184,9 @@ class WebContentsVideoCaptureDevice::FrameTracker
|
||
// Note: MouseCursorOverlayController runs on the UI thread. It's also
|
||
// important that SetTargetView() be called in the current stack while
|
||
// |native_view| is known to be a valid pointer. http://crbug.com/818679
|
||
- cursor_controller_->SetTargetView(native_view);
|
||
+ if (cursor_controller_) {
|
||
+ cursor_controller_->SetTargetView(native_view);
|
||
+ }
|
||
}
|
||
} else {
|
||
device_task_runner_->PostTask(
|
||
@@ -192,7 +194,9 @@ class WebContentsVideoCaptureDevice::FrameTracker
|
||
base::BindOnce(
|
||
&WebContentsVideoCaptureDevice::OnTargetPermanentlyLost,
|
||
device_));
|
||
- cursor_controller_->SetTargetView(gfx::NativeView());
|
||
+ if (cursor_controller_) {
|
||
+ cursor_controller_->SetTargetView(gfx::NativeView());
|
||
+ }
|
||
}
|
||
}
|
||
|
||
@@ -200,10 +204,11 @@ class WebContentsVideoCaptureDevice::FrameTracker
|
||
const base::WeakPtr<WebContentsVideoCaptureDevice> device_;
|
||
const scoped_refptr<base::SingleThreadTaskRunner> device_task_runner_;
|
||
|
||
- // Owned by FrameSinkVideoCaptureDevice. This will be valid for the life of
|
||
- // FrameTracker because the FrameTracker deleter task will be posted to the UI
|
||
- // thread before the MouseCursorOverlayController deleter task.
|
||
- MouseCursorOverlayController* const cursor_controller_;
|
||
+ // Owned by FrameSinkVideoCaptureDevice. This may only be accessed on the
|
||
+ // UI thread. This is not guaranteed to be valid and must be checked before
|
||
+ // use.
|
||
+ // https://crbug.com/1480152
|
||
+ const base::WeakPtr<MouseCursorOverlayController> cursor_controller_;
|
||
|
||
viz::FrameSinkId target_frame_sink_id_;
|
||
gfx::NativeView target_native_view_ = gfx::NativeView();
|
||
From 6a382d96ac3becf92f28f8549318390193da1ddd Mon Sep 17 00:00:00 2001
|
||
From: pthier <pthier@chromium.org>
|
||
Date: Tue, 24 Oct 2023 13:28:22 +0200
|
||
Subject: [PATCH] [Backport] Security bug 1488199 (1/2)
|
||
|
||
Manual backport of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/v8/v8/+/4971832:
|
||
[regexp] Fix stack check in native code when interrupt was requested
|
||
|
||
When an interrupt was requested at the time we hit the stack check, the
|
||
check to ensure we have enough space for local variables was skipped.
|
||
|
||
Bug: chromium:1488199
|
||
Change-Id: I95d82fe737420d2ef43c1ace35560cfd5860829b
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4971832
|
||
Commit-Queue: Patrick Thier <pthier@chromium.org>
|
||
Reviewed-by: Jakob Linke <jgruber@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#90560}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/523701
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../regexp/arm/regexp-macro-assembler-arm.cc | 22 +++++++-----
|
||
.../regexp/arm/regexp-macro-assembler-arm.h | 5 +--
|
||
.../arm64/regexp-macro-assembler-arm64.cc | 21 ++++++-----
|
||
.../arm64/regexp-macro-assembler-arm64.h | 6 ++--
|
||
.../ia32/regexp-macro-assembler-ia32.cc | 19 ++++++----
|
||
.../regexp/ia32/regexp-macro-assembler-ia32.h | 5 +--
|
||
.../v8/src/regexp/regexp-macro-assembler.cc | 5 +--
|
||
.../v8/src/regexp/regexp-macro-assembler.h | 2 +-
|
||
.../regexp/x64/regexp-macro-assembler-x64.cc | 35 ++++++++++++-------
|
||
.../regexp/x64/regexp-macro-assembler-x64.h | 4 +--
|
||
10 files changed, 78 insertions(+), 46 deletions(-)
|
||
|
||
diff --git a/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.cc b/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||
index 78b586e265d0..099fc62fa07b 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.cc.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||
@@ -670,11 +670,13 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
||
__ mov(r0, Operand(stack_limit));
|
||
__ ldr(r0, MemOperand(r0));
|
||
__ sub(r0, sp, r0, SetCC);
|
||
+ Operand extra_space_for_variables(num_registers_ * kPointerSize);
|
||
+
|
||
// Handle it if the stack pointer is already below the stack limit.
|
||
__ b(ls, &stack_limit_hit);
|
||
// Check if there is room for the variable number of registers above
|
||
// the stack limit.
|
||
- __ cmp(r0, Operand(num_registers_ * kPointerSize));
|
||
+ __ cmp(r0, extra_space_for_variables);
|
||
__ b(hs, &stack_ok);
|
||
// Exit with OutOfMemory exception. There is not enough space on the stack
|
||
// for our working registers.
|
||
@@ -682,7 +684,7 @@ Handle<HeapObject> RegExpMacroAssemblerARM::GetCode(Handle<String> source) {
|
||
__ jmp(&return_r0);
|
||
|
||
__ bind(&stack_limit_hit);
|
||
- CallCheckStackGuardState();
|
||
+ CallCheckStackGuardState(extra_space_for_variables);
|
||
__ cmp(r0, Operand::Zero());
|
||
// If returned value is non-zero, we exit with the returned value as result.
|
||
__ b(ne, &return_r0);
|
||
@@ -1048,16 +1050,18 @@ void RegExpMacroAssemblerARM::WriteStackPointerToRegister(int reg) {
|
||
|
||
// Private methods:
|
||
|
||
-void RegExpMacroAssemblerARM::CallCheckStackGuardState() {
|
||
+void RegExpMacroAssemblerARM::CallCheckStackGuardState(Operand extra_space) {
|
||
DCHECK(!isolate()->IsGeneratingEmbeddedBuiltins());
|
||
DCHECK(!masm_->options().isolate_independent_code);
|
||
|
||
- __ PrepareCallCFunction(3);
|
||
+ __ PrepareCallCFunction(4);
|
||
|
||
+ // Extra space for variables to consider in stack check.
|
||
+ __ mov(arg_reg_4, extra_space);
|
||
// RegExp code frame pointer.
|
||
- __ mov(r2, frame_pointer());
|
||
+ __ mov(arg_reg3, frame_pointer());
|
||
// Code of self.
|
||
- __ mov(r1, Operand(masm_->CodeObject()));
|
||
+ __ mov(arg_reg2, Operand(masm_->CodeObject()));
|
||
|
||
// We need to make room for the return address on the stack.
|
||
int stack_alignment = base::OS::ActivationFrameAlignment();
|
||
@@ -1101,7 +1105,8 @@ static T* frame_entry_address(Address re_frame, int frame_offset) {
|
||
|
||
int RegExpMacroAssemblerARM::CheckStackGuardState(Address* return_address,
|
||
Address raw_code,
|
||
- Address re_frame) {
|
||
+ Address re_frame,
|
||
+ uintptr_t extra_space) {
|
||
Code re_code = Code::cast(Object(raw_code));
|
||
return NativeRegExpMacroAssembler::CheckStackGuardState(
|
||
frame_entry<Isolate*>(re_frame, kIsolate),
|
||
@@ -1110,7 +1115,8 @@ int RegExpMacroAssemblerARM::CheckStackGuardState(Address* return_address,
|
||
return_address, re_code,
|
||
frame_entry_address<Address>(re_frame, kInputString),
|
||
frame_entry_address<const byte*>(re_frame, kInputStart),
|
||
- frame_entry_address<const byte*>(re_frame, kInputEnd));
|
||
+ frame_entry_address<const byte*>(re_frame, kInputEnd),
|
||
+ extra_space);
|
||
}
|
||
|
||
|
||
diff --git a/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.h b/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.h
|
||
index 910e5c46079a..114120755fcb 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.h.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.h
|
||
@@ -89,7 +89,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerARM
|
||
// returning.
|
||
// {raw_code} is an Address because this is called via ExternalReference.
|
||
static int CheckStackGuardState(Address* return_address, Address raw_code,
|
||
- Address re_frame);
|
||
+ Address re_frame, uintptr_t extra_space);
|
||
|
||
private:
|
||
// Offsets from frame_pointer() of function parameters and stored registers.
|
||
@@ -134,7 +134,8 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerARM
|
||
|
||
|
||
// Generate a call to CheckStackGuardState.
|
||
- void CallCheckStackGuardState();
|
||
+ void CallCheckStackGuardState(
|
||
+ Operand extra_space_for_variables = Operand::Zero());
|
||
|
||
// The ebp-relative location of a regexp register.
|
||
MemOperand register_location(int register_index);
|
||
diff --git a/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc b/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
|
||
index ac33f8631ffe..1e5342dd42e5 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
|
||
@@ -781,13 +781,14 @@ Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
|
||
__ Mov(x10, stack_limit);
|
||
__ Ldr(x10, MemOperand(x10));
|
||
__ Subs(x10, sp, x10);
|
||
+ Operand extra_space_for_variables(num_wreg_to_allocate * kWRegSize);
|
||
|
||
// Handle it if the stack pointer is already below the stack limit.
|
||
__ B(ls, &stack_limit_hit);
|
||
|
||
// Check if there is room for the variable number of registers above
|
||
// the stack limit.
|
||
- __ Cmp(x10, num_wreg_to_allocate * kWRegSize);
|
||
+ __ Cmp(x10, extra_space_for_variables);
|
||
__ B(hs, &stack_ok);
|
||
|
||
// Exit with OutOfMemory exception. There is not enough space on the stack
|
||
@@ -796,7 +797,7 @@ Handle<HeapObject> RegExpMacroAssemblerARM64::GetCode(Handle<String> source) {
|
||
__ B(&return_w0);
|
||
|
||
__ Bind(&stack_limit_hit);
|
||
- CallCheckStackGuardState(x10);
|
||
+ CallCheckStackGuardState(x10, extra_space_for_variables);
|
||
// If returned value is non-zero, we exit with the returned value as result.
|
||
__ Cbnz(w0, &return_w0);
|
||
|
||
@@ -1332,13 +1333,14 @@ static T* frame_entry_address(Address re_frame, int frame_offset) {
|
||
|
||
int RegExpMacroAssemblerARM64::CheckStackGuardState(
|
||
Address* return_address, Address raw_code, Address re_frame,
|
||
- int start_index, const byte** input_start, const byte** input_end) {
|
||
+ int start_index, const byte** input_start, const byte** input_end,
|
||
+ uintptr_t extra_space) {
|
||
Code re_code = Code::cast(Object(raw_code));
|
||
return NativeRegExpMacroAssembler::CheckStackGuardState(
|
||
frame_entry<Isolate*>(re_frame, kIsolate), start_index,
|
||
static_cast<RegExp::CallOrigin>(frame_entry<int>(re_frame, kDirectCall)),
|
||
return_address, re_code, frame_entry_address<Address>(re_frame, kInput),
|
||
- input_start, input_end);
|
||
+ input_start, input_end, extra_space);
|
||
}
|
||
|
||
|
||
@@ -1357,21 +1359,24 @@ void RegExpMacroAssemblerARM64::CheckPosition(int cp_offset,
|
||
|
||
// Private methods:
|
||
|
||
-void RegExpMacroAssemblerARM64::CallCheckStackGuardState(Register scratch) {
|
||
+void RegExpMacroAssemblerARM64::CallCheckStackGuardState(Register scratch,
|
||
+ Operand extra_space) {
|
||
DCHECK(!isolate()->IsGeneratingEmbeddedBuiltins());
|
||
DCHECK(!masm_->options().isolate_independent_code);
|
||
|
||
// Allocate space on the stack to store the return address. The
|
||
// CheckStackGuardState C++ function will override it if the code
|
||
- // moved. Allocate extra space for 2 arguments passed by pointers.
|
||
- // AAPCS64 requires the stack to be 16 byte aligned.
|
||
+ // moved. Allocate extra space for 3 arguments (2 for input start/end and 1
|
||
+ // for gap). AAPCS64 requires the stack to be 16 byte aligned.
|
||
int alignment = masm_->ActivationFrameAlignment();
|
||
DCHECK_EQ(alignment % 16, 0);
|
||
int align_mask = (alignment / kXRegSize) - 1;
|
||
- int xreg_to_claim = (3 + align_mask) & ~align_mask;
|
||
+ int xreg_to_claim = (4 + align_mask) & ~align_mask;
|
||
|
||
__ Claim(xreg_to_claim);
|
||
|
||
+ __ Mov(x0, extra_space);
|
||
+ __ Poke(x0, 3 * kSystemPointerSize);
|
||
// CheckStackGuardState needs the end and start addresses of the input string.
|
||
__ Poke(input_end(), 2 * kSystemPointerSize);
|
||
__ Add(x5, sp, 2 * kSystemPointerSize);
|
||
diff --git a/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.h b/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.h
|
||
index aeb49aa9fff3..e4c4b0ac34f3 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.h.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.h
|
||
@@ -97,7 +97,8 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerARM64
|
||
static int CheckStackGuardState(Address* return_address, Address raw_code,
|
||
Address re_frame, int start_offset,
|
||
const byte** input_start,
|
||
- const byte** input_end);
|
||
+ const byte** input_end,
|
||
+ uintptr_t extra_space);
|
||
|
||
private:
|
||
// Above the frame pointer - Stored registers and stack passed parameters.
|
||
@@ -145,7 +146,8 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerARM64
|
||
void CheckStackLimit();
|
||
|
||
// Generate a call to CheckStackGuardState.
|
||
- void CallCheckStackGuardState(Register scratch);
|
||
+ void CallCheckStackGuardState(Register scratch,
|
||
+ Operand extra_space = Operand(0));
|
||
|
||
// Location of a 32 bit position register.
|
||
MemOperand register_location(int register_index);
|
||
diff --git a/chromium/v8/src/regexp/ia32/regexp-macro-assembler-ia32.cc b/chromium/v8/src/regexp/ia32/regexp-macro-assembler-ia32.cc
|
||
index 2135e977a742..d5fbd960675e 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/ia32/regexp-macro-assembler-ia32.cc.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/ia32/regexp-macro-assembler-ia32.cc
|
||
@@ -700,11 +700,13 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
||
ExternalReference::address_of_jslimit(isolate());
|
||
__ mov(ecx, esp);
|
||
__ sub(ecx, StaticVariable(stack_limit));
|
||
+ Immediate extra_space_for_variables(num_registers_ * kSystemPointerSize);
|
||
+
|
||
// Handle it if the stack pointer is already below the stack limit.
|
||
__ j(below_equal, &stack_limit_hit);
|
||
// Check if there is room for the variable number of registers above
|
||
// the stack limit.
|
||
- __ cmp(ecx, num_registers_ * kSystemPointerSize);
|
||
+ __ cmp(ecx, extra_space_for_variables);
|
||
__ j(above_equal, &stack_ok);
|
||
// Exit with OutOfMemory exception. There is not enough space on the stack
|
||
// for our working registers.
|
||
@@ -712,7 +714,7 @@ Handle<HeapObject> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
||
__ jmp(&return_eax);
|
||
|
||
__ bind(&stack_limit_hit);
|
||
- CallCheckStackGuardState(ebx);
|
||
+ CallCheckStackGuardState(ebx, extra_space_for_variables);
|
||
__ or_(eax, eax);
|
||
// If returned value is non-zero, we exit with the returned value as result.
|
||
__ j(not_zero, &return_eax);
|
||
@@ -1080,9 +1082,12 @@ void RegExpMacroAssemblerIA32::WriteStackPointerToRegister(int reg) {
|
||
|
||
// Private methods:
|
||
|
||
-void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) {
|
||
- static const int num_arguments = 3;
|
||
+void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch,
|
||
+ Immediate extra_space) {
|
||
+ static const int num_arguments = 4;
|
||
__ PrepareCallCFunction(num_arguments, scratch);
|
||
+ // Extra space for variables.
|
||
+ __ mov(Operand(esp, 3 * kSystemPointerSize), extra_space);
|
||
// RegExp code frame pointer.
|
||
__ mov(Operand(esp, 2 * kSystemPointerSize), ebp);
|
||
// Code of self.
|
||
@@ -1113,7 +1118,8 @@ static T* frame_entry_address(Address re_frame, int frame_offset) {
|
||
|
||
int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address,
|
||
Address raw_code,
|
||
- Address re_frame) {
|
||
+ Address re_frame,
|
||
+ uintptr_t extra_space) {
|
||
Code re_code = Code::cast(Object(raw_code));
|
||
return NativeRegExpMacroAssembler::CheckStackGuardState(
|
||
frame_entry<Isolate*>(re_frame, kIsolate),
|
||
@@ -1122,7 +1128,8 @@ int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address,
|
||
return_address, re_code,
|
||
frame_entry_address<Address>(re_frame, kInputString),
|
||
frame_entry_address<const byte*>(re_frame, kInputStart),
|
||
- frame_entry_address<const byte*>(re_frame, kInputEnd));
|
||
+ frame_entry_address<const byte*>(re_frame, kInputEnd),
|
||
+ extra_space);
|
||
}
|
||
|
||
|
||
diff --git a/chromium/v8/src/regexp/ia32/regexp-macro-assembler-ia32.h b/chromium/v8/src/regexp/ia32/regexp-macro-assembler-ia32.h
|
||
index a30bff29a15c..620e7fb2982e 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/ia32/regexp-macro-assembler-ia32.h.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/ia32/regexp-macro-assembler-ia32.h
|
||
@@ -88,7 +88,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerIA32
|
||
// returning.
|
||
// {raw_code} is an Address because this is called via ExternalReference.
|
||
static int CheckStackGuardState(Address* return_address, Address raw_code,
|
||
- Address re_frame);
|
||
+ Address re_frame, uintptr_t extra_space);
|
||
|
||
private:
|
||
Operand StaticVariable(const ExternalReference& ext);
|
||
@@ -133,7 +133,8 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerIA32
|
||
void CheckStackLimit();
|
||
|
||
// Generate a call to CheckStackGuardState.
|
||
- void CallCheckStackGuardState(Register scratch);
|
||
+ void CallCheckStackGuardState(Register scratch,
|
||
+ Immediate extra_space = Immediate(0));
|
||
|
||
// The ebp-relative location of a regexp register.
|
||
Operand register_location(int register_index);
|
||
diff --git a/chromium/v8/src/regexp/regexp-macro-assembler.cc b/chromium/v8/src/regexp/regexp-macro-assembler.cc
|
||
index cf4346309eb2..009027c10398 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/regexp-macro-assembler.cc.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/regexp-macro-assembler.cc
|
||
@@ -168,14 +168,15 @@ bool NativeRegExpMacroAssembler::CanReadUnaligned() {
|
||
int NativeRegExpMacroAssembler::CheckStackGuardState(
|
||
Isolate* isolate, int start_index, RegExp::CallOrigin call_origin,
|
||
Address* return_address, Code re_code, Address* subject,
|
||
- const byte** input_start, const byte** input_end) {
|
||
+ const byte** input_start, const byte** input_end,
|
||
+ uintptr_t gap) {
|
||
DisallowHeapAllocation no_gc;
|
||
Address old_pc = PointerAuthentication::AuthenticatePC(return_address, 0);
|
||
DCHECK_LE(re_code.raw_instruction_start(), old_pc);
|
||
DCHECK_LE(old_pc, re_code.raw_instruction_end());
|
||
|
||
StackLimitCheck check(isolate);
|
||
- bool js_has_overflowed = check.JsHasOverflowed();
|
||
+ bool js_has_overflowed = check.JsHasOverflowed(gap);
|
||
|
||
if (call_origin == RegExp::CallOrigin::kFromJs) {
|
||
// Direct calls from JavaScript can be interrupted in two ways:
|
||
diff --git a/chromium/v8/src/regexp/regexp-macro-assembler.h b/chromium/v8/src/regexp/regexp-macro-assembler.h
|
||
index 52465610cb66..da233d3c73df 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/regexp-macro-assembler.h.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/regexp-macro-assembler.h
|
||
@@ -261,7 +261,7 @@ class NativeRegExpMacroAssembler: public RegExpMacroAssembler {
|
||
RegExp::CallOrigin call_origin,
|
||
Address* return_address, Code re_code,
|
||
Address* subject, const byte** input_start,
|
||
- const byte** input_end);
|
||
+ const byte** input_end, uintptr_t gap);
|
||
|
||
// Byte map of one byte characters with a 0xff if the character is a word
|
||
// character (digit, letter or underscore) and 0x00 otherwise.
|
||
diff --git a/chromium/v8/src/regexp/x64/regexp-macro-assembler-x64.cc b/chromium/v8/src/regexp/x64/regexp-macro-assembler-x64.cc
|
||
index da0397689fba..6ae1114f24ef 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/x64/regexp-macro-assembler-x64.cc.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/x64/regexp-macro-assembler-x64.cc
|
||
@@ -736,11 +736,13 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
||
__ movq(rcx, rsp);
|
||
__ Move(kScratchRegister, stack_limit);
|
||
__ subq(rcx, Operand(kScratchRegister, 0));
|
||
+ Immediate extra_space_for_variables(num_registers_ * kSystemPointerSize);
|
||
+
|
||
// Handle it if the stack pointer is already below the stack limit.
|
||
__ j(below_equal, &stack_limit_hit);
|
||
// Check if there is room for the variable number of registers above
|
||
// the stack limit.
|
||
- __ cmpq(rcx, Immediate(num_registers_ * kSystemPointerSize));
|
||
+ __ cmpq(rcx, extra_space_for_variables);
|
||
__ j(above_equal, &stack_ok);
|
||
// Exit with OutOfMemory exception. There is not enough space on the stack
|
||
// for our working registers.
|
||
@@ -749,7 +751,8 @@ Handle<HeapObject> RegExpMacroAssemblerX64::GetCode(Handle<String> source) {
|
||
|
||
__ bind(&stack_limit_hit);
|
||
__ Move(code_object_pointer(), masm_.CodeObject());
|
||
- CallCheckStackGuardState(); // Preserves no registers beside rbp and rsp.
|
||
+ // CallCheckStackGuardState preserves no registers beside rbp and rsp.
|
||
+ CallCheckStackGuardState(extra_space_for_variables);
|
||
__ testq(rax, rax);
|
||
// If returned value is non-zero, we exit with the returned value as result.
|
||
__ j(not_zero, &return_rax);
|
||
@@ -1147,27 +1150,31 @@ void RegExpMacroAssemblerX64::WriteStackPointerToRegister(int reg) {
|
||
|
||
// Private methods:
|
||
|
||
-void RegExpMacroAssemblerX64::CallCheckStackGuardState() {
|
||
+void RegExpMacroAssemblerX64::CallCheckStackGuardState(Immediate extra_space) {
|
||
// This function call preserves no register values. Caller should
|
||
// store anything volatile in a C call or overwritten by this function.
|
||
- static const int num_arguments = 3;
|
||
+ static const int num_arguments = 4;
|
||
__ PrepareCallCFunction(num_arguments);
|
||
#ifdef V8_TARGET_OS_WIN
|
||
- // Second argument: Code of self. (Do this before overwriting r8).
|
||
- __ movq(rdx, code_object_pointer());
|
||
+ // Fourth argument: Extra space for variables.
|
||
+ __ movq(arg_reg_4, extra_space);
|
||
+ // Second argument: Code of self. (Do this before overwriting r8 (arg_reg_3)).
|
||
+ __ movq(arg_reg_2, code_object_pointer());
|
||
// Third argument: RegExp code frame pointer.
|
||
- __ movq(r8, rbp);
|
||
+ __ movq(arg_reg_3, rbp);
|
||
// First argument: Next address on the stack (will be address of
|
||
// return address).
|
||
- __ leaq(rcx, Operand(rsp, -kSystemPointerSize));
|
||
+ __ leaq(arg_reg_1, Operand(rsp, -kSystemPointerSize));
|
||
#else
|
||
+ // Fourth argument: Extra space for variables.
|
||
+ __ movq(arg_reg_4, extra_space);
|
||
// Third argument: RegExp code frame pointer.
|
||
- __ movq(rdx, rbp);
|
||
+ __ movq(arg_reg_3, rbp);
|
||
// Second argument: Code of self.
|
||
- __ movq(rsi, code_object_pointer());
|
||
+ __ movq(arg_reg_2, code_object_pointer());
|
||
// First argument: Next address on the stack (will be address of
|
||
// return address).
|
||
- __ leaq(rdi, Operand(rsp, -kSystemPointerSize));
|
||
+ __ leaq(arg_reg_1, Operand(rsp, -kSystemPointerSize));
|
||
#endif
|
||
ExternalReference stack_check =
|
||
ExternalReference::re_check_stack_guard_state(isolate());
|
||
@@ -1189,7 +1196,8 @@ static T* frame_entry_address(Address re_frame, int frame_offset) {
|
||
|
||
int RegExpMacroAssemblerX64::CheckStackGuardState(Address* return_address,
|
||
Address raw_code,
|
||
- Address re_frame) {
|
||
+ Address re_frame,
|
||
+ uintptr_t extra_space) {
|
||
Code re_code = Code::cast(Object(raw_code));
|
||
return NativeRegExpMacroAssembler::CheckStackGuardState(
|
||
frame_entry<Isolate*>(re_frame, kIsolate),
|
||
@@ -1198,7 +1206,8 @@ int RegExpMacroAssemblerX64::CheckStackGuardState(Address* return_address,
|
||
return_address, re_code,
|
||
frame_entry_address<Address>(re_frame, kInputString),
|
||
frame_entry_address<const byte*>(re_frame, kInputStart),
|
||
- frame_entry_address<const byte*>(re_frame, kInputEnd));
|
||
+ frame_entry_address<const byte*>(re_frame, kInputEnd),
|
||
+ extra_space);
|
||
}
|
||
|
||
|
||
diff --git a/chromium/v8/src/regexp/x64/regexp-macro-assembler-x64.h b/chromium/v8/src/regexp/x64/regexp-macro-assembler-x64.h
|
||
index ea4d45edba83..6e5dcd18c286 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/x64/regexp-macro-assembler-x64.h.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/x64/regexp-macro-assembler-x64.h
|
||
@@ -82,7 +82,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerX64
|
||
// returning.
|
||
// {raw_code} is an Address because this is called via ExternalReference.
|
||
static int CheckStackGuardState(Address* return_address, Address raw_code,
|
||
- Address re_frame);
|
||
+ Address re_frame, uintptr_t extra_space);
|
||
|
||
private:
|
||
// Offsets from rbp of function parameters and stored registers.
|
||
@@ -166,7 +166,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerX64
|
||
void CheckStackLimit();
|
||
|
||
// Generate a call to CheckStackGuardState.
|
||
- void CallCheckStackGuardState();
|
||
+ void CallCheckStackGuardState(Immediate extra_space = Immediate(0));
|
||
|
||
// The rbp-relative location of a regexp register.
|
||
Operand register_location(int register_index);
|
||
From a3a63cf72f11a9e1a40fd076dea0ce8f532251ba Mon Sep 17 00:00:00 2001
|
||
From: pthier <pthier@chromium.org>
|
||
Date: Mon, 30 Oct 2023 11:59:09 +0100
|
||
Subject: [PATCH] [Backport] Security bug 1488199 (2/2)
|
||
|
||
Manual backport of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/v8/v8/+/4987306:
|
||
[regexp][arm64] Fix stack check extra space argument
|
||
|
||
Pass argument in register instead of the stack.
|
||
|
||
Bug: chromium:1488199, v8:14415
|
||
Change-Id: Ic9967c9f2ca5da1981a0138ddb5f0335ab7f1425
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/4987306
|
||
Commit-Queue: Patrick Thier <pthier@chromium.org>
|
||
Reviewed-by: Camillo Bruni <cbruni@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#90669}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/523702
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc | 9 ++++-----
|
||
1 file changed, 4 insertions(+), 5 deletions(-)
|
||
|
||
diff --git a/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc b/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
|
||
index 1e5342dd42e..aaab0c52344 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc.orig
|
||
+++ src/3rdparty/chromium/v8/src/regexp/arm64/regexp-macro-assembler-arm64.cc
|
||
@@ -1366,17 +1366,16 @@ void RegExpMacroAssemblerARM64::CallCheckStackGuardState(Register scratch,
|
||
|
||
// Allocate space on the stack to store the return address. The
|
||
// CheckStackGuardState C++ function will override it if the code
|
||
- // moved. Allocate extra space for 3 arguments (2 for input start/end and 1
|
||
- // for gap). AAPCS64 requires the stack to be 16 byte aligned.
|
||
+ // moved. Allocate extra space for 2 arguments passed by pointers.
|
||
+ // AAPCS64 requires the stack to be 16 byte aligned.
|
||
int alignment = masm_->ActivationFrameAlignment();
|
||
DCHECK_EQ(alignment % 16, 0);
|
||
int align_mask = (alignment / kXRegSize) - 1;
|
||
- int xreg_to_claim = (4 + align_mask) & ~align_mask;
|
||
+ int xreg_to_claim = (3 + align_mask) & ~align_mask;
|
||
|
||
__ Claim(xreg_to_claim);
|
||
|
||
- __ Mov(x0, extra_space);
|
||
- __ Poke(x0, 3 * kSystemPointerSize);
|
||
+ __ Mov(x6, extra_space);
|
||
// CheckStackGuardState needs the end and start addresses of the input string.
|
||
__ Poke(input_end(), 2 * kSystemPointerSize);
|
||
__ Add(x5, sp, 2 * kSystemPointerSize);
|
||
From 7eb931bc199e72fbf95aed22c9dd370269862c6c Mon Sep 17 00:00:00 2001
|
||
From: Michal Klocek <michal.klocek@qt.io>
|
||
Date: Mon, 8 Jan 2024 11:23:07 +0100
|
||
Subject: [PATCH] [Backport] CVE-2023-6345: Integer overflow in Skia
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
Cherry-pick of patch originally reviewed on
|
||
https://skia-review.googlesource.com/c/skia/+/782936:
|
||
Avoid combining extremely large meshes.
|
||
|
||
Bug: chromium:1505053
|
||
|
||
Fixes: QTBUG-120589
|
||
Change-Id: I42f2ff872bbf054686ec7af0cc85ff63055fcfbf
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/528729
|
||
Reviewed-by: Michael Brüning <michael.bruning@qt.io>
|
||
---
|
||
chromium/third_party/skia/src/gpu/ops/GrDrawVerticesOp.cpp | 6 +++++-
|
||
1 file changed, 5 insertions(+), 1 deletion(-)
|
||
|
||
diff --git a/chromium/third_party/skia/src/gpu/ops/GrDrawVerticesOp.cpp b/chromium/third_party/skia/src/gpu/ops/GrDrawVerticesOp.cpp
|
||
index 0a80e674325f..e50293b4dfe9 100644
|
||
--- src/3rdparty/chromium/third_party/skia/src/gpu/ops/GrDrawVerticesOp.cpp
|
||
+++ src/3rdparty/chromium/third_party/skia/src/gpu/ops/GrDrawVerticesOp.cpp
|
||
@@ -757,7 +757,11 @@ GrOp::CombineResult DrawVerticesOp::onCombineIfPossible(GrOp* t, GrRecordingCont
|
||
return CombineResult::kCannotCombine;
|
||
}
|
||
|
||
- if (fVertexCount + that->fVertexCount > SkTo<int>(UINT16_MAX)) {
|
||
+ if (fVertexCount > INT32_MAX - that->fVertexCount) {
|
||
+ return CombineResult::kCannotCombine;
|
||
+ }
|
||
+
|
||
+ if (fVertexCount > SkTo<int>(UINT16_MAX) - that->fVertexCount) {
|
||
return CombineResult::kCannotCombine;
|
||
}
|
||
|
||
From 31c7c9445955762102fdcd04e71da6114e1fcb4c Mon Sep 17 00:00:00 2001
|
||
From: Zakhar Voit <voit@google.com>
|
||
Date: Thu, 14 Dec 2023 11:11:43 +0000
|
||
Subject: [PATCH] [Backport] CVE-2023-6702: Type Confusion in V8
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
Manual backport of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/v8/v8/+/5110982:
|
||
[M114-LTS][promises, async stack traces] Fix the case when the closure has run
|
||
|
||
M114 changes:
|
||
- replace IsNativeContext(*context) by context->IsNativeContext()
|
||
|
||
We were using the closure pointing to NativeContext as a marker that the
|
||
closure has run, but async stack trace code was confused about it.
|
||
|
||
(cherry picked from commit bde3d360097607f36cd1d17cbe8412b84eae0a7f)
|
||
|
||
Bug: chromium:1501326
|
||
Change-Id: I30d438f3b2e3fdd7562ea9a79dde4561ce9b0083
|
||
Cr-Original-Commit-Position: refs/heads/main@{#90949}
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5110982
|
||
Commit-Queue: Marja Hölttä <marja@chromium.org>
|
||
Auto-Submit: Marja Hölttä <marja@chromium.org>
|
||
Cr-Commit-Position: refs/branch-heads/12.0@{#18}
|
||
Cr-Branched-From: ed7b4caf1fb8184ad9e24346c84424055d4d430a-refs/heads/12.0.267@{#1}
|
||
Cr-Branched-From: 210e75b19db4352c9b78dce0bae11c2dc3077df4-refs/heads/main@{#90651}
|
||
(cherry picked from commit cbd09b2ca928f1fd929ef52e173aa81213e38cb8)
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/526232
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
chromium/v8/src/execution/isolate.cc | 16 ++++++++++++++--
|
||
1 file changed, 14 insertions(+), 2 deletions(-)
|
||
|
||
diff --git a/chromium/v8/src/execution/isolate.cc b/chromium/v8/src/execution/isolate.cc
|
||
index c1c3bd1b24a6..99b851ef96d7 100644
|
||
--- src/3rdparty/chromium/v8/src/execution/isolate.cc
|
||
+++ src/3rdparty/chromium/v8/src/execution/isolate.cc
|
||
@@ -944,7 +944,13 @@ void CaptureAsyncStackTrace(Isolate* isolate, Handle<JSPromise> promise,
|
||
builder->AppendPromiseCombinatorFrame(function, combinator,
|
||
FrameArray::kIsPromiseAll, context);
|
||
|
||
- // Now peak into the Promise.all() resolve element context to
|
||
+ if (context->IsNativeContext()) {
|
||
+ // NativeContext is used as a marker that the closure was already
|
||
+ // called. We can't access the reject element context any more.
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ // Now peek into the Promise.all() resolve element context to
|
||
// find the promise capability that's being resolved when all
|
||
// the concurrent promises resolve.
|
||
int const index =
|
||
@@ -963,7 +969,13 @@ void CaptureAsyncStackTrace(Isolate* isolate, Handle<JSPromise> promise,
|
||
builder->AppendPromiseCombinatorFrame(function, combinator,
|
||
FrameArray::kIsPromiseAny, context);
|
||
|
||
- // Now peak into the Promise.any() reject element context to
|
||
+ if (context->IsNativeContext()) {
|
||
+ // NativeContext is used as a marker that the closure was already
|
||
+ // called. We can't access the reject element context any more.
|
||
+ return;
|
||
+ }
|
||
+
|
||
+ // Now peek into the Promise.any() reject element context to
|
||
// find the promise capability that's being resolved when any of
|
||
// the concurrent promises resolve.
|
||
int const index = PromiseBuiltins::kPromiseAnyRejectElementCapabilitySlot;
|
||
From 73c9c09a8b314b8c66bbe3d2648d6bfe18d5d4a8 Mon Sep 17 00:00:00 2001
|
||
From: Kai Ninomiya <kainino@chromium.org>
|
||
Date: Wed, 29 Nov 2023 17:44:48 +0000
|
||
Subject: [PATCH] [Backport] Security bug 1505632
|
||
|
||
Manual backport of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5069480:
|
||
Fix reinit order in ContextProviderCommandBuffer::BindToCurrentSequence
|
||
|
||
See comments for explanation.
|
||
|
||
Bug: 1505632
|
||
Change-Id: I0f43821a9708af91303048332e9fae5e100deee5
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5069480
|
||
Reviewed-by: Saifuddin Hitawala <hitawala@chromium.org>
|
||
Commit-Queue: Kai Ninomiya <kainino@chromium.org>
|
||
Reviewed-by: Brendon Tiszka <tiszka@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#1230735}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/526233
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../gpu/context_provider_command_buffer.cc | 24 +++++++++----
|
||
.../cpp/gpu/context_provider_command_buffer.h | 34 ++++++++++++++++---
|
||
2 files changed, 47 insertions(+), 11 deletions(-)
|
||
|
||
diff --git a/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.cc b/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
|
||
index e8b9ff4983d4..d79b97fd3748 100644
|
||
--- src/3rdparty/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
|
||
+++ src/3rdparty/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.cc
|
||
@@ -164,13 +164,13 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() {
|
||
}
|
||
|
||
// The transfer buffer is used to serialize Dawn commands
|
||
- transfer_buffer_ =
|
||
+ auto transfer_buffer =
|
||
std::make_unique<gpu::TransferBuffer>(webgpu_helper.get());
|
||
|
||
// The WebGPUImplementation exposes the WebGPUInterface, as well as the
|
||
// gpu::ContextSupport interface.
|
||
auto webgpu_impl = std::make_unique<gpu::webgpu::WebGPUImplementation>(
|
||
- webgpu_helper.get(), transfer_buffer_.get(), command_buffer_.get());
|
||
+ webgpu_helper.get(), transfer_buffer.get(), command_buffer_.get());
|
||
bind_result_ = webgpu_impl->Initialize(memory_limits_);
|
||
if (bind_result_ != gpu::ContextResult::kSuccess) {
|
||
DLOG(ERROR) << "Failed to initialize WebGPUImplementation.";
|
||
@@ -182,8 +182,11 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() {
|
||
std::string unique_context_name =
|
||
base::StringPrintf("%s-%p", type_name.c_str(), webgpu_impl.get());
|
||
|
||
+ // IMPORTANT: These hold raw_ptrs to each other, so must be set together.
|
||
+ // See note in the header (and keep it up to date if things change).
|
||
impl_ = webgpu_impl.get();
|
||
webgpu_interface_ = std::move(webgpu_impl);
|
||
+ transfer_buffer_ = std::move(transfer_buffer);
|
||
helper_ = std::move(webgpu_helper);
|
||
} else if (attributes_.enable_raster_interface &&
|
||
!attributes_.enable_gles2_interface &&
|
||
@@ -201,14 +204,14 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() {
|
||
}
|
||
// The transfer buffer is used to copy resources between the client
|
||
// process and the GPU process.
|
||
- transfer_buffer_ =
|
||
+ auto transfer_buffer =
|
||
std::make_unique<gpu::TransferBuffer>(raster_helper.get());
|
||
|
||
// The RasterImplementation exposes the RasterInterface, as well as the
|
||
// gpu::ContextSupport interface.
|
||
DCHECK(channel_);
|
||
auto raster_impl = std::make_unique<gpu::raster::RasterImplementation>(
|
||
- raster_helper.get(), transfer_buffer_.get(),
|
||
+ raster_helper.get(), transfer_buffer.get(),
|
||
attributes_.bind_generates_resource,
|
||
attributes_.lose_context_when_out_of_memory, command_buffer_.get(),
|
||
channel_->image_decode_accelerator_proxy());
|
||
@@ -225,8 +228,11 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() {
|
||
raster_impl->TraceBeginCHROMIUM("gpu_toplevel",
|
||
unique_context_name.c_str());
|
||
|
||
+ // IMPORTANT: These hold raw_ptrs to each other, so must be set together.
|
||
+ // See note in the header (and keep it up to date if things change).
|
||
impl_ = raster_impl.get();
|
||
raster_interface_ = std::move(raster_impl);
|
||
+ transfer_buffer_ = std::move(transfer_buffer);
|
||
helper_ = std::move(raster_helper);
|
||
} else {
|
||
// The GLES2 helper writes the command buffer protocol.
|
||
@@ -241,7 +247,7 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() {
|
||
|
||
// The transfer buffer is used to copy resources between the client
|
||
// process and the GPU process.
|
||
- transfer_buffer_ =
|
||
+ auto transfer_buffer =
|
||
std::make_unique<gpu::TransferBuffer>(gles2_helper.get());
|
||
|
||
// The GLES2Implementation exposes the OpenGLES2 API, as well as the
|
||
@@ -254,13 +260,13 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() {
|
||
// we only use it if grcontext_support was requested.
|
||
gles2_impl = std::make_unique<
|
||
skia_bindings::GLES2ImplementationWithGrContextSupport>(
|
||
- gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer_.get(),
|
||
+ gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer.get(),
|
||
attributes_.bind_generates_resource,
|
||
attributes_.lose_context_when_out_of_memory,
|
||
support_client_side_arrays, command_buffer_.get());
|
||
} else {
|
||
gles2_impl = std::make_unique<gpu::gles2::GLES2Implementation>(
|
||
- gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer_.get(),
|
||
+ gles2_helper.get(), /*share_group=*/nullptr, transfer_buffer.get(),
|
||
attributes_.bind_generates_resource,
|
||
attributes_.lose_context_when_out_of_memory,
|
||
support_client_side_arrays, command_buffer_.get());
|
||
@@ -271,8 +277,11 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() {
|
||
return bind_result_;
|
||
}
|
||
|
||
+ // IMPORTANT: These hold raw_ptrs to each other, so must be set together.
|
||
+ // See note in the header (and keep it up to date if things change).
|
||
impl_ = gles2_impl.get();
|
||
gles2_impl_ = std::move(gles2_impl);
|
||
+ transfer_buffer_ = std::move(transfer_buffer);
|
||
helper_ = std::move(gles2_helper);
|
||
}
|
||
|
||
@@ -306,6 +315,7 @@ gpu::ContextResult ContextProviderCommandBuffer::BindToCurrentThread() {
|
||
switches::kEnableGpuClientTracing)) {
|
||
// This wraps the real GLES2Implementation and we should always use this
|
||
// instead when it's present.
|
||
+ // IMPORTANT: This holds a raw_ptr to gles2_impl_.
|
||
trace_impl_ = std::make_unique<gpu::gles2::GLES2TraceImplementation>(
|
||
gles2_impl_.get());
|
||
gl = trace_impl_.get();
|
||
diff --git a/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.h b/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.h
|
||
index 22d80baf765b..9a867177048e 100644
|
||
--- src/3rdparty/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.h
|
||
+++ src/3rdparty/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.h
|
||
@@ -156,18 +156,44 @@ class ContextProviderCommandBuffer
|
||
// associated shared images are destroyed.
|
||
std::unique_ptr<gpu::ClientSharedImageInterface> shared_image_interface_;
|
||
|
||
- base::Lock context_lock_; // Referenced by command_buffer_.
|
||
+ //////////////////////////////////////////////////////////////////////////////
|
||
+ // IMPORTANT NOTE: All of the objects in this block are part of a complex //
|
||
+ // graph of raw pointers (holder or pointee of various raw_ptrs). They are //
|
||
+ // defined in topological order: only later items point to earlier items. //
|
||
+ // - When writing any member, always ensure its pointers to earlier members
|
||
+ // are guaranteed to stay alive.
|
||
+ // - When clearing OR overwriting any member, always ensure objects that
|
||
+ // point to it have already been cleared.
|
||
+ // - The topological order of definitions guarantees that the
|
||
+ // destructors will be called in the correct order (bottom to top).
|
||
+ // - When overwriting multiple members, similarly do so in reverse order.
|
||
+ //
|
||
+ // Please note these comments are likely not to stay perfectly up-to-date.
|
||
+
|
||
+ base::Lock context_lock_;
|
||
+ // Points to the context_lock_ field of `this`.
|
||
std::unique_ptr<gpu::CommandBufferProxyImpl> command_buffer_;
|
||
+
|
||
+ // Points to command_buffer_.
|
||
std::unique_ptr<gpu::CommandBufferHelper> helper_;
|
||
+ // Points to helper_.
|
||
std::unique_ptr<gpu::TransferBuffer> transfer_buffer_;
|
||
|
||
- // Owned by either gles2_impl_ or raster_interface_, not both.
|
||
- gpu::ImplementationBase* impl_;
|
||
+ // Points to transfer_buffer_, helper_, and command_buffer_.
|
||
std::unique_ptr<gpu::gles2::GLES2Implementation> gles2_impl_;
|
||
+ // Points to gles2_impl_.
|
||
std::unique_ptr<gpu::gles2::GLES2TraceImplementation> trace_impl_;
|
||
- std::unique_ptr<gpu::raster::RasterInterface> raster_interface_;
|
||
+ // Points to transfer_buffer_, helper_, and command_buffer_.
|
||
+ std::unique_ptr<gpu::raster::RasterInterface> raster_interface_;
|
||
+ // Points to transfer_buffer_, helper_, and command_buffer_.
|
||
std::unique_ptr<gpu::webgpu::WebGPUInterface> webgpu_interface_;
|
||
|
||
+ // END IMPORTANT NOTE //
|
||
+ //////////////////////////////////////////////////////////////////////////////
|
||
+
|
||
+ // Owned by either gles2_impl_ or raster_interface_, not both.
|
||
+ gpu::ImplementationBase* impl_;
|
||
+
|
||
std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_;
|
||
#if BUILDFLAG(SKIA_USE_DAWN)
|
||
std::unique_ptr<skia_bindings::GrContextForWebGPUInterface>
|
||
From 2d8ce130db72ce75e2ca8b51f3c32938fbff9143 Mon Sep 17 00:00:00 2001
|
||
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
|
||
Date: Mon, 8 Jan 2024 15:39:03 +0100
|
||
Subject: [PATCH] Fixup: [Backport] Security bug 1505632
|
||
|
||
Change-Id: I8af12a1fecededb373145fd89362e08b030f1d7f
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/528821
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../viz/public/cpp/gpu/context_provider_command_buffer.h | 2 +-
|
||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
||
diff --git a/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.h b/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.h
|
||
index 9a867177048..0ac70dae7e9 100644
|
||
--- src/3rdparty/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.h
|
||
+++ src/3rdparty/chromium/services/viz/public/cpp/gpu/context_provider_command_buffer.h
|
||
@@ -192,7 +192,7 @@ class ContextProviderCommandBuffer
|
||
//////////////////////////////////////////////////////////////////////////////
|
||
|
||
// Owned by either gles2_impl_ or raster_interface_, not both.
|
||
- gpu::ImplementationBase* impl_;
|
||
+ gpu::ImplementationBase* impl_ = nullptr;
|
||
|
||
std::unique_ptr<skia_bindings::GrContextForGLES2Interface> gr_context_;
|
||
#if BUILDFLAG(SKIA_USE_DAWN)
|
||
From c8088aea77818f87d42f709ddcb743b907c38e9c Mon Sep 17 00:00:00 2001
|
||
From: =?UTF-8?q?Michael=20Br=C3=BCning?= <michael.bruning@qt.io>
|
||
Date: Sun, 14 Jan 2024 23:48:08 +0100
|
||
Subject: [PATCH] Fixup: [Backport] Security bug 1488199
|
||
|
||
Add register aliases following respective platform calling
|
||
conventions. Also fix a typo.
|
||
|
||
Change-Id: I8f844cd4db35393580f2a0adae6a4095584087a5
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/530618
|
||
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
|
||
---
|
||
chromium/v8/src/codegen/arm/register-arm.h | 6 ++++++
|
||
chromium/v8/src/codegen/arm64/register-arm64.h | 6 ++++++
|
||
chromium/v8/src/codegen/mips64/register-mips64.h | 6 ++++++
|
||
chromium/v8/src/codegen/ppc/register-ppc.h | 6 ++++++
|
||
chromium/v8/src/codegen/s390/register-s390.h | 6 ++++++
|
||
chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.cc | 4 ++--
|
||
6 files changed, 32 insertions(+), 2 deletions(-)
|
||
|
||
diff --git a/chromium/v8/src/codegen/arm/register-arm.h b/chromium/v8/src/codegen/arm/register-arm.h
|
||
index 6cb6c602c254..8deddc5804b1 100644
|
||
--- src/3rdparty/chromium/v8/src/codegen/arm/register-arm.h
|
||
+++ src/3rdparty/chromium/v8/src/codegen/arm/register-arm.h
|
||
@@ -119,6 +119,12 @@ GENERAL_REGISTERS(DECLARE_REGISTER)
|
||
#undef DECLARE_REGISTER
|
||
constexpr Register no_reg = Register::no_reg();
|
||
|
||
+// ARM calling convention
|
||
+constexpr Register arg_reg_1 = r0;
|
||
+constexpr Register arg_reg_2 = r1;
|
||
+constexpr Register arg_reg_3 = r2;
|
||
+constexpr Register arg_reg_4 = r3;
|
||
+
|
||
constexpr bool kPadArguments = false;
|
||
constexpr bool kSimpleFPAliasing = false;
|
||
constexpr bool kSimdMaskRegisters = false;
|
||
diff --git a/chromium/v8/src/codegen/arm64/register-arm64.h b/chromium/v8/src/codegen/arm64/register-arm64.h
|
||
index fbbb0a18dadf..06026a065bbf 100644
|
||
--- src/3rdparty/chromium/v8/src/codegen/arm64/register-arm64.h
|
||
+++ src/3rdparty/chromium/v8/src/codegen/arm64/register-arm64.h
|
||
@@ -482,6 +482,12 @@ ALIAS_REGISTER(VRegister, fp_scratch2, d31);
|
||
|
||
#undef ALIAS_REGISTER
|
||
|
||
+// Arm64 calling convention
|
||
+constexpr Register arg_reg_1 = x0;
|
||
+constexpr Register arg_reg_2 = x1;
|
||
+constexpr Register arg_reg_3 = x2;
|
||
+constexpr Register arg_reg_4 = x3;
|
||
+
|
||
// AreAliased returns true if any of the named registers overlap. Arguments set
|
||
// to NoReg are ignored. The system stack pointer may be specified.
|
||
V8_EXPORT_PRIVATE bool AreAliased(
|
||
diff --git a/chromium/v8/src/codegen/mips64/register-mips64.h b/chromium/v8/src/codegen/mips64/register-mips64.h
|
||
index d7b45eda3838..05aba9fcbd2f 100644
|
||
--- src/3rdparty/chromium/v8/src/codegen/mips64/register-mips64.h
|
||
+++ src/3rdparty/chromium/v8/src/codegen/mips64/register-mips64.h
|
||
@@ -362,6 +362,12 @@ DEFINE_REGISTER_NAMES(FPURegister, DOUBLE_REGISTERS)
|
||
DEFINE_REGISTER_NAMES(MSARegister, SIMD128_REGISTERS)
|
||
|
||
// Give alias names to registers for calling conventions.
|
||
+
|
||
+constexpr Register arg_reg_1 = a0;
|
||
+constexpr Register arg_reg_2 = a1;
|
||
+constexpr Register arg_reg_3 = a2;
|
||
+constexpr Register arg_reg_4 = a3;
|
||
+
|
||
constexpr Register kReturnRegister0 = v0;
|
||
constexpr Register kReturnRegister1 = v1;
|
||
constexpr Register kReturnRegister2 = a0;
|
||
diff --git a/chromium/v8/src/codegen/ppc/register-ppc.h b/chromium/v8/src/codegen/ppc/register-ppc.h
|
||
index eded9622c4cc..352b95192023 100644
|
||
--- src/3rdparty/chromium/v8/src/codegen/ppc/register-ppc.h
|
||
+++ src/3rdparty/chromium/v8/src/codegen/ppc/register-ppc.h
|
||
@@ -209,6 +209,12 @@ constexpr Register kConstantPoolRegister = r28; // Constant pool.
|
||
constexpr Register kRootRegister = r29; // Roots array pointer.
|
||
constexpr Register cp = r30; // JavaScript context pointer.
|
||
|
||
+// PPC64 calling convention
|
||
+constexpr Register arg_reg_1 = r3;
|
||
+constexpr Register arg_reg_2 = r4;
|
||
+constexpr Register arg_reg_3 = r5;
|
||
+constexpr Register arg_reg_4 = r6;
|
||
+
|
||
constexpr bool kPadArguments = false;
|
||
constexpr bool kSimpleFPAliasing = true;
|
||
constexpr bool kSimdMaskRegisters = false;
|
||
diff --git a/chromium/v8/src/codegen/s390/register-s390.h b/chromium/v8/src/codegen/s390/register-s390.h
|
||
index 009248a65ca0..6904802d0150 100644
|
||
--- src/3rdparty/chromium/v8/src/codegen/s390/register-s390.h
|
||
+++ src/3rdparty/chromium/v8/src/codegen/s390/register-s390.h
|
||
@@ -167,6 +167,12 @@ constexpr Register no_reg = Register::no_reg();
|
||
constexpr Register kRootRegister = r10; // Roots array pointer.
|
||
constexpr Register cp = r13; // JavaScript context pointer.
|
||
|
||
+// s390x calling convention
|
||
+constexpr Register arg_reg_1 = r2;
|
||
+constexpr Register arg_reg_2 = r3;
|
||
+constexpr Register arg_reg_3 = r4;
|
||
+constexpr Register arg_reg_4 = r5;
|
||
+
|
||
constexpr bool kPadArguments = false;
|
||
constexpr bool kSimpleFPAliasing = true;
|
||
constexpr bool kSimdMaskRegisters = false;
|
||
diff --git a/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.cc b/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||
index 099fc62fa07b..5580b24308a7 100644
|
||
--- src/3rdparty/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||
+++ src/3rdparty/chromium/v8/src/regexp/arm/regexp-macro-assembler-arm.cc
|
||
@@ -1059,9 +1059,9 @@ void RegExpMacroAssemblerARM::CallCheckStackGuardState(Operand extra_space) {
|
||
// Extra space for variables to consider in stack check.
|
||
__ mov(arg_reg_4, extra_space);
|
||
// RegExp code frame pointer.
|
||
- __ mov(arg_reg3, frame_pointer());
|
||
+ __ mov(arg_reg_3, frame_pointer());
|
||
// Code of self.
|
||
- __ mov(arg_reg2, Operand(masm_->CodeObject()));
|
||
+ __ mov(arg_reg_2, Operand(masm_->CodeObject()));
|
||
|
||
// We need to make room for the return address on the stack.
|
||
int stack_alignment = base::OS::ActivationFrameAlignment();
|
||
From aac73f3a715655476ce5b347a9614d1ca0ba9b93 Mon Sep 17 00:00:00 2001
|
||
From: Shahbaz Youssefi <syoussefi@chromium.org>
|
||
Date: Tue, 5 Dec 2023 13:36:53 -0500
|
||
Subject: [PATCH] [Backport] CVE-2024-0222: Use after free in ANGLE
|
||
|
||
Manual cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/angle/angle/+/5143829:
|
||
M120: Vulkan: Don't crash when glCopyTexImage2D redefines itself
|
||
|
||
The Vulkan backend marks a level being redefined as such before doing
|
||
the copy. If a single-level texture was being redefined, it releases it
|
||
so it can be immediately reallocated. If the source of the copy is the
|
||
same texture, this causes a crash.
|
||
|
||
This can be properly supported by using a temp image to do the copy, but
|
||
that is not implemented in this change.
|
||
|
||
Bug: chromium:1501798
|
||
Change-Id: I3a902b1e9eec41afd385d9c75a8c95dc986070a8
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/angle/angle/+/5143829
|
||
Reviewed-by: Cody Northrop <cnorthrop@google.com>
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532069
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../libANGLE/renderer/vulkan/TextureVk.cpp | 23 ++++++++++++++++++-
|
||
1 file changed, 22 insertions(+), 1 deletion(-)
|
||
|
||
diff --git a/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp b/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||
index 1950375b9b19..a098da4bfd33 100644
|
||
--- src/3rdparty/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||
+++ src/3rdparty/chromium/third_party/angle/src/libANGLE/renderer/vulkan/TextureVk.cpp
|
||
@@ -466,8 +466,28 @@ angle::Result TextureVk::copyImage(const gl::Context *context,
|
||
gl::GetInternalFormatInfo(internalFormat, GL_UNSIGNED_BYTE);
|
||
const vk::Format &vkFormat = renderer->getFormat(internalFormatInfo.sizedInternalFormat);
|
||
|
||
+ // The texture level being redefined might be the same as the one bound to the framebuffer.
|
||
+ // This _could_ be supported by using a temp image before redefining the level (and potentially
|
||
+ // discarding the image). However, this is currently unimplemented.
|
||
+ FramebufferVk *framebufferVk = vk::GetImpl(source);
|
||
+ RenderTargetVk *colorReadRT = framebufferVk->getColorReadRenderTarget();
|
||
+ vk::ImageHelper *srcImage = &colorReadRT->getImageForCopy();
|
||
+ const bool isCubeMap = index.getType() == gl::TextureType::CubeMap;
|
||
+ gl::LevelIndex levelIndex(getNativeImageIndex(index).getLevelIndex());
|
||
+ const uint32_t layerIndex = index.hasLayer() ? index.getLayerIndex() : 0;
|
||
+ const uint32_t redefinedFace = isCubeMap ? layerIndex : 0;
|
||
+ const uint32_t sourceFace = isCubeMap ? colorReadRT->getLayerIndex() : 0;
|
||
+ const bool isSelfCopy = mImage == srcImage && levelIndex == colorReadRT->getLevelIndex() &&
|
||
+ redefinedFace == sourceFace;
|
||
+
|
||
ANGLE_TRY(redefineLevel(context, index, vkFormat, newImageSize));
|
||
|
||
+ if (isSelfCopy)
|
||
+ {
|
||
+ UNIMPLEMENTED();
|
||
+ return angle::Result::Continue;
|
||
+ }
|
||
+
|
||
return copySubImageImpl(context, index, gl::Offset(0, 0, 0), sourceArea, internalFormatInfo,
|
||
source);
|
||
}
|
||
@@ -1393,7 +1413,8 @@ angle::Result TextureVk::redefineLevel(const gl::Context *context,
|
||
mImage->getLevelCount() == 1 && mImage->getBaseLevel() == levelIndexGL;
|
||
|
||
// If incompatible, and redefining the single-level image, release it so it can be
|
||
- // recreated immediately. This is an optimization to avoid an extra copy.
|
||
+ // recreated immediately. This is needed so that the texture can be reallocated with
|
||
+ // the correct format/size.
|
||
if (!isCompatibleRedefinition && isUpdateToSingleLevelImage)
|
||
{
|
||
releaseImage(contextVk);
|
||
From b3bd93f5093ceef2bcf0c2346a2b761455ab842a Mon Sep 17 00:00:00 2001
|
||
From: Joshua Pawlicki <waffles@chromium.org>
|
||
Date: Wed, 20 Dec 2023 22:33:06 +0000
|
||
Subject: [PATCH] [Backport] CVE-2024-0333: Insufficient data validation in
|
||
Extensions
|
||
|
||
Manual cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5141787:
|
||
crx_file: Error early for CRXs with ZIP markers in header.
|
||
|
||
Bug: 1513379
|
||
Change-Id: I029b4f15778df0c150866b1f49a9b5b2924690ed
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5141787
|
||
Commit-Queue: Joshua Pawlicki <waffles@chromium.org>
|
||
Auto-Submit: Joshua Pawlicki <waffles@chromium.org>
|
||
Code-Coverage: findit-for-me@appspot.gserviceaccount.com <findit-for-me@appspot.gserviceaccount.com>
|
||
Commit-Queue: Sorin Jianu <sorin@chromium.org>
|
||
Reviewed-by: Sorin Jianu <sorin@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#1239849}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532070
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
chromium/components/crx_file/crx_verifier.cc | 16 ++++++++++++++++
|
||
1 file changed, 16 insertions(+)
|
||
|
||
diff --git a/chromium/components/crx_file/crx_verifier.cc b/chromium/components/crx_file/crx_verifier.cc
|
||
index cbd7d777b6a6..d03cadb150db 100644
|
||
--- src/3rdparty/chromium/components/crx_file/crx_verifier.cc
|
||
+++ src/3rdparty/chromium/components/crx_file/crx_verifier.cc
|
||
@@ -4,6 +4,7 @@
|
||
|
||
#include "components/crx_file/crx_verifier.h"
|
||
|
||
+#include <algorithm>
|
||
#include <cstring>
|
||
#include <iterator>
|
||
#include <memory>
|
||
@@ -44,6 +45,9 @@ constexpr uint8_t kPublisherTestKeyHash[] = {
|
||
0x5f, 0x64, 0xf3, 0xa6, 0x17, 0x03, 0x0d, 0xde, 0x21, 0x61, 0xbe,
|
||
0xb7, 0x95, 0x91, 0x95, 0x83, 0x68, 0x12, 0xe9, 0x78, 0x1e};
|
||
|
||
+constexpr uint8_t kEocd[] = {'P', 'K', 0x05, 0x06};
|
||
+constexpr uint8_t kEocd64[] = {'P', 'K', 0x06, 0x07};
|
||
+
|
||
using VerifierCollection =
|
||
std::vector<std::unique_ptr<crypto::SignatureVerifier>>;
|
||
using RepeatedProof = google::protobuf::RepeatedPtrField<AsymmetricKeyProof>;
|
||
@@ -109,6 +113,18 @@ VerifierResult VerifyCrx3(
|
||
if (ReadAndHashBuffer(header_bytes.data(), header_size, file, hash) !=
|
||
static_cast<int>(header_size))
|
||
return VerifierResult::ERROR_HEADER_INVALID;
|
||
+
|
||
+ // If the header contains a ZIP EOCD or EOCD64 token, unzipping may not work
|
||
+ // correctly.
|
||
+ if (std::search(std::begin(header_bytes), std::end(header_bytes),
|
||
+ std::begin(kEocd),
|
||
+ std::end(kEocd)) != std::end(header_bytes) ||
|
||
+ std::search(std::begin(header_bytes), std::end(header_bytes),
|
||
+ std::begin(kEocd64),
|
||
+ std::end(kEocd64)) != std::end(header_bytes)) {
|
||
+ return VerifierResult::ERROR_HEADER_INVALID;
|
||
+ }
|
||
+
|
||
CrxFileHeader header;
|
||
if (!header.ParseFromArray(header_bytes.data(), header_size))
|
||
return VerifierResult::ERROR_HEADER_INVALID;
|
||
From 520c290ba211017b31324cc9f361c0388433616a Mon Sep 17 00:00:00 2001
|
||
From: =?UTF-8?q?Dominik=20Inf=C3=BChr?= <dinfuehr@chromium.org>
|
||
Date: Mon, 18 Dec 2023 09:15:00 +0100
|
||
Subject: [PATCH] [Backport] CVE-2024-0518: Type Confusion in V8
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
Manual backport of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/v8/v8/+/5125960:
|
||
[codegen] Install BytecodeArray last in SharedFunctionInfo
|
||
|
||
Maglev assumes that when a SharedFunctionInfo has a BytecodeArray,
|
||
then it should also have FeedbackMetadata. However, this may not
|
||
hold with concurrent compilation when the SharedFunctionInfo is
|
||
re-compiled after being flushed. Here the BytecodeArray was installed
|
||
on the SFI before the FeedbackMetadata and a concurrent thread could
|
||
observe the BytecodeArray but not the FeedbackMetadata.
|
||
|
||
Drive-by: Reset the age field before setting the BytecodeArray as
|
||
well. This ensures that the concurrent marker will not observe the
|
||
old age for the new BytecodeArray.
|
||
|
||
Bug: chromium:1507412
|
||
Change-Id: I8855ed7ecc50c4a47d2c89043d62ac053858bc75
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5125960
|
||
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
|
||
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#91568}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532071
|
||
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
|
||
---
|
||
chromium/v8/src/codegen/compiler.cc | 4 ++--
|
||
1 file changed, 2 insertions(+), 2 deletions(-)
|
||
|
||
diff --git a/chromium/v8/src/codegen/compiler.cc b/chromium/v8/src/codegen/compiler.cc
|
||
index f09658ebdf62..f963b0d92684 100644
|
||
--- src/3rdparty/chromium/v8/src/codegen/compiler.cc
|
||
+++ src/3rdparty/chromium/v8/src/codegen/compiler.cc
|
||
@@ -543,11 +543,11 @@ void InstallUnoptimizedCode(UnoptimizedCompilationInfo* compilation_info,
|
||
shared_info->set_is_asm_wasm_broken(true);
|
||
}
|
||
|
||
- shared_info->set_bytecode_array(*compilation_info->bytecode_array());
|
||
-
|
||
Handle<FeedbackMetadata> feedback_metadata = FeedbackMetadata::New(
|
||
isolate, compilation_info->feedback_vector_spec());
|
||
shared_info->set_feedback_metadata(*feedback_metadata);
|
||
+
|
||
+ shared_info->set_bytecode_array(*compilation_info->bytecode_array());
|
||
} else {
|
||
DCHECK(compilation_info->has_asm_wasm_data());
|
||
// We should only have asm/wasm data when finalizing on the main thread.
|
||
From 6fb8d851a5048e85877ae33b1800c122c8cd034d Mon Sep 17 00:00:00 2001
|
||
From: Toon Verwaest <verwaest@chromium.org>
|
||
Date: Thu, 11 Jan 2024 10:47:17 +0100
|
||
Subject: [PATCH] [Backport] CVE-2024-0519: Out of bounds memory access in V8
|
||
|
||
Manual cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/v8/v8/+/5192447:
|
||
Merged: [runtime] Drop fast last-property deletion
|
||
|
||
This interacts badly with other optimizations and isn't particularly
|
||
common.
|
||
|
||
Bug: chromium:1517354
|
||
(cherry picked from commit 389ea9be7d68bb189e16da79f6414edbd4f7594f)
|
||
|
||
Change-Id: Ie16aa38e8984c4879491c0d9a0ca9df0e041fd1d
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/5192447
|
||
Auto-Submit: Toon Verwaest <verwaest@chromium.org>
|
||
Reviewed-by: Leszek Swirski <leszeks@chromium.org>
|
||
Cr-Commit-Position: refs/branch-heads/12.0@{#32}
|
||
Cr-Branched-From: ed7b4caf1fb8184ad9e24346c84424055d4d430a-refs/heads/12.0.267@{#1}
|
||
Cr-Branched-From: 210e75b19db4352c9b78dce0bae11c2dc3077df4-refs/heads/main@{#90651}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532072
|
||
Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
|
||
---
|
||
chromium/v8/src/runtime/runtime-object.cc | 160 ----------------------
|
||
1 file changed, 160 deletions(-)
|
||
|
||
diff --git a/chromium/v8/src/runtime/runtime-object.cc b/chromium/v8/src/runtime/runtime-object.cc
|
||
index bd5d23dce45f..075bc0c665d3 100644
|
||
--- src/3rdparty/chromium/v8/src/runtime/runtime-object.cc
|
||
+++ src/3rdparty/chromium/v8/src/runtime/runtime-object.cc
|
||
@@ -92,170 +92,10 @@ MaybeHandle<Object> Runtime::HasProperty(Isolate* isolate,
|
||
: ReadOnlyRoots(isolate).false_value_handle();
|
||
}
|
||
|
||
-namespace {
|
||
-
|
||
-void GeneralizeAllTransitionsToFieldAsMutable(Isolate* isolate, Handle<Map> map,
|
||
- Handle<Name> name) {
|
||
- InternalIndex descriptor(map->NumberOfOwnDescriptors());
|
||
-
|
||
- Handle<Map> target_maps[kPropertyAttributesCombinationsCount];
|
||
- int target_maps_count = 0;
|
||
-
|
||
- // Collect all outgoing field transitions.
|
||
- {
|
||
- DisallowHeapAllocation no_gc;
|
||
- TransitionsAccessor transitions(isolate, *map, &no_gc);
|
||
- transitions.ForEachTransitionTo(
|
||
- *name,
|
||
- [&](Map target) {
|
||
- DCHECK_EQ(descriptor, target.LastAdded());
|
||
- DCHECK_EQ(*name, target.GetLastDescriptorName(isolate));
|
||
- PropertyDetails details = target.GetLastDescriptorDetails(isolate);
|
||
- // Currently, we track constness only for fields.
|
||
- if (details.kind() == kData &&
|
||
- details.constness() == PropertyConstness::kConst) {
|
||
- target_maps[target_maps_count++] = handle(target, isolate);
|
||
- }
|
||
- DCHECK_IMPLIES(details.kind() == kAccessor,
|
||
- details.constness() == PropertyConstness::kConst);
|
||
- },
|
||
- &no_gc);
|
||
- CHECK_LE(target_maps_count, kPropertyAttributesCombinationsCount);
|
||
- }
|
||
-
|
||
- for (int i = 0; i < target_maps_count; i++) {
|
||
- Handle<Map> target = target_maps[i];
|
||
- PropertyDetails details =
|
||
- target->instance_descriptors(isolate)
|
||
- .GetDetails(descriptor);
|
||
- Handle<FieldType> field_type(
|
||
- target->instance_descriptors(isolate)
|
||
- .GetFieldType(descriptor),
|
||
- isolate);
|
||
- Map::GeneralizeField(isolate, target, descriptor,
|
||
- PropertyConstness::kMutable, details.representation(),
|
||
- field_type);
|
||
- DCHECK_EQ(PropertyConstness::kMutable,
|
||
- target->instance_descriptors(isolate)
|
||
- .GetDetails(descriptor)
|
||
- .constness());
|
||
- }
|
||
-}
|
||
-
|
||
-bool DeleteObjectPropertyFast(Isolate* isolate, Handle<JSReceiver> receiver,
|
||
- Handle<Object> raw_key) {
|
||
- // This implements a special case for fast property deletion: when the
|
||
- // last property in an object is deleted, then instead of normalizing
|
||
- // the properties, we can undo the last map transition, with a few
|
||
- // prerequisites:
|
||
- // (1) The receiver must be a regular object and the key a unique name.
|
||
- Handle<Map> receiver_map(receiver->map(), isolate);
|
||
- if (receiver_map->IsSpecialReceiverMap()) return false;
|
||
- DCHECK(receiver_map->IsJSObjectMap());
|
||
-
|
||
- if (!raw_key->IsUniqueName()) return false;
|
||
- Handle<Name> key = Handle<Name>::cast(raw_key);
|
||
- // (2) The property to be deleted must be the last property.
|
||
- int nof = receiver_map->NumberOfOwnDescriptors();
|
||
- if (nof == 0) return false;
|
||
- InternalIndex descriptor(nof - 1);
|
||
- Handle<DescriptorArray> descriptors(receiver_map->instance_descriptors(),
|
||
- isolate);
|
||
- if (descriptors->GetKey(descriptor) != *key) return false;
|
||
- // (3) The property to be deleted must be deletable.
|
||
- PropertyDetails details = descriptors->GetDetails(descriptor);
|
||
- if (!details.IsConfigurable()) return false;
|
||
- // (4) The map must have a back pointer.
|
||
- Handle<Object> backpointer(receiver_map->GetBackPointer(), isolate);
|
||
- if (!backpointer->IsMap()) return false;
|
||
- Handle<Map> parent_map = Handle<Map>::cast(backpointer);
|
||
- // (5) The last transition must have been caused by adding a property
|
||
- // (and not any kind of special transition).
|
||
- if (parent_map->NumberOfOwnDescriptors() != nof - 1) return false;
|
||
-
|
||
- // Preconditions successful. No more bailouts after this point.
|
||
-
|
||
- // Zap the property to avoid keeping objects alive. Zapping is not necessary
|
||
- // for properties stored in the descriptor array.
|
||
- if (details.location() == kField) {
|
||
- DisallowHeapAllocation no_allocation;
|
||
-
|
||
- // Invalidate slots manually later in case we delete an in-object tagged
|
||
- // property. In this case we might later store an untagged value in the
|
||
- // recorded slot.
|
||
- isolate->heap()->NotifyObjectLayoutChange(*receiver, no_allocation,
|
||
- InvalidateRecordedSlots::kNo);
|
||
- FieldIndex index =
|
||
- FieldIndex::ForPropertyIndex(*receiver_map, details.field_index());
|
||
- // Special case deleting the last out-of object property.
|
||
- if (!index.is_inobject() && index.outobject_array_index() == 0) {
|
||
- DCHECK(!parent_map->HasOutOfObjectProperties());
|
||
- // Clear out the properties backing store.
|
||
- receiver->SetProperties(ReadOnlyRoots(isolate).empty_fixed_array());
|
||
- } else {
|
||
- Object filler = ReadOnlyRoots(isolate).one_pointer_filler_map();
|
||
- JSObject::cast(*receiver).RawFastPropertyAtPut(index, filler);
|
||
- // We must clear any recorded slot for the deleted property, because
|
||
- // subsequent object modifications might put a raw double there.
|
||
- // Slot clearing is the reason why this entire function cannot currently
|
||
- // be implemented in the DeleteProperty stub.
|
||
- if (index.is_inobject() && !receiver_map->IsUnboxedDoubleField(index)) {
|
||
- // We need to clear the recorded slot in this case because in-object
|
||
- // slack tracking might not be finished. This ensures that we don't
|
||
- // have recorded slots in free space.
|
||
- isolate->heap()->ClearRecordedSlot(*receiver,
|
||
- receiver->RawField(index.offset()));
|
||
- MemoryChunk* chunk = MemoryChunk::FromHeapObject(*receiver);
|
||
- chunk->InvalidateRecordedSlots(*receiver);
|
||
- }
|
||
- }
|
||
- }
|
||
- // If the {receiver_map} was marked stable before, then there could be
|
||
- // optimized code that depends on the assumption that no object that
|
||
- // reached this {receiver_map} transitions away from it without triggering
|
||
- // the "deoptimize dependent code" mechanism.
|
||
- receiver_map->NotifyLeafMapLayoutChange(isolate);
|
||
- // Finally, perform the map rollback.
|
||
- receiver->synchronized_set_map(*parent_map);
|
||
-#if VERIFY_HEAP
|
||
- receiver->HeapObjectVerify(isolate);
|
||
- receiver->property_array().PropertyArrayVerify(isolate);
|
||
-#endif
|
||
-
|
||
- // If the {descriptor} was "const" so far, we need to update the
|
||
- // {receiver_map} here, otherwise we could get the constants wrong, i.e.
|
||
- //
|
||
- // o.x = 1;
|
||
- // [change o.x's attributes or reconfigure property kind]
|
||
- // delete o.x;
|
||
- // o.x = 2;
|
||
- //
|
||
- // could trick V8 into thinking that `o.x` is still 1 even after the second
|
||
- // assignment.
|
||
-
|
||
- // Step 1: Migrate object to an up-to-date shape.
|
||
- if (parent_map->is_deprecated()) {
|
||
- JSObject::MigrateInstance(isolate, Handle<JSObject>::cast(receiver));
|
||
- parent_map = handle(receiver->map(), isolate);
|
||
- }
|
||
-
|
||
- // Step 2: Mark outgoing transitions from the up-to-date version of the
|
||
- // parent_map to same property name of any kind or attributes as mutable.
|
||
- // Also migrate object to the up-to-date map to make the object shapes
|
||
- // converge sooner.
|
||
- GeneralizeAllTransitionsToFieldAsMutable(isolate, parent_map, key);
|
||
-
|
||
- return true;
|
||
-}
|
||
-
|
||
-} // namespace
|
||
-
|
||
Maybe<bool> Runtime::DeleteObjectProperty(Isolate* isolate,
|
||
Handle<JSReceiver> receiver,
|
||
Handle<Object> key,
|
||
LanguageMode language_mode) {
|
||
- if (DeleteObjectPropertyFast(isolate, receiver, key)) return Just(true);
|
||
-
|
||
bool success = false;
|
||
LookupIterator::Key lookup_key(isolate, key, &success);
|
||
if (!success) return Nothing<bool>();
|
||
From 1dbdcfd64885f0dc034e73dacf6ef4e20f8351bf Mon Sep 17 00:00:00 2001
|
||
From: Mike Wasserman <msw@chromium.org>
|
||
Date: Tue, 9 Jan 2024 01:07:39 +0000
|
||
Subject: [PATCH] [Backport] Security bug 1506535
|
||
|
||
Manual cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5146875:
|
||
[M120 merge] Speculative fix for UAF in content::WebContentsImpl::ExitFullscreenMode
|
||
|
||
(cherry picked from commit c1cda70a433a0c625b280eb88ed6ff4f4feffa12)
|
||
|
||
Bug: 1506535, 854815
|
||
Change-Id: Iace64d63f8cea2dbfbc761ad233db42451ec101c
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5146875
|
||
Commit-Queue: John Abd-El-Malek <jam@chromium.org>
|
||
Auto-Submit: Mike Wasserman <msw@chromium.org>
|
||
Reviewed-by: John Abd-El-Malek <jam@chromium.org>
|
||
Cr-Original-Commit-Position: refs/heads/main@{#1240353}
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5178801
|
||
Cr-Commit-Position: refs/branch-heads/6099@{#1727}
|
||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532073
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
chromium/content/browser/web_contents/web_contents_impl.cc | 5 +++++
|
||
1 file changed, 5 insertions(+)
|
||
|
||
diff --git a/chromium/content/browser/web_contents/web_contents_impl.cc b/chromium/content/browser/web_contents/web_contents_impl.cc
|
||
index 0627170ed036..23d4268a1b67 100644
|
||
--- src/3rdparty/chromium/content/browser/web_contents/web_contents_impl.cc
|
||
+++ src/3rdparty/chromium/content/browser/web_contents/web_contents_impl.cc
|
||
@@ -3278,7 +3278,12 @@ void WebContentsImpl::ExitFullscreenMode(bool will_cause_resize) {
|
||
}
|
||
|
||
if (delegate_) {
|
||
+ // This may spin the message loop and destroy this object crbug.com/1506535
|
||
+ base::WeakPtr<WebContentsImpl> weak_ptr = weak_factory_.GetWeakPtr();
|
||
delegate_->ExitFullscreenModeForTab(this);
|
||
+ if (!weak_ptr) {
|
||
+ return;
|
||
+ }
|
||
|
||
if (keyboard_lock_widget_)
|
||
delegate_->CancelKeyboardLockRequest(this);
|
||
From 1c6050c84b2a8bd14a96787ca845a3aec0d87a4f Mon Sep 17 00:00:00 2001
|
||
From: Gustaf Ullberg <gustaf@chromium.org>
|
||
Date: Tue, 19 Dec 2023 18:08:19 +0000
|
||
Subject: [PATCH] [Backport] CVE-2023-7024: Heap buffer overflow in WebRTC
|
||
|
||
Cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5136295:
|
||
WebRtcAudioSink: Stop on invalid configuration
|
||
|
||
Bug: 1513170
|
||
Change-Id: Ia4ca55e9eafb81789b28b8b8c54e615ac28df633
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5136295
|
||
Reviewed-by: Harald Alvestrand <hta@chromium.org>
|
||
Commit-Queue: Gustaf Ullberg <gustaf@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#1239233}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532066
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../blink/renderer/platform/peerconnection/webrtc_audio_sink.cc | 2 +-
|
||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||
|
||
diff --git a/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc b/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
|
||
index a0f2c5e8005f..0542a9a7d4c0 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/platform/peerconnection/webrtc_audio_sink.cc
|
||
@@ -115,7 +115,7 @@ void WebRtcAudioSink::OnData(const media::AudioBus& audio_bus,
|
||
}
|
||
|
||
void WebRtcAudioSink::OnSetFormat(const media::AudioParameters& params) {
|
||
- DCHECK(params.IsValid());
|
||
+ CHECK(params.IsValid());
|
||
SendLogMessage(base::StringPrintf("OnSetFormat([label=%s] {params=[%s]})",
|
||
adapter_->label().c_str(),
|
||
params.AsHumanReadableString().c_str()));
|
||
From 525ae23fbd019ab819a2f7e26e43bfce4ee79c51 Mon Sep 17 00:00:00 2001
|
||
From: Hongchan Choi <hongchan@chromium.org>
|
||
Date: Tue, 12 Dec 2023 02:36:08 +0000
|
||
Subject: [PATCH] [Backport] CVE-2024-0224: Use after free in WebAudio
|
||
|
||
Manual cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5112992:
|
||
Wrap buffer read index in delay kernel
|
||
|
||
The current code assumes that the first buffer read index in the delay
|
||
kernel does not go out of bound. This CL applies the wrapping function
|
||
to the read index array.
|
||
|
||
(cherry picked from commit fb96fd5f41bec823dbb208d9a7d53fbbf4d16ce4)
|
||
|
||
Bug: 1505086
|
||
Test: Locally confirmed the repro does not crash anymore
|
||
Change-Id: Idca3dfc7dec5b5a7f9b22d87135e2d775729631a
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5072113
|
||
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
|
||
Reviewed-by: Michael Wilson <mjwilson@chromium.org>
|
||
Cr-Original-Commit-Position: refs/heads/main@{#1231040}
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5112992
|
||
Auto-Submit: Hongchan Choi <hongchan@chromium.org>
|
||
Commit-Queue: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
|
||
Cr-Commit-Position: refs/branch-heads/6099@{#1498}
|
||
Cr-Branched-From: e6ee4500f7d6549a9ac1354f8d056da49ef406be-refs/heads/main@{#1217362}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532067
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../renderer/platform/audio/audio_delay_dsp_kernel.cc | 2 +-
|
||
.../audio/cpu/arm/audio_delay_dsp_kernel_neon.cc | 7 +++++--
|
||
.../audio/cpu/x86/audio_delay_dsp_kernel_sse2.cc | 10 +++++++---
|
||
3 files changed, 13 insertions(+), 6 deletions(-)
|
||
|
||
diff --git a/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc b/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
|
||
index 25818dcf2aa7..c34118e953ac 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/platform/audio/audio_delay_dsp_kernel.cc
|
||
@@ -150,7 +150,7 @@ int AudioDelayDSPKernel::ProcessARateScalar(unsigned start,
|
||
const float* delay_times = delay_times_.Data();
|
||
|
||
for (unsigned i = start; i < frames_to_process; ++i) {
|
||
- double delay_time = delay_times[i];
|
||
+ double delay_time = std::fmax(delay_times[i], 0);
|
||
double desired_delay_frames = delay_time * sample_rate;
|
||
|
||
double read_position = w_index + buffer_length - desired_delay_frames;
|
||
diff --git a/chromium/third_party/blink/renderer/platform/audio/cpu/arm/audio_delay_dsp_kernel_neon.cc b/chromium/third_party/blink/renderer/platform/audio/cpu/arm/audio_delay_dsp_kernel_neon.cc
|
||
index 2843bd60b8ba..803f3e724423 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/platform/audio/cpu/arm/audio_delay_dsp_kernel_neon.cc
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/platform/audio/cpu/arm/audio_delay_dsp_kernel_neon.cc
|
||
@@ -60,6 +60,7 @@ std::tuple<unsigned, int> AudioDelayDSPKernel::ProcessARateVector(
|
||
int w_index = write_index_;
|
||
|
||
const float32x4_t v_sample_rate = vdupq_n_f32(sample_rate);
|
||
+ const float32x4_t v_all_zeros = vdupq_n_f32(0);
|
||
|
||
// The buffer length as a float and as an int so we don't need to constant
|
||
// convert from one to the other.
|
||
@@ -87,7 +88,8 @@ std::tuple<unsigned, int> AudioDelayDSPKernel::ProcessARateVector(
|
||
int k = 0;
|
||
|
||
for (int n = 0; n < number_of_loops; ++n, k += 4) {
|
||
- const float32x4_t v_delay_time = vld1q_f32(delay_times + k);
|
||
+ const float32x4_t v_delay_time = vmaxq_f32(vld1q_f32(delay_times + k),
|
||
+ v_all_zeros);
|
||
const float32x4_t v_desired_delay_frames =
|
||
vmulq_f32(v_delay_time, v_sample_rate);
|
||
|
||
@@ -100,7 +102,8 @@ std::tuple<unsigned, int> AudioDelayDSPKernel::ProcessARateVector(
|
||
WrapPositionVector(v_read_position, v_buffer_length_float);
|
||
|
||
// Get indices into the buffer for the samples we need for interpolation.
|
||
- const int32x4_t v_read_index1 = vcvtq_s32_f32(v_read_position);
|
||
+ const int32x4_t v_read_index1 = WrapIndexVector(
|
||
+ vcvtq_s32_f32(v_read_position), v_buffer_length_int);
|
||
const int32x4_t v_read_index2 = WrapIndexVector(
|
||
vaddq_s32(v_read_index1, vdupq_n_s32(1)), v_buffer_length_int);
|
||
|
||
diff --git a/chromium/third_party/blink/renderer/platform/audio/cpu/x86/audio_delay_dsp_kernel_sse2.cc b/chromium/third_party/blink/renderer/platform/audio/cpu/x86/audio_delay_dsp_kernel_sse2.cc
|
||
index fe2aef95aeda..dd368ee4b0f4 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/platform/audio/cpu/x86/audio_delay_dsp_kernel_sse2.cc
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/platform/audio/cpu/x86/audio_delay_dsp_kernel_sse2.cc
|
||
@@ -56,10 +56,10 @@ std::tuple<unsigned, int> AudioDelayDSPKernel::ProcessARateVector(
|
||
|
||
const float sample_rate = this->SampleRate();
|
||
const float* delay_times = delay_times_.Data();
|
||
-
|
||
int w_index = write_index_;
|
||
|
||
const __m128 v_sample_rate = _mm_set1_ps(sample_rate);
|
||
+ const __m128 v_all_zeros = _mm_setzero_ps();
|
||
|
||
// The buffer length as a float and as an int so we don't need to constant
|
||
// convert from one to the other.
|
||
@@ -82,7 +82,10 @@ std::tuple<unsigned, int> AudioDelayDSPKernel::ProcessARateVector(
|
||
int k = 0;
|
||
|
||
for (int n = 0; n < number_of_loops; ++n, k += 4) {
|
||
- const __m128 v_delay_time = _mm_loadu_ps(delay_times + k);
|
||
+ // It's possible that `delay_time` contains negative values. Make sure
|
||
+ // they are greater than zero.
|
||
+ const __m128 v_delay_time = _mm_max_ps(_mm_loadu_ps(delay_times + k),
|
||
+ v_all_zeros);
|
||
const __m128 v_desired_delay_frames =
|
||
_mm_mul_ps(v_delay_time, v_sample_rate);
|
||
|
||
@@ -95,7 +98,8 @@ std::tuple<unsigned, int> AudioDelayDSPKernel::ProcessARateVector(
|
||
WrapPositionVector(v_read_position, v_buffer_length_float);
|
||
|
||
// Get indices into the buffer for the samples we need for interpolation.
|
||
- const __m128i v_read_index1 = _mm_cvttps_epi32(v_read_position);
|
||
+ const __m128i v_read_index1 = WrapIndexVector(
|
||
+ _mm_cvttps_epi32(v_read_position), v_buffer_length_int);
|
||
const __m128i v_read_index2 = WrapIndexVector(
|
||
_mm_add_epi32(v_read_index1, _mm_set1_epi32(1)), v_buffer_length_int);
|
||
|
||
From c96132ccf271137bbd3f5b1a8c9c172650e69526 Mon Sep 17 00:00:00 2001
|
||
From: Evan Stade <estade@chromium.org>
|
||
Date: Fri, 15 Dec 2023 21:38:02 +0000
|
||
Subject: [PATCH] [Backport] Security bug 1511689
|
||
|
||
Manual cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/deps/sqlite/+/5123910:
|
||
Fix a spurious "misuse of aggregate function" error that could occur when an aggregate function was used within the FROM clause of a sub-select of the select that owns the aggregate. e.g. "SELECT (SELECT x FROM (SELECT sum(t1.a) AS x)) FROM t1". [forum:/forumpost/c9970a37ed | Forum post c9970a37ed].
|
||
|
||
FossilOrigin-Name: 4470f657d2069972d02a00983252dec1f814d90c0d8d0906e320e955111e8c11
|
||
(cherry picked from commit 5e4233a9e48b124d4d342b757b34e4ae849f5cf8)
|
||
|
||
Bug: 1511689
|
||
Change-Id: I69263fc0a5fa66df5c09b964864568f2fc7a6ca5
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/deps/sqlite/+/5123910
|
||
Auto-Submit: Evan Stade <estade@chromium.org>
|
||
Commit-Queue: Ayu Ishii <ayui@chromium.org>
|
||
Reviewed-by: Ayu Ishii <ayui@chromium.org>
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532068
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
chromium/third_party/sqlite/src/amalgamation/sqlite3.c | 6 +++++-
|
||
chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.c | 6 +++++-
|
||
chromium/third_party/sqlite/src/src/resolve.c | 7 +++++--
|
||
chromium/third_party/sqlite/src/src/sqliteInt.h | 1 +
|
||
4 files changed, 16 insertions(+), 4 deletions(-)
|
||
|
||
diff --git a/chromium/third_party/sqlite/src/amalgamation/sqlite3.c b/chromium/third_party/sqlite/src/amalgamation/sqlite3.c
|
||
index d7766b7d7ec..b353aa88348 100644
|
||
--- src/3rdparty/chromium/third_party/sqlite/src/amalgamation/sqlite3.c
|
||
+++ src/3rdparty/chromium/third_party/sqlite/src/amalgamation/sqlite3.c
|
||
@@ -18804,6 +18804,7 @@ struct NameContext {
|
||
int nRef; /* Number of names resolved by this context */
|
||
int nNcErr; /* Number of errors encountered while resolving names */
|
||
int ncFlags; /* Zero or more NC_* flags defined below */
|
||
+ int nNestedSelect; /* Number of nested selects using this NC */
|
||
Select *pWinSelect; /* SELECT statement for any window functions */
|
||
};
|
||
|
||
@@ -104749,11 +104750,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||
while( pNC2
|
||
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
|
||
){
|
||
- pExpr->op2++;
|
||
+ pExpr->op2 += (1 + pNC2->nNestedSelect);
|
||
pNC2 = pNC2->pNext;
|
||
}
|
||
assert( pDef!=0 || IN_RENAME_OBJECT );
|
||
if( pNC2 && pDef ){
|
||
+ pExpr->op2 += pNC2->nNestedSelect;
|
||
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
|
||
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
|
||
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
|
||
@@ -105314,6 +105316,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||
|
||
/* Recursively resolve names in all subqueries in the FROM clause
|
||
*/
|
||
+ if( pOuterNC ) pOuterNC->nNestedSelect++;
|
||
for(i=0; i<p->pSrc->nSrc; i++){
|
||
SrcItem *pItem = &p->pSrc->a[i];
|
||
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
|
||
@@ -105338,6 +105341,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||
}
|
||
}
|
||
}
|
||
+ if( pOuterNC ) pOuterNC->nNestedSelect--;
|
||
|
||
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
|
||
** resolve the result-set expression list.
|
||
diff --git a/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.c b/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.c
|
||
index 0819ea6a615..5c72a44dd6b 100644
|
||
--- src/3rdparty/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.c
|
||
+++ src/3rdparty/chromium/third_party/sqlite/src/amalgamation_dev/sqlite3.c
|
||
@@ -18817,6 +18817,7 @@ struct NameContext {
|
||
int nRef; /* Number of names resolved by this context */
|
||
int nNcErr; /* Number of errors encountered while resolving names */
|
||
int ncFlags; /* Zero or more NC_* flags defined below */
|
||
+ int nNestedSelect; /* Number of nested selects using this NC */
|
||
Select *pWinSelect; /* SELECT statement for any window functions */
|
||
};
|
||
|
||
@@ -104762,11 +104763,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||
while( pNC2
|
||
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
|
||
){
|
||
- pExpr->op2++;
|
||
+ pExpr->op2 += (1 + pNC2->nNestedSelect);
|
||
pNC2 = pNC2->pNext;
|
||
}
|
||
assert( pDef!=0 || IN_RENAME_OBJECT );
|
||
if( pNC2 && pDef ){
|
||
+ pExpr->op2 += pNC2->nNestedSelect;
|
||
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
|
||
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
|
||
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
|
||
@@ -105327,6 +105329,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||
|
||
/* Recursively resolve names in all subqueries in the FROM clause
|
||
*/
|
||
+ if( pOuterNC ) pOuterNC->nNestedSelect++;
|
||
for(i=0; i<p->pSrc->nSrc; i++){
|
||
SrcItem *pItem = &p->pSrc->a[i];
|
||
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
|
||
@@ -105351,6 +105354,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||
}
|
||
}
|
||
}
|
||
+ if( pOuterNC ) pOuterNC->nNestedSelect--;
|
||
|
||
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
|
||
** resolve the result-set expression list.
|
||
diff --git a/chromium/third_party/sqlite/src/src/resolve.c b/chromium/third_party/sqlite/src/src/resolve.c
|
||
index 4b36ecca348..c5228a7f097 100644
|
||
--- src/3rdparty/chromium/third_party/sqlite/src/src/resolve.c
|
||
+++ src/3rdparty/chromium/third_party/sqlite/src/src/resolve.c
|
||
@@ -1211,11 +1211,12 @@ static int resolveExprStep(Walker *pWalker, Expr *pExpr){
|
||
while( pNC2
|
||
&& sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0
|
||
){
|
||
- pExpr->op2++;
|
||
+ pExpr->op2 += (1 + pNC2->nNestedSelect);
|
||
pNC2 = pNC2->pNext;
|
||
}
|
||
assert( pDef!=0 || IN_RENAME_OBJECT );
|
||
if( pNC2 && pDef ){
|
||
+ pExpr->op2 += pNC2->nNestedSelect;
|
||
assert( SQLITE_FUNC_MINMAX==NC_MinMaxAgg );
|
||
assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg );
|
||
testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 );
|
||
@@ -1776,6 +1777,7 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||
|
||
/* Recursively resolve names in all subqueries in the FROM clause
|
||
*/
|
||
+ if( pOuterNC ) pOuterNC->nNestedSelect++;
|
||
for(i=0; i<p->pSrc->nSrc; i++){
|
||
SrcItem *pItem = &p->pSrc->a[i];
|
||
if( pItem->pSelect && (pItem->pSelect->selFlags & SF_Resolved)==0 ){
|
||
@@ -1800,7 +1802,8 @@ static int resolveSelectStep(Walker *pWalker, Select *p){
|
||
}
|
||
}
|
||
}
|
||
-
|
||
+ if( pOuterNC ) pOuterNC->nNestedSelect--;
|
||
+
|
||
/* Set up the local name-context to pass to sqlite3ResolveExprNames() to
|
||
** resolve the result-set expression list.
|
||
*/
|
||
diff --git a/chromium/third_party/sqlite/src/src/sqliteInt.h b/chromium/third_party/sqlite/src/src/sqliteInt.h
|
||
index 2614f4be458..07bc4def106 100644
|
||
--- src/3rdparty/chromium/third_party/sqlite/src/src/sqliteInt.h
|
||
+++ src/3rdparty/chromium/third_party/sqlite/src/src/sqliteInt.h
|
||
@@ -3321,6 +3321,7 @@ struct NameContext {
|
||
int nRef; /* Number of names resolved by this context */
|
||
int nNcErr; /* Number of errors encountered while resolving names */
|
||
int ncFlags; /* Zero or more NC_* flags defined below */
|
||
+ int nNestedSelect; /* Number of nested selects using this NC */
|
||
Select *pWinSelect; /* SELECT statement for any window functions */
|
||
};
|
||
|
||
From f1ef87d506845dd62bb0802e80092d53100222f4 Mon Sep 17 00:00:00 2001
|
||
From: Hongchan Choi <hongchan@chromium.org>
|
||
Date: Fri, 12 Jan 2024 22:57:22 +0000
|
||
Subject: [PATCH] [Backport] CVE-2024-0807: Use after free in WebAudio
|
||
|
||
Manual cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5225523:
|
||
Update rendering state of automatic pull nodes before graph rendering
|
||
|
||
M114 merge issues:
|
||
third_party/blink/renderer/modules/webaudio/analyser_handler.cc:
|
||
PullInputs/CheckNumberOfChannelsForInput not present in 114.
|
||
|
||
In rare cases, the rendering fan out count of automatic pull node
|
||
does not match the main thread fan out count after recreating
|
||
a platform destination followed by disconnection.
|
||
|
||
This CL forces the update of the rendering state of automatic
|
||
pull nodes before graph rendering to make sure that fan out counts
|
||
are synchronized before executing the audio processing function call.
|
||
|
||
NOTE: This change makes 2 WPTs fail. The follow-up work is planned
|
||
to address them once this patch is merged.
|
||
|
||
Bug: 1505080
|
||
Test: Locally confirmed that ASAN doesn't crash on all repro cases.
|
||
Change-Id: I6768cd8bc64525ea9d56a19b9c58439e9cdab9a8
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5131958
|
||
Commit-Queue: Hongchan Choi <hongchan@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#1246718}
|
||
(cherry picked from commit f4bffa09b46c21147431179e1e6dd2b27bc35fbc)
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/537374
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../renderer/modules/webaudio/analyser_node.cc | 11 +++++++++--
|
||
.../renderer/modules/webaudio/audio_worklet_node.cc | 13 +++++++++----
|
||
.../modules/webaudio/audio_worklet_processor.cc | 6 ++++++
|
||
.../modules/webaudio/deferred_task_handler.cc | 10 ++++++++++
|
||
4 files changed, 34 insertions(+), 6 deletions(-)
|
||
|
||
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
|
||
index cb281f5b728f..9f515af5d9a9 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/modules/webaudio/analyser_node.cc
|
||
@@ -51,9 +51,11 @@ AnalyserHandler::~AnalyserHandler() {
|
||
}
|
||
|
||
void AnalyserHandler::Process(uint32_t frames_to_process) {
|
||
- AudioBus* output_bus = Output(0).Bus();
|
||
+ DCHECK(Context()->IsAudioThread());
|
||
|
||
- if (!IsInitialized()) {
|
||
+ AudioBus* output_bus = Output(0).RenderingFanOutCount() > 0 ? Output(0).Bus() : nullptr;
|
||
+
|
||
+ if (!IsInitialized() && output_bus) {
|
||
output_bus->Zero();
|
||
return;
|
||
}
|
||
@@ -65,6 +67,11 @@ void AnalyserHandler::Process(uint32_t frames_to_process) {
|
||
// Analyser reflects the current input.
|
||
analyser_.WriteInput(input_bus.get(), frames_to_process);
|
||
|
||
+ // Subsequent steps require `output_bus` to be valid.
|
||
+ if (!output_bus) {
|
||
+ return;
|
||
+ }
|
||
+
|
||
if (!Input(0).IsConnected()) {
|
||
// No inputs, so clear the output, and propagate the silence hint.
|
||
output_bus->Zero();
|
||
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
|
||
index eccf002b6da6..5f18c4cd12d2 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_node.cc
|
||
@@ -102,11 +102,16 @@ void AudioWorkletHandler::Process(uint32_t frames_to_process) {
|
||
// We also need to check if the global scope is valid before we request
|
||
// the rendering in the AudioWorkletGlobalScope.
|
||
if (processor_ && !processor_->hasErrorOccurred()) {
|
||
- // If the input is not connected, inform the processor with nullptr.
|
||
- for (unsigned i = 0; i < NumberOfInputs(); ++i)
|
||
+ // If the input or the output is not connected, inform the processor with
|
||
+ // nullptr.
|
||
+ for (unsigned i = 0; i < NumberOfInputs(); ++i) {
|
||
inputs_[i] = Input(i).IsConnected() ? Input(i).Bus() : nullptr;
|
||
- for (unsigned i = 0; i < NumberOfOutputs(); ++i)
|
||
- outputs_[i] = WrapRefCounted(Output(i).Bus());
|
||
+ }
|
||
+ for (unsigned i = 0; i < NumberOfOutputs(); ++i) {
|
||
+ outputs_[i] = Output(i).RenderingFanOutCount() > 0
|
||
+ ? WrapRefCounted(Output(i).Bus())
|
||
+ : nullptr;
|
||
+ }
|
||
|
||
for (const auto& param_name : param_value_map_.Keys()) {
|
||
auto* const param_handler = param_handler_map_.at(param_name);
|
||
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc b/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
|
||
index e68b1c1b2f6b..84ab72b9774c 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/modules/webaudio/audio_worklet_processor.cc
|
||
@@ -343,6 +343,12 @@ void AudioWorkletProcessor::CopyArrayBuffersToPort(
|
||
|
||
for (uint32_t bus_index = 0; bus_index < audio_port.size(); ++bus_index) {
|
||
const scoped_refptr<AudioBus>& audio_bus = audio_port[bus_index];
|
||
+
|
||
+ // nullptr indicates the output bus is not connected. Do not proceed.
|
||
+ if (!audio_bus) {
|
||
+ break;
|
||
+ }
|
||
+
|
||
for (uint32_t channel_index = 0;
|
||
channel_index < audio_bus->NumberOfChannels(); ++channel_index) {
|
||
const v8::ArrayBuffer::Contents& contents =
|
||
diff --git a/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc b/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
|
||
index 76aa9acccd30..88e4228caefa 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/modules/webaudio/deferred_task_handler.cc
|
||
@@ -169,6 +169,16 @@ void DeferredTaskHandler::UpdateAutomaticPullNodes() {
|
||
if (try_locker.Locked()) {
|
||
CopyToVector(automatic_pull_handlers_,
|
||
rendering_automatic_pull_handlers_);
|
||
+
|
||
+ // In rare cases, it is possible for automatic pull nodes' output bus
|
||
+ // to become stale. Make sure update their rendering output counts.
|
||
+ // crbug.com/1505080.
|
||
+ for (auto& handler : rendering_automatic_pull_handlers_) {
|
||
+ for (unsigned i = 0; i < handler->NumberOfOutputs(); ++i) {
|
||
+ handler->Output(i).UpdateRenderingState();
|
||
+ }
|
||
+ }
|
||
+
|
||
automatic_pull_handlers_need_updating_ = false;
|
||
}
|
||
}
|
||
From 850527b41e56a8b48d99513eddcc75d4efe3c16d Mon Sep 17 00:00:00 2001
|
||
From: Lyra Rebane <rebane2001@gmail.com>
|
||
Date: Mon, 8 Jan 2024 13:39:46 +0000
|
||
Subject: [PATCH] [Backport] CVE-2024-0808: Integer underflow in WebUI
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
Manual backport of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5177426:
|
||
[M114-LTS] Verify resource order in data pack files
|
||
|
||
This CL adds a resource order check when loading a data pack or calling DataPack::GetStringPiece to make sure the resources are ordered sequentially in memory.
|
||
|
||
Bug: 1504936
|
||
Change-Id: Ie3bf1d9dbac937407355935a859a5daa9ce84350
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5059113
|
||
Commit-Queue: Peter Boström <pbos@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#1238675}
|
||
(cherry picked from commit c4b2e6246ad0e95eaf0727bb25a2e4969155e989)
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/537375
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
chromium/AUTHORS | 1 +
|
||
chromium/ui/base/resource/data_pack.cc | 19 ++++++++++++++++++-
|
||
.../ui/base/resource/data_pack_literal.cc | 12 ++++++++++++
|
||
chromium/ui/base/resource/data_pack_literal.h | 2 ++
|
||
4 files changed, 33 insertions(+), 1 deletion(-)
|
||
|
||
diff --git a/chromium/AUTHORS b/chromium/AUTHORS
|
||
index 92f53ac669a0..9d61a61e57b9 100644
|
||
--- src/3rdparty/chromium/AUTHORS
|
||
+++ src/3rdparty/chromium/AUTHORS
|
||
@@ -631,6 +631,7 @@ Luke Inman-Semerau <luke.semerau@gmail.com>
|
||
Luke Seunghoe Gu <gulukesh@gmail.com>
|
||
Luke Zarko <lukezarko@gmail.com>
|
||
Luoxi Pan <l.panpax@gmail.com>
|
||
+Lyra Rebane <rebane2001@gmail.com>
|
||
Maarten Lankhorst <m.b.lankhorst@gmail.com>
|
||
Magnus Danielsson <fuzzac@gmail.com>
|
||
Mahesh Kulkarni <mahesh.kk@samsung.com>
|
||
diff --git a/chromium/ui/base/resource/data_pack.cc b/chromium/ui/base/resource/data_pack.cc
|
||
index 09513e6aed24..4e522c9ad758 100644
|
||
--- src/3rdparty/chromium/ui/base/resource/data_pack.cc
|
||
+++ src/3rdparty/chromium/ui/base/resource/data_pack.cc
|
||
@@ -400,7 +400,16 @@ bool DataPack::LoadImpl(std::unique_ptr<DataPack::DataSource> data_source) {
|
||
}
|
||
}
|
||
|
||
- // 3) Verify the aliases are within the appropriate bounds.
|
||
+ // 3) Verify the entries are ordered correctly.
|
||
+ for (size_t i = 0; i < resource_count_; ++i) {
|
||
+ if (resource_table_[i].file_offset > resource_table_[i + 1].file_offset) {
|
||
+ LOG(ERROR) << "Data pack file corruption: "
|
||
+ << "Entry #" << i + 1 << " before Entry #" << i << ".";
|
||
+ return false;
|
||
+ }
|
||
+ }
|
||
+
|
||
+ // 4) Verify the aliases are within the appropriate bounds.
|
||
for (size_t i = 0; i < alias_count_; ++i) {
|
||
if (alias_table_[i].entry_index >= resource_count_) {
|
||
LOG(ERROR) << "Data pack file corruption: "
|
||
@@ -461,6 +470,14 @@ bool DataPack::GetStringPiece(uint16_t resource_id,
|
||
<< "file modified?";
|
||
return false;
|
||
}
|
||
+ if (target->file_offset > next_entry->file_offset) {
|
||
+ size_t entry_index = target - resource_table_;
|
||
+ size_t next_index = next_entry - resource_table_;
|
||
+ LOG(ERROR) << "Entry #" << next_index << " in data pack is before Entry #"
|
||
+ << entry_index << ". This should have been caught when loading. "
|
||
+ << "Was the file modified?";
|
||
+ return false;
|
||
+ }
|
||
|
||
MaybePrintResourceId(resource_id);
|
||
size_t length = next_entry->file_offset - target->file_offset;
|
||
diff --git a/chromium/ui/base/resource/data_pack_literal.cc b/chromium/ui/base/resource/data_pack_literal.cc
|
||
index f6669ed82447..70e225b6e84e 100644
|
||
--- src/3rdparty/chromium/ui/base/resource/data_pack_literal.cc
|
||
+++ src/3rdparty/chromium/ui/base/resource/data_pack_literal.cc
|
||
@@ -91,6 +91,18 @@ const char kSampleCorruptPakContents[] = {
|
||
|
||
const size_t kSampleCorruptPakSize = sizeof(kSampleCorruptPakContents);
|
||
|
||
+const uint8_t kSampleMisorderedPakContents[] = {
|
||
+ 0x05, 0x00, 0x00, 0x00, // version
|
||
+ 0x01, 0x00, 0x00, 0x00, // encoding + padding
|
||
+ 0x02, 0x00, 0x00, 0x00, // num_resources, num_aliases
|
||
+ 0x06, 0x00, 0x2a, 0x00, 0x00, 0x00, // index entry 6 (wrong order)
|
||
+ 0x04, 0x00, 0x1e, 0x00, 0x00, 0x00, // index entry 4
|
||
+ 0x00, 0x00, 0x36, 0x00, 0x00, 0x00, // extra entry for the size of last
|
||
+ 't', 'h', 'i', 's', ' ', 'i', 's', ' ', 'i', 'd', ' ', '4',
|
||
+ 't', 'h', 'i', 's', ' ', 'i', 's', ' ', 'i', 'd', ' ', '6'};
|
||
+
|
||
+const size_t kSampleMisorderedPakSize = sizeof(kSampleMisorderedPakContents);
|
||
+
|
||
const char kSamplePakContents2x[] = {
|
||
0x04, 0x00, 0x00, 0x00, // header(version
|
||
0x01, 0x00, 0x00, 0x00, // no. entries
|
||
diff --git a/chromium/ui/base/resource/data_pack_literal.h b/chromium/ui/base/resource/data_pack_literal.h
|
||
index 83a8dc04c141..a7fcf2bf85c7 100644
|
||
--- src/3rdparty/chromium/ui/base/resource/data_pack_literal.h
|
||
+++ src/3rdparty/chromium/ui/base/resource/data_pack_literal.h
|
||
@@ -19,6 +19,8 @@ extern const char kEmptyPakContents[];
|
||
extern const size_t kEmptyPakSize;
|
||
extern const char kSampleCorruptPakContents[];
|
||
extern const size_t kSampleCorruptPakSize;
|
||
+extern const uint8_t kSampleMisorderedPakContents[];
|
||
+extern const size_t kSampleMisorderedPakSize;
|
||
|
||
} // namespace ui
|
||
|
||
From 629a490cede4673cec29addd4629c432319a3b6f Mon Sep 17 00:00:00 2001
|
||
From: =?UTF-8?q?Peter=20Bostr=C3=B6m?= <pbos@chromium.org>
|
||
Date: Tue, 23 Jan 2024 01:06:06 +0000
|
||
Subject: [PATCH] [Backport] Security bug 1519980
|
||
MIME-Version: 1.0
|
||
Content-Type: text/plain; charset=UTF-8
|
||
Content-Transfer-Encoding: 8bit
|
||
|
||
Manual cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5226127:
|
||
Speculatively fix race in mojo ShutDownOnIOThread
|
||
|
||
This acquires `write_lock_` before resetting handles used by WriteNoLock
|
||
(which is called under the same lock in another thread). We also set
|
||
`reject_writes_` to prevent future write attempts after shutdown. That
|
||
seems strictly more correct.
|
||
|
||
We also acquire `fds_to_close_lock_` before clearing the FDs.
|
||
|
||
I was unable to repro locally as content_browsertests just times out
|
||
in my local setup without reporting anything interesting. This seems
|
||
strictly more correct though.
|
||
|
||
Bug: 1519980
|
||
Change-Id: I96279936ca908ecb98eddd381df20d61597cba43
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5226127
|
||
Auto-Submit: Peter Boström <pbos@chromium.org>
|
||
Reviewed-by: Ken Rockot <rockot@google.com>
|
||
Commit-Queue: Ken Rockot <rockot@google.com>
|
||
Commit-Queue: Peter Boström <pbos@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#1250580}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/537376
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
chromium/mojo/core/channel_posix.cc | 27 ++++++++++++++++-----------
|
||
1 file changed, 16 insertions(+), 11 deletions(-)
|
||
|
||
diff --git a/chromium/mojo/core/channel_posix.cc b/chromium/mojo/core/channel_posix.cc
|
||
index d7d9d6cfee15..e17aa8d82a91 100644
|
||
--- src/3rdparty/chromium/mojo/core/channel_posix.cc
|
||
+++ src/3rdparty/chromium/mojo/core/channel_posix.cc
|
||
@@ -242,18 +242,23 @@ class ChannelPosix : public Channel,
|
||
void ShutDownOnIOThread() {
|
||
base::CurrentThread::Get()->RemoveDestructionObserver(this);
|
||
|
||
- read_watcher_.reset();
|
||
- write_watcher_.reset();
|
||
- if (leak_handle_) {
|
||
- ignore_result(socket_.release());
|
||
- server_.TakePlatformHandle().release();
|
||
- } else {
|
||
- socket_.reset();
|
||
- ignore_result(server_.TakePlatformHandle());
|
||
+ {
|
||
+ base::AutoLock lock(write_lock_);
|
||
+ reject_writes_ = true;
|
||
+ read_watcher_.reset();
|
||
+ write_watcher_.reset();
|
||
+ if (leak_handle_) {
|
||
+ std::ignore = socket_.release();
|
||
+ server_.TakePlatformHandle().release();
|
||
+ } else {
|
||
+ socket_.reset();
|
||
+ std::ignore = server_.TakePlatformHandle();
|
||
+ }
|
||
+ #if defined(OS_IOS)
|
||
+ base::AutoLock fd_lock(fds_to_close_lock_);
|
||
+ fds_to_close_.clear();
|
||
+ #endif
|
||
}
|
||
-#if defined(OS_IOS)
|
||
- fds_to_close_.clear();
|
||
-#endif
|
||
|
||
// May destroy the |this| if it was the last reference.
|
||
self_ = nullptr;
|
||
From 024962f9456bbb5823a877441e92ca3af30279a6 Mon Sep 17 00:00:00 2001
|
||
From: Tsuyoshi Horo <horo@chromium.org>
|
||
Date: Tue, 9 Jan 2024 08:40:00 +0000
|
||
Subject: [PATCH] [Backport] CVE-2024-1077: Use after free in Network
|
||
|
||
Cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5179746:
|
||
Fix UAF in SourceStreamToDataPipe
|
||
|
||
SourceStreamToDataPipe::ReadMore() is passing a callback with
|
||
Unretained(this) to net::SourceStream::Read(). But this callback may be
|
||
called even after the SourceStream is destructed. This is causing UAF
|
||
issue (crbug.com/1511085).
|
||
|
||
To solve this problem, this CL changes ReadMore() method to pass a
|
||
callback with a weak ptr of this.
|
||
|
||
Bug: 1511085
|
||
Change-Id: Idd4e34ff300ff5db2de1de7b303841c7db3a964a
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5179746
|
||
Reviewed-by: Adam Rice <ricea@chromium.org>
|
||
Commit-Queue: Tsuyoshi Horo <horo@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#1244526}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/537377
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../network/public/cpp/source_stream_to_data_pipe.cc | 6 +++---
|
||
1 file changed, 3 insertions(+), 3 deletions(-)
|
||
|
||
diff --git a/chromium/services/network/public/cpp/source_stream_to_data_pipe.cc b/chromium/services/network/public/cpp/source_stream_to_data_pipe.cc
|
||
index d6ade7b0ec52..615804ad8d29 100644
|
||
--- src/3rdparty/chromium/services/network/public/cpp/source_stream_to_data_pipe.cc
|
||
+++ src/3rdparty/chromium/services/network/public/cpp/source_stream_to_data_pipe.cc
|
||
@@ -53,9 +53,9 @@ void SourceStreamToDataPipe::ReadMore() {
|
||
|
||
scoped_refptr<net::IOBuffer> buffer(
|
||
new network::NetToMojoIOBuffer(pending_write_.get()));
|
||
- int result = source_->Read(
|
||
- buffer.get(), base::checked_cast<int>(num_bytes),
|
||
- base::BindOnce(&SourceStreamToDataPipe::DidRead, base::Unretained(this)));
|
||
+ int result = source_->Read(buffer.get(), base::checked_cast<int>(num_bytes),
|
||
+ base::BindOnce(&SourceStreamToDataPipe::DidRead,
|
||
+ weak_factory_.GetWeakPtr()));
|
||
|
||
if (result != net::ERR_IO_PENDING)
|
||
DidRead(result);
|
||
From 06e89516b94241e088f6d350bc3a113e726355cd Mon Sep 17 00:00:00 2001
|
||
From: Jean-Philippe Gravel <jpgravel@chromium.org>
|
||
Date: Wed, 17 Jan 2024 17:45:45 +0000
|
||
Subject: [PATCH] [Backport] CVE-2024-1060: Use after free in Canvas
|
||
|
||
Manual backport of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5198419:
|
||
Fix use-after-free in DrawTextInternal
|
||
|
||
DrawTextInternal was calling GetOrCreatePaintCanvas multiple times,
|
||
once at the start of the function, once inside of the
|
||
BaseRenderingContext2DAutoRestoreSkCanvas helper class and once in the
|
||
Draw call. GetOrCreatePaintCanvas destroys the canvas resource provider
|
||
if the GPU context is lost. If this happens on the second call to
|
||
GetOrCreatePaintCanvas, destroying the resource provider will
|
||
invalidate the cc::PaintCanvas returned by the first call to
|
||
GetOrCreatePaintCanvas.
|
||
|
||
The GPU process can technically crash at any point during the renderer
|
||
process execution (perhaps because of something another renderer
|
||
process did). We therefore have to assume that any call to
|
||
GetOrCreatePaintCanvas can invalidate previously returned
|
||
cc::PaintCanvas.
|
||
|
||
Change-Id: Ifa77735ab1b2b55b3d494f886b8566299937f6fe
|
||
Fixed: 1511567
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5198419
|
||
Reviewed-by: Fernando Serboncini <fserb@chromium.org>
|
||
Commit-Queue: Jean-Philippe Gravel <jpgravel@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#1248204}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/537378
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../canvas2d/canvas_rendering_context_2d.cc | 50 ++++++-------------
|
||
.../canvas2d/canvas_rendering_context_2d.h | 2 -
|
||
2 files changed, 16 insertions(+), 36 deletions(-)
|
||
|
||
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
|
||
index ade14e0102ae..fe8c4cd277ce 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.cc
|
||
@@ -86,35 +86,6 @@ static bool ContextLostRestoredEventsEnabled() {
|
||
return RuntimeEnabledFeatures::Canvas2dContextLostRestoredEnabled();
|
||
}
|
||
|
||
-// Drawing methods need to use this instead of SkAutoCanvasRestore in case
|
||
-// overdraw detection substitutes the recording canvas (to discard overdrawn
|
||
-// draw calls).
|
||
-class CanvasRenderingContext2DAutoRestoreSkCanvas {
|
||
- STACK_ALLOCATED();
|
||
-
|
||
- public:
|
||
- explicit CanvasRenderingContext2DAutoRestoreSkCanvas(
|
||
- CanvasRenderingContext2D* context)
|
||
- : context_(context), save_count_(0) {
|
||
- DCHECK(context_);
|
||
- cc::PaintCanvas* c = context_->GetOrCreatePaintCanvas();
|
||
- if (c) {
|
||
- save_count_ = c->getSaveCount();
|
||
- }
|
||
- }
|
||
-
|
||
- ~CanvasRenderingContext2DAutoRestoreSkCanvas() {
|
||
- cc::PaintCanvas* c = context_->GetOrCreatePaintCanvas();
|
||
- if (c)
|
||
- c->restoreToCount(save_count_);
|
||
- context_->ValidateStateStack();
|
||
- }
|
||
-
|
||
- private:
|
||
- CanvasRenderingContext2D* context_;
|
||
- int save_count_;
|
||
-};
|
||
-
|
||
CanvasRenderingContext2D::CanvasRenderingContext2D(
|
||
HTMLCanvasElement* canvas,
|
||
const CanvasContextCreationAttributesCore& attrs)
|
||
@@ -850,9 +821,11 @@ void CanvasRenderingContext2D::DrawTextInternal(
|
||
// to 0, for example), so update style before grabbing the PaintCanvas.
|
||
canvas()->GetDocument().UpdateStyleAndLayoutTreeForNode(canvas());
|
||
|
||
- cc::PaintCanvas* c = GetOrCreatePaintCanvas();
|
||
- if (!c)
|
||
+ // Abort if we don't have a paint canvas (e.g. the context was lost).
|
||
+ cc::PaintCanvas* paint_canvas = GetOrCreatePaintCanvas();
|
||
+ if (!paint_canvas) {
|
||
return;
|
||
+ }
|
||
|
||
if (!std::isfinite(x) || !std::isfinite(y))
|
||
return;
|
||
@@ -920,14 +893,13 @@ void CanvasRenderingContext2D::DrawTextInternal(
|
||
if (paint_type == CanvasRenderingContext2DState::kStrokePaintType)
|
||
InflateStrokeRect(bounds);
|
||
|
||
- CanvasRenderingContext2DAutoRestoreSkCanvas state_restorer(this);
|
||
if (use_max_width) {
|
||
- c->save();
|
||
+ paint_canvas->save();
|
||
// We draw when fontWidth is 0 so compositing operations (eg, a "copy" op)
|
||
// still work. As the width of canvas is scaled, so text can be scaled to
|
||
// match the given maxwidth, update text location so it appears on desired
|
||
// place.
|
||
- c->scale(clampTo<float>(width / font_width), 1);
|
||
+ paint_canvas->scale(clampTo<float>(width / font_width), 1);
|
||
location.SetX(location.X() / clampTo<float>(width / font_width));
|
||
}
|
||
|
||
@@ -942,6 +914,16 @@ void CanvasRenderingContext2D::DrawTextInternal(
|
||
[](const SkIRect& rect) // overdraw test lambda
|
||
{ return false; },
|
||
bounds, paint_type, CanvasRenderingContext2DState::kNoImage);
|
||
+
|
||
+ if (use_max_width) {
|
||
+ // Cannot use `paint_canvas` in case recording canvas was substituted or
|
||
+ // destroyed during draw call.
|
||
+ cc::PaintCanvas* c = GetPaintCanvas();
|
||
+ if (c) {
|
||
+ c->restore();
|
||
+ }
|
||
+ }
|
||
+ ValidateStateStack();
|
||
}
|
||
|
||
const Font& CanvasRenderingContext2D::AccessFont() {
|
||
diff --git a/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h b/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
|
||
index ac10ae4389a8..b0d09f182a7d 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/modules/canvas/canvas2d/canvas_rendering_context_2d.h
|
||
@@ -236,8 +236,6 @@ class MODULES_EXPORT CanvasRenderingContext2D final
|
||
void WillOverwriteCanvas() override;
|
||
|
||
private:
|
||
- friend class CanvasRenderingContext2DAutoRestoreSkCanvas;
|
||
-
|
||
void DispatchContextLostEvent(TimerBase*);
|
||
void DispatchContextRestoredEvent(TimerBase*);
|
||
void TryRestoreContextEvent(TimerBase*);
|
||
From 6f0832285560ce72dfe1403a1c2d7a53f6bf7f55 Mon Sep 17 00:00:00 2001
|
||
From: John Stiles <johnstiles@google.com>
|
||
Date: Mon, 29 Jan 2024 23:50:14 +0000
|
||
Subject: [PATCH] [Backport] CVE-2024-1283: Heap buffer overflow in Skia
|
||
|
||
Manual cherry-pick of patch originally reviewed on
|
||
https://chromium-review.googlesource.com/c/chromium/src/+/5241305:
|
||
Fix a crash when a BMP image contains an unnecessary EOF code.
|
||
|
||
Previously, this would try to perform color correction on a row
|
||
one past the end of the image data.
|
||
|
||
Bug: 1521893
|
||
Change-Id: I425437005b9ef400138556705616095857d2cf0d
|
||
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5241305
|
||
Auto-Submit: John Stiles <johnstiles@google.com>
|
||
Commit-Queue: John Stiles <johnstiles@google.com>
|
||
Reviewed-by: Peter Kasting <pkasting@chromium.org>
|
||
Cr-Commit-Position: refs/heads/main@{#1253633}
|
||
Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/538168
|
||
Reviewed-by: Michal Klocek <michal.klocek@qt.io>
|
||
---
|
||
.../image-decoders/bmp/bmp_image_reader.cc | 18 +++++++++++++++---
|
||
1 file changed, 15 insertions(+), 3 deletions(-)
|
||
|
||
diff --git a/chromium/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc b/chromium/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
|
||
index 562223397030..662e66cab884 100644
|
||
--- src/3rdparty/chromium/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
|
||
+++ src/3rdparty/chromium/third_party/blink/renderer/platform/image-decoders/bmp/bmp_image_reader.cc
|
||
@@ -827,8 +827,11 @@ BMPImageReader::ProcessingResult BMPImageReader::ProcessRLEData() {
|
||
// the image.
|
||
const uint8_t count = ReadUint8(0);
|
||
const uint8_t code = ReadUint8(1);
|
||
- if ((count || (code != 1)) && PastEndOfImage(0))
|
||
+ const bool is_past_end_of_image = PastEndOfImage(0);
|
||
+ if ((count || (code != 1)) && is_past_end_of_image) {
|
||
return kFailure;
|
||
+ }
|
||
+
|
||
|
||
// Decode.
|
||
if (!count) {
|
||
@@ -849,7 +852,9 @@ BMPImageReader::ProcessingResult BMPImageReader::ProcessRLEData() {
|
||
(is_top_down_ ? (coord_.Y() < (parent_->Size().Height() - 1))
|
||
: (coord_.Y() > 0)))
|
||
buffer_->SetHasAlpha(true);
|
||
- ColorCorrectCurrentRow();
|
||
+ if (!is_past_end_of_image) {
|
||
+ ColorCorrectCurrentRow();
|
||
+ }
|
||
// There's no need to move |coord_| here to trigger the caller
|
||
// to call SetPixelsChanged(). If the only thing that's changed
|
||
// is the alpha state, that will be properly written into the
|
||
@@ -1061,6 +1066,13 @@ void BMPImageReader::ColorCorrectCurrentRow() {
|
||
const ColorProfileTransform* const transform = parent_->ColorTransform();
|
||
if (!transform)
|
||
return;
|
||
+ int decoder_width = parent_->Size().Width();
|
||
+ // Enforce 0 ≤ current row < bitmap height.
|
||
+ CHECK_GE(coord_.Y(), 0);
|
||
+ CHECK_LT(coord_.Y(), buffer_->Bitmap().height());
|
||
+ // Enforce decoder width == bitmap width exactly. (The bitmap rowbytes might
|
||
+ // add a bit of padding, but we are only converting one row at a time.)
|
||
+ CHECK_EQ(decoder_width, buffer_->Bitmap().width());
|
||
ImageFrame::PixelData* const row = buffer_->GetAddr(0, coord_.Y());
|
||
const skcms_PixelFormat fmt = XformColorFormat();
|
||
const skcms_AlphaFormat alpha =
|
||
@@ -1069,7 +1081,7 @@ void BMPImageReader::ColorCorrectCurrentRow() {
|
||
: skcms_AlphaFormat_Unpremul;
|
||
const bool success =
|
||
skcms_Transform(row, fmt, alpha, transform->SrcProfile(), row, fmt, alpha,
|
||
- transform->DstProfile(), parent_->Size().Width());
|
||
+ transform->DstProfile(), decoder_width);
|
||
DCHECK(success);
|
||
buffer_->SetPixelsChanged(true);
|
||
}
|