diff --git a/www/qt5-webengine/Makefile b/www/qt5-webengine/Makefile index b1a526c9a8cb..908b666c6e20 100644 --- a/www/qt5-webengine/Makefile +++ b/www/qt5-webengine/Makefile @@ -1,179 +1,179 @@ # QtWebEngine itself is a very thin layer of Qt code on top of a large part of # Chromium (everything up to the content/ layer). As such, most of the work in # this port revolves around taming Chromium and getting it to build on FreeBSD. # While it does build at the moment, there are several items that should be # investigated or improved: # - We are using several stub files, especially in Chromium's base/ and net/ # layers. We should look at implementing the missing bits instead. # - We are currently not using any sandboxing mechanism. # - We need to see if more "use_system_" flags can be passed. # - The process of porting QtWebEngine needs to be documented so we can move to # newer releases more easily. # # Also note that, due to the insane amount of patches this port needs, it tends # to lag behind the rest of the official Qt5 ones, which is why we set # QT5_VERSION and DISTINFO_FILE here. # In order to successfully build this port in poudriere you need to add # MAX_FILES_qt5_webengine=4096 to /usr/local/etc/poudriere.conf PORTNAME= webengine DISTVERSION= ${QT5_VERSION}${QT5_KDE_PATCH} -PORTREVISION= 3 +PORTREVISION= 4 CATEGORIES= www PKGNAMEPREFIX= qt5- MAINTAINER= kde@FreeBSD.org COMMENT= Qt 5 library to render web content BUILD_DEPENDS= bison:devel/bison \ ${LOCALBASE}/include/linux/input.h:devel/evdev-proto \ ${LOCALBASE}/include/linux/videodev2.h:multimedia/v4l_compat LIB_DEPENDS= libavcodec.so:multimedia/ffmpeg \ libdbus-1.so:devel/dbus \ libdouble-conversion.so:devel/double-conversion \ libevent.so:devel/libevent \ libfontconfig.so:x11-fonts/fontconfig \ libfreetype.so:print/freetype2 \ libharfbuzz.so:print/harfbuzz \ libjsoncpp.so:devel/jsoncpp \ liblcms2.so:graphics/lcms2 \ libnspr4.so:devel/nspr \ libnss3.so:security/nss \ libopenh264.so:multimedia/openh264 \ libopus.so:audio/opus \ libpci.so:devel/libpci \ libpng.so:graphics/png \ libre2.so:devel/re2 \ libsnappy.so:archivers/snappy \ libvpx.so:multimedia/libvpx \ libwebp.so:graphics/webp DISTINFO_FILE= ${.CURDIR}/distinfo QT5_VERSION= ${_KDE_webengine_VERSION} # Add extra-patch-no-mempcpy-nasm only when there's no mempcpy() in base. # Nested variable expansion avoids executing the test when not needed for # expanding EXTRA_PATCHES. # mempcpy was introduced in ee37f64cf875255338f917a9da76c643cf59786c EXTRA_PATCHES+= ${"${:!${GREP} mempcpy ${CROSS_SYSROOT}/usr/include/string.h \ || ${TRUE}!}" == "":?${PATCHDIR}/extra-patch-no-mempcpy-nasm:} OPTIONS_SINGLE= AUDIO OPTIONS_SINGLE_AUDIO= ALSA PULSEAUDIO SNDIO OPTIONS_DEFAULT= ALSA AUDIO_DESC= Audio backend # Need the alsa plugins to get sound at runtime, otherwise messages # that the pcm_oss plugin can't be opened. ALSA_LIB_DEPENDS= libasound.so:audio/alsa-lib ALSA_RUN_DEPENDS= alsa-plugins>=0:audio/alsa-plugins ALSA_VARS= QMAKE_CONFIGURE_ARGS+=-alsa ALSA_VARS_OFF= QMAKE_CONFIGURE_ARGS+=-no-alsa PULSEAUDIO_LIB_DEPENDS= libpulse.so:audio/pulseaudio PULSEAUDIO_VARS= QMAKE_CONFIGURE_ARGS+=-pulseaudio PULSEAUDIO_VARS_OFF= QMAKE_CONFIGURE_ARGS+=-no-pulseaudio SNDIO_LIB_DEPENDS= libsndio.so:audio/sndio SNDIO_VARS= QMAKE_CONFIGURE_ARGS+=-sndio SNDIO_VARS_OFF= QMAKE_CONFIGURE_ARGS+=-no-sndio # We pass `norecursive' to USES=qmake because src/plugins/plugins.pro checks # whether webenginewidgets is available, which fails when qmake processes all # .pro files at once. USES= gl gnome gperf jpeg minizip ninja:build nodejs:build,lts \ perl5 pkgconfig python:build qmake:norecursive,outsource \ qt-dist:5,webengine shebangfix xorg USE_GL= gl USE_GNOME= glib20 libxml2 libxslt USE_PERL5= build USE_QT= core declarative gui location network printsupport \ webchannel widgets \ buildtools:build designer:build qmake:build USE_XORG= x11 xcb xcomposite xcursor xdamage xext xfixes xi xkbfile \ xorgproto xrandr xrender xscrnsaver xtst QMAKE_CONFIGURE_ARGS= -proprietary-codecs -system-ffmpeg # We could just set it to an empty string as well. "all" does not account for # dependencies correctly in the generated Makefiles, use the right target here. ALL_TARGET= first # We need ar(1) from ports because the Chromium code uses the @file syntax. # We then need to ensure ld(1) from ports is used because of the archives ar(1) # generated. USE_BINUTILS= yes CC+= "-B${LOCALBASE}/bin" CXX+= "-B${LOCALBASE}/bin" # The build system reads the environment variable $NINJA_PATH to decide whether # to boostrap ninja or not (and also to invoke it afterwards). CC and CXX are # read by some Chromium code to determine which compiler to invoke when running # some configuration tests. # Since we use USES=qmake:norecursive, we also need to pass some variables to # MAKE_ENV because part of the configuration process happens during the build. CONFIGURE_ENV+= NINJAFLAGS="-j${MAKE_JOBS_NUMBER}" \ NINJA_PATH="${LOCALBASE}/bin/ninja" \ PATH=${CONFIGURE_WRKSRC}/bin:${LOCALBASE}/bin:${PATH} MAKE_ENV+= CC="${CC}" CXX="${CXX}" \ C_INCLUDE_PATH=${LOCALBASE}/include \ CPLUS_INCLUDE_PATH=${LOCALBASE}/include \ ${CONFIGURE_ENV} QT_BINARIES= yes .include .if ${ARCH:Mmips*} || ${ARCH:Mpowerpc*} PLIST_SUB+= BE="" LE="@comment " .else PLIST_SUB+= BE="@comment " LE="" .endif post-extract: # Install FreeBSD's freebsd.pri file. ${CP} ${FILESDIR}/freebsd.pri ${WRKSRC}/src/buildtools/config/freebsd.pri post-extract-SNDIO-on: @cd ${WRKSRC}/src/3rdparty/chromium/media/audio && ${MKDIR} sndio openbsd @${CP} ${FILESDIR}/sndio_*put.* \ ${WRKSRC}/src/3rdparty/chromium/media/audio/sndio @${CP} ${FILESDIR}/audio_manager_openbsd.* \ ${WRKSRC}/src/3rdparty/chromium/media/audio/openbsd post-patch: @${REINPLACE_CMD} -e 's|%%LOCALBASE%%|${LOCALBASE}|' \ ${WRKSRC}/src/3rdparty/chromium/base/linux_util.cc \ ${WRKSRC}/src/3rdparty/chromium/base/test/BUILD.gn \ ${WRKSRC}/src/3rdparty/chromium/build/toolchain/gcc_toolchain.gni \ ${WRKSRC}/src/3rdparty/chromium/chrome/common/chrome_paths.cc \ ${WRKSRC}/src/3rdparty/chromium/third_party/pdfium/core/fxge/fx_ge_linux.cpp \ ${WRKSRC}/src/3rdparty/gn/build/gen.py @${REINPLACE_CMD} -E -e 's|^(MODULE_VERSION = ).*|\1${QT5_VERSION}|' \ ${WRKSRC}/.qmake.conf .if ${ARCH:Mmips*} || ${ARCH:Mpowerpc*} @${REINPLACE_CMD} -e 's/icudtl.dat/icudtb.dat/' \ ${WRKSRC}/src/core/core_module.pro .endif pre-configure: # Link in ${PYTHON_CMD} to ${CONFIGURE_WRKSRC}/bin -- the scripts hardcode 'python' # in too many places to reasonably patch. So just link in ${PYTHON_CMD} to work around # $LOCALBASE/bin/python being python3 if the default versions is set to 3.x. ${MKDIR} ${CONFIGURE_WRKSRC}/bin && ${LN} -s ${PYTHON_CMD} ${CONFIGURE_WRKSRC}/bin/python # Unbundle a few dependencies. cd ${WRKSRC}/src/3rdparty/chromium && ${SETENV} ${CONFIGURE_ENV} ${PYTHON_CMD} \ ./build/linux/unbundle/replace_gn_files.py --system-libraries\ fontconfig freetype harfbuzz-ng libdrm libevent libpng libwebp libxml libxslt openh264 opus || ${FALSE} # Rerun syncqt.pl -- otherwise the resulting package misses some forwarding headers. cd ${WRKSRC} && ${QT_BINDIR}/syncqt.pl -version ${QT5_VERSION} post-build: # Fix version mismatches for CMake .for module in Pdf PdfWidgets WebEngine WebEngineCore WebEngineWidgets @${REINPLACE_CMD} -e '/${QT5_VERSION} $${_Qt5${module}_FIND_VERSION_EXACT}/s|${QT5_VERSION}|'"$$(${MAKE} -C ../../devel/qt5-core -VQT5_VERSION)"'|' \ ${BUILD_WRKSRC}/lib/cmake/Qt5${module}/Qt5${module}Config.cmake .endfor .include diff --git a/www/qt5-webengine/files/patch-security-rollup b/www/qt5-webengine/files/patch-security-rollup index dd53f7adcba8..6fd5660e68f7 100644 --- a/www/qt5-webengine/files/patch-security-rollup +++ b/www/qt5-webengine/files/patch-security-rollup @@ -1,722 +1,1920 @@ 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 From 8ca846140881c9480b18bc9645b38fb9ea565ea3 Mon Sep 17 00:00:00 2001 From: Ken Rockot 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 Reviewed-by: Robert Sesek Cr-Original-Commit-Position: refs/heads/main@{#1221953} Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5038080 Auto-Submit: Ken Rockot Commit-Queue: Daniel Cheng Reviewed-by: Daniel Cheng 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 --- 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 endpoints_to_remove; std::vector> 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 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 Commit-Queue: Jordan Bayles Cr-Commit-Position: refs/heads/main@{#1206698} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/523700 Reviewed-by: Michal Klocek --- .../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 device_; const scoped_refptr 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 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 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 Reviewed-by: Jakob Linke Cr-Commit-Position: refs/heads/main@{#90560} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/523701 Reviewed-by: Michal Klocek --- .../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 RegExpMacroAssemblerARM::GetCode(Handle 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 RegExpMacroAssemblerARM::GetCode(Handle 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(re_frame, kIsolate), @@ -1110,7 +1115,8 @@ int RegExpMacroAssemblerARM::CheckStackGuardState(Address* return_address, return_address, re_code, frame_entry_address
(re_frame, kInputString), frame_entry_address(re_frame, kInputStart), - frame_entry_address(re_frame, kInputEnd)); + frame_entry_address(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 RegExpMacroAssemblerARM64::GetCode(Handle 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 RegExpMacroAssemblerARM64::GetCode(Handle 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(re_frame, kIsolate), start_index, static_cast(frame_entry(re_frame, kDirectCall)), return_address, re_code, frame_entry_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 RegExpMacroAssemblerIA32::GetCode(Handle 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 RegExpMacroAssemblerIA32::GetCode(Handle 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(re_frame, kIsolate), @@ -1122,7 +1128,8 @@ int RegExpMacroAssemblerIA32::CheckStackGuardState(Address* return_address, return_address, re_code, frame_entry_address
(re_frame, kInputString), frame_entry_address(re_frame, kInputStart), - frame_entry_address(re_frame, kInputEnd)); + frame_entry_address(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 RegExpMacroAssemblerX64::GetCode(Handle 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 RegExpMacroAssemblerX64::GetCode(Handle 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(re_frame, kIsolate), @@ -1198,7 +1206,8 @@ int RegExpMacroAssemblerX64::CheckStackGuardState(Address* return_address, return_address, re_code, frame_entry_address
(re_frame, kInputString), frame_entry_address(re_frame, kInputStart), - frame_entry_address(re_frame, kInputEnd)); + frame_entry_address(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 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 Reviewed-by: Camillo Bruni Cr-Commit-Position: refs/heads/main@{#90669} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/523702 Reviewed-by: Michal Klocek --- .../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 +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 +--- + 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(UINT16_MAX)) { ++ if (fVertexCount > INT32_MAX - that->fVertexCount) { ++ return CombineResult::kCannotCombine; ++ } ++ ++ if (fVertexCount > SkTo(UINT16_MAX) - that->fVertexCount) { + return CombineResult::kCannotCombine; + } + +From 31c7c9445955762102fdcd04e71da6114e1fcb4c Mon Sep 17 00:00:00 2001 +From: Zakhar Voit +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ä +Auto-Submit: Marja Hölttä +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 +--- + 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 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 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 +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 +Commit-Queue: Kai Ninomiya +Reviewed-by: Brendon Tiszka +Cr-Commit-Position: refs/heads/main@{#1230735} +Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/526233 +Reviewed-by: Michal Klocek +--- + .../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(webgpu_helper.get()); + + // The WebGPUImplementation exposes the WebGPUInterface, as well as the + // gpu::ContextSupport interface. + auto webgpu_impl = std::make_unique( +- 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(raster_helper.get()); + + // The RasterImplementation exposes the RasterInterface, as well as the + // gpu::ContextSupport interface. + DCHECK(channel_); + auto raster_impl = std::make_unique( +- 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(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( +- 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( + 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 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 command_buffer_; ++ ++ // Points to command_buffer_. + std::unique_ptr helper_; ++ // Points to helper_. + std::unique_ptr 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 gles2_impl_; ++ // Points to gles2_impl_. + std::unique_ptr trace_impl_; +- std::unique_ptr raster_interface_; ++ // Points to transfer_buffer_, helper_, and command_buffer_. ++ std::unique_ptr raster_interface_; ++ // Points to transfer_buffer_, helper_, and command_buffer_. + std::unique_ptr webgpu_interface_; + ++ // END IMPORTANT NOTE // ++ ////////////////////////////////////////////////////////////////////////////// ++ ++ // Owned by either gles2_impl_ or raster_interface_, not both. ++ gpu::ImplementationBase* impl_; ++ + std::unique_ptr gr_context_; + #if BUILDFLAG(SKIA_USE_DAWN) + std::unique_ptr +From 2d8ce130db72ce75e2ca8b51f3c32938fbff9143 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20Br=C3=BCning?= +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 +--- + .../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 gr_context_; + #if BUILDFLAG(SKIA_USE_DAWN) +From c8088aea77818f87d42f709ddcb743b907c38e9c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Michael=20Br=C3=BCning?= +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 +--- + 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 +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 +Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532069 +Reviewed-by: Michal Klocek +--- + .../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 +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 +Auto-Submit: Joshua Pawlicki +Code-Coverage: findit-for-me@appspot.gserviceaccount.com +Commit-Queue: Sorin Jianu +Reviewed-by: Sorin Jianu +Cr-Commit-Position: refs/heads/main@{#1239849} +Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532070 +Reviewed-by: Michal Klocek +--- + 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 + #include + #include + #include +@@ -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>; + using RepeatedProof = google::protobuf::RepeatedPtrField; +@@ -109,6 +113,18 @@ VerifierResult VerifyCrx3( + if (ReadAndHashBuffer(header_bytes.data(), header_size, file, hash) != + static_cast(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?= +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 +Commit-Queue: Dominik Inführ +Cr-Commit-Position: refs/heads/main@{#91568} +Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532071 +Reviewed-by: Allan Sandfeld Jensen +--- + 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 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 +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 +Reviewed-by: Leszek Swirski +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 +--- + 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 Runtime::HasProperty(Isolate* isolate, + : ReadOnlyRoots(isolate).false_value_handle(); + } + +-namespace { +- +-void GeneralizeAllTransitionsToFieldAsMutable(Isolate* isolate, Handle map, +- Handle name) { +- InternalIndex descriptor(map->NumberOfOwnDescriptors()); +- +- Handle 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 target = target_maps[i]; +- PropertyDetails details = +- target->instance_descriptors(isolate) +- .GetDetails(descriptor); +- Handle 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 receiver, +- Handle 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 receiver_map(receiver->map(), isolate); +- if (receiver_map->IsSpecialReceiverMap()) return false; +- DCHECK(receiver_map->IsJSObjectMap()); +- +- if (!raw_key->IsUniqueName()) return false; +- Handle key = Handle::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 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 backpointer(receiver_map->GetBackPointer(), isolate); +- if (!backpointer->IsMap()) return false; +- Handle parent_map = Handle::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::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 Runtime::DeleteObjectProperty(Isolate* isolate, + Handle receiver, + Handle 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(); +From 1dbdcfd64885f0dc034e73dacf6ef4e20f8351bf Mon Sep 17 00:00:00 2001 +From: Mike Wasserman +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 +Auto-Submit: Mike Wasserman +Reviewed-by: John Abd-El-Malek +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 +--- + 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 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 +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 +Commit-Queue: Gustaf Ullberg +Cr-Commit-Position: refs/heads/main@{#1239233} +Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532066 +Reviewed-by: Michal Klocek +--- + .../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 +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 +Reviewed-by: Michael Wilson +Cr-Original-Commit-Position: refs/heads/main@{#1231040} +Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5112992 +Auto-Submit: Hongchan Choi +Commit-Queue: Rubber Stamper +Bot-Commit: Rubber Stamper +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 +--- + .../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 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 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 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 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 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 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 +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 +Commit-Queue: Ayu Ishii +Reviewed-by: Ayu Ishii +Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/532068 +Reviewed-by: Michal Klocek +--- + 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; ipSrc->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; ipSrc->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; ipSrc->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 */ + }; +