diff options
Diffstat (limited to '')
-rw-r--r-- | www/qt6-webengine/files/patch-security-rollup | 246 |
1 files changed, 246 insertions, 0 deletions
diff --git a/www/qt6-webengine/files/patch-security-rollup b/www/qt6-webengine/files/patch-security-rollup new file mode 100644 index 000000000000..8955c1fb52d9 --- /dev/null +++ b/www/qt6-webengine/files/patch-security-rollup @@ -0,0 +1,246 @@ +Security patches since 6.9.2 release + +CVE-2025-8879: Heap buffer overflow in libaom +CVE-2025-8880: Race in V8 +CVE-2025-8881: Inappropriate implementation in File Picker +CVE-2025-8901: Out of bounds write in ANGLE + +https://github.com/qt/qtwebengine-chromium/compare/136d7fe8aa41c9d4cd764a6b890af9699f5141dd..130-based.diff + +diff --git a/chromium/content/browser/web_contents/file_chooser_impl.cc b/chromium/content/browser/web_contents/file_chooser_impl.cc +index 7e2391bd1afd..d366c5d26bba 100644 +--- src/3rdparty/chromium/content/browser/web_contents/file_chooser_impl.cc ++++ src/3rdparty/chromium/content/browser/web_contents/file_chooser_impl.cc +@@ -169,6 +169,12 @@ void FileChooserImpl::OpenFileChooser(blink::mojom::FileChooserParamsPtr params, + return; + } + ++ // Do not allow open dialogs to have renderer-controlled default_file_name. ++ // See https://crbug.com/433800617 for context. ++ if (params->mode != blink::mojom::FileChooserParams::Mode::kSave) { ++ params->default_file_name = base::FilePath(); ++ } ++ + // Don't allow page with open FileChooser to enter BackForwardCache to avoid + // any unexpected behaviour from BackForwardCache. + BackForwardCache::DisableForRenderFrameHost( +diff --git a/chromium/media/audio/audio_input_device.cc b/chromium/media/audio/audio_input_device.cc +index a7d8e1098241..44abd451c397 100644 +--- src/3rdparty/chromium/media/audio/audio_input_device.cc ++++ src/3rdparty/chromium/media/audio/audio_input_device.cc +@@ -482,7 +482,7 @@ void AudioInputDevice::AudioThreadCallback::Process(uint32_t pending_data) { + const base::TimeTicks capture_time = + base::TimeTicks() + base::Microseconds(buffer->params.capture_time_us); + const base::TimeTicks now_time = base::TimeTicks::Now(); +- DCHECK_GE(now_time, capture_time); ++ // DCHECK_GE(now_time, capture_time); + + AudioGlitchInfo glitch_info{ + .duration = base::Microseconds(buffer->params.glitch_duration_us), +diff --git a/chromium/third_party/angle/src/compiler/translator/Compiler.cpp b/chromium/third_party/angle/src/compiler/translator/Compiler.cpp +index 107f61cf4603..04b698b7fc08 100644 +--- src/3rdparty/chromium/third_party/angle/src/compiler/translator/Compiler.cpp ++++ src/3rdparty/chromium/third_party/angle/src/compiler/translator/Compiler.cpp +@@ -775,24 +775,6 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root, + return false; + } + +- // For now, rewrite pixel local storage before collecting variables or any operations on images. +- // +- // TODO(anglebug.com/40096838): +- // Should this actually run after collecting variables? +- // Do we need more introspection? +- // Do we want to hide rewritten shader image uniforms from glGetActiveUniform? +- if (hasPixelLocalStorageUniforms()) +- { +- ASSERT( +- IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_shader_pixel_local_storage)); +- if (!RewritePixelLocalStorage(this, root, getSymbolTable(), compileOptions, +- getShaderVersion())) +- { +- mDiagnostics.globalError("internal compiler error translating pixel local storage"); +- return false; +- } +- } +- + if (shouldRunLoopAndIndexingValidation(compileOptions) && + !ValidateLimitations(root, mShaderType, &mSymbolTable, &mDiagnostics)) + { +@@ -939,6 +921,24 @@ bool TCompiler::checkAndSimplifyAST(TIntermBlock *root, + return false; + } + ++ // For now, rewrite pixel local storage before collecting variables or any operations on images. ++ // ++ // TODO(anglebug.com/40096838): ++ // Should this actually run after collecting variables? ++ // Do we need more introspection? ++ // Do we want to hide rewritten shader image uniforms from glGetActiveUniform? ++ if (hasPixelLocalStorageUniforms()) ++ { ++ ASSERT( ++ IsExtensionEnabled(mExtensionBehavior, TExtension::ANGLE_shader_pixel_local_storage)); ++ if (!RewritePixelLocalStorage(this, root, getSymbolTable(), compileOptions, ++ getShaderVersion())) ++ { ++ mDiagnostics.globalError("internal compiler error translating pixel local storage"); ++ return false; ++ } ++ } ++ + // Clamping uniform array bounds needs to happen after validateLimitations pass. + if (compileOptions.clampIndirectArrayBounds) + { +diff --git a/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp b/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp +index 927783db73f6..d3481f1a4d1f 100644 +--- src/3rdparty/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp ++++ src/3rdparty/chromium/third_party/angle/src/compiler/translator/ValidateOutputs.cpp +@@ -72,15 +72,19 @@ ValidateOutputsTraverser::ValidateOutputsTraverser(const TExtensionBehavior &ext + void ValidateOutputsTraverser::visitSymbol(TIntermSymbol *symbol) + { + if (symbol->variable().symbolType() == SymbolType::Empty) ++ { + return; ++ } + + if (mVisitedSymbols.count(symbol->uniqueId().get()) == 1) ++ { + return; ++ } + + mVisitedSymbols.insert(symbol->uniqueId().get()); + + TQualifier qualifier = symbol->getQualifier(); +- if (qualifier == EvqFragmentOut) ++ if (qualifier == EvqFragmentOut || qualifier == EvqFragmentInOut) + { + const TLayoutQualifier &layoutQualifier = symbol->getType().getLayoutQualifier(); + if (layoutQualifier.location != -1) +diff --git a/chromium/third_party/blink/public/mojom/choosers/file_chooser.mojom b/chromium/third_party/blink/public/mojom/choosers/file_chooser.mojom +index 22ccb9cc709f..f323fa2aa2eb 100644 +--- src/3rdparty/chromium/third_party/blink/public/mojom/choosers/file_chooser.mojom ++++ src/3rdparty/chromium/third_party/blink/public/mojom/choosers/file_chooser.mojom +@@ -25,7 +25,7 @@ struct FileChooserParams { + kUploadFolder, + + // Allows picking a nonexistent file, and prompts to overwrite if the file +- // already exists. This is not for Blink but for PPAPI. ++ // already exists. + kSave, + }; + Mode mode = kOpen; +@@ -34,7 +34,8 @@ struct FileChooserParams { + // which will be either "Open" or "Save" depending on the mode. + mojo_base.mojom.String16 title; + +- // Default file name to select in the dialog with kSave mode. ++ // Default file name to select in the dialog with kSave mode. This value ++ // is cleared if mode is not kSave. + mojo_base.mojom.FilePath default_file_name; + + // |selected_files| has filenames which a file upload control already +diff --git a/chromium/third_party/libaom/source/libaom/av1/encoder/ratectrl.c b/chromium/third_party/libaom/source/libaom/av1/encoder/ratectrl.c +index 4fd5ec6bf54b..82a48c39cb10 100644 +--- src/3rdparty/chromium/third_party/libaom/source/libaom/av1/encoder/ratectrl.c ++++ src/3rdparty/chromium/third_party/libaom/source/libaom/av1/encoder/ratectrl.c +@@ -3236,8 +3236,9 @@ static void rc_scene_detection_onepass_rt(AV1_COMP *cpi, + // non-zero sad exists along bottom border even though source is static. + const int border = + rc->prev_frame_is_dropped || cpi->svc.number_temporal_layers > 1; +- // Store blkwise SAD for later use +- if (width == cm->render_width && height == cm->render_height) { ++ // Store blkwise SAD for later use. Disable for spatial layers for now. ++ if (width == cm->render_width && height == cm->render_height && ++ cpi->svc.number_spatial_layers == 1) { + if (cpi->src_sad_blk_64x64 == NULL) { + CHECK_MEM_ERROR(cm, cpi->src_sad_blk_64x64, + (uint64_t *)aom_calloc(sb_cols * sb_rows, +diff --git a/chromium/v8/src/wasm/streaming-decoder.cc b/chromium/v8/src/wasm/streaming-decoder.cc +index f3745b4c055a..ce5dad96d52f 100644 +--- src/3rdparty/chromium/v8/src/wasm/streaming-decoder.cc ++++ src/3rdparty/chromium/v8/src/wasm/streaming-decoder.cc +@@ -230,45 +230,61 @@ class V8_EXPORT_PRIVATE AsyncStreamingDecoder : public StreamingDecoder { + }; + + void AsyncStreamingDecoder::OnBytesReceived(base::Vector<const uint8_t> bytes) { +- DCHECK(!full_wire_bytes_.empty()); ++ TRACE_STREAMING("OnBytesReceived(%zu bytes)\n", bytes.size()); ++ ++ // Note: The bytes are passed by the embedder, and they might point into the ++ // sandbox. Hence we copy them once and then process those copied bytes, to ++ // avoid being vulnerable to concurrent modification. ++ // Since we might not be able to store the bytes contiguously in memory, ++ // remember up to two byte vectors to process after copying. ++ base::Vector<const uint8_t> copied_bytes[2] = {{}, {}}; ++ + // Fill the previous vector, growing up to 16kB. After that, allocate new + // vectors on overflow. ++ DCHECK(!full_wire_bytes_.empty()); ++ std::vector<uint8_t>* last_wire_byte_vector = &full_wire_bytes_.back(); ++ size_t existing_vector_size = last_wire_byte_vector->size(); + size_t remaining_capacity = +- std::max(full_wire_bytes_.back().capacity(), size_t{16} * KB) - +- full_wire_bytes_.back().size(); ++ std::max(last_wire_byte_vector->capacity(), size_t{16} * KB) - ++ existing_vector_size; + size_t bytes_for_existing_vector = std::min(remaining_capacity, bytes.size()); +- full_wire_bytes_.back().insert(full_wire_bytes_.back().end(), bytes.data(), +- bytes.data() + bytes_for_existing_vector); ++ last_wire_byte_vector->insert(last_wire_byte_vector->end(), bytes.data(), ++ bytes.data() + bytes_for_existing_vector); ++ copied_bytes[0] = ++ base::VectorOf(last_wire_byte_vector->data() + existing_vector_size, ++ bytes_for_existing_vector); + if (bytes.size() > bytes_for_existing_vector) { + // The previous vector's capacity is not enough to hold all new bytes, and + // it's bigger than 16kB, so expensive to copy. Allocate a new vector for + // the remaining bytes, growing exponentially. + size_t new_capacity = std::max(bytes.size() - bytes_for_existing_vector, +- 2 * full_wire_bytes_.back().capacity()); ++ 2 * last_wire_byte_vector->capacity()); + full_wire_bytes_.emplace_back(); +- full_wire_bytes_.back().reserve(new_capacity); +- full_wire_bytes_.back().insert(full_wire_bytes_.back().end(), +- bytes.data() + bytes_for_existing_vector, +- bytes.end()); ++ last_wire_byte_vector = &full_wire_bytes_.back(); ++ last_wire_byte_vector->reserve(new_capacity); ++ last_wire_byte_vector->insert(last_wire_byte_vector->end(), ++ bytes.data() + bytes_for_existing_vector, ++ bytes.end()); ++ copied_bytes[1] = base::VectorOf(*last_wire_byte_vector); + } ++ // Do not access `bytes` any more after copying. ++ DCHECK_EQ(bytes.size(), copied_bytes[0].size() + copied_bytes[1].size()); ++ bytes = {}; + + if (deserializing()) return; + +- TRACE_STREAMING("OnBytesReceived(%zu bytes)\n", bytes.size()); +- +- size_t current = 0; +- while (ok() && current < bytes.size()) { +- size_t num_bytes = +- state_->ReadBytes(this, bytes.SubVector(current, bytes.size())); +- current += num_bytes; +- module_offset_ += num_bytes; +- if (state_->offset() == state_->buffer().size()) { +- state_ = state_->Next(this); ++ for (base::Vector<const uint8_t> vec : copied_bytes) { ++ size_t current = 0; ++ while (ok() && current < vec.size()) { ++ size_t num_bytes = state_->ReadBytes(this, vec.SubVectorFrom(current)); ++ current += num_bytes; ++ module_offset_ += num_bytes; ++ if (state_->offset() == state_->buffer().size()) { ++ state_ = state_->Next(this); ++ } + } + } +- if (ok()) { +- processor_->OnFinishedChunk(); +- } ++ if (ok()) processor_->OnFinishedChunk(); + } + + size_t AsyncStreamingDecoder::DecodingState::ReadBytes( |