Firefox · DOM
CVE-2026-74990
Memory Corruption in DOM
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifdom/media/webm/WebMDemuxer.cpp |
modified | |
ifgfx/layers/ImageContainer.cpp |
modified |
Files Changed
dom/media/MediaData.cppdom/media/webm/WebMDemuxer.cppgfx/layers/ImageContainer.cpp
Patch
diff --git a/dom/media/MediaData.cpp b/dom/media/MediaData.cpp
index 85a6b1ca0fa..040da354eb6 100644
--- a/dom/media/MediaData.cpp
+++ b/dom/media/MediaData.cpp
@@ -229,9 +229,10 @@ static MediaResult ValidateBufferAndPicture(
}
// Ensure the picture size specified in the headers can be extracted out of
// the frame we've been supplied without indexing out of bounds.
+ // The picture extent and the plane width are both measured in samples.
CheckedUint32 xLimit = aPicture.x + CheckedUint32(aPicture.width);
CheckedUint32 yLimit = aPicture.y + CheckedUint32(aPicture.height);
- if (!xLimit.isValid() || xLimit.value() > aBuffer.mPlanes[0].mStride ||
+ if (!xLimit.isValid() || xLimit.value() > aBuffer.mPlanes[0].mWidth ||
!yLimit.isValid() || yLimit.value() > aBuffer.mPlanes[0].mHeight) {
// The specified picture dimensions can't be contained inside the video
// frame, we'll stomp memory if we try to copy it. Fail.
diff --git a/dom/media/webm/WebMDemuxer.cpp b/dom/media/webm/WebMDemuxer.cpp
index 3bf19b09cde..dfa3a39a28f 100644
--- a/dom/media/webm/WebMDemuxer.cpp
+++ b/dom/media/webm/WebMDemuxer.cpp
@@ -527,19 +527,19 @@ nsresult WebMDemuxer::ReadMetadata() {
mInfo.mVideo.mHDRMetadata = ParseWebMMasteringMetadata(params);
// Picture region, taking into account cropping, before scaling
- // to the display size.
- unsigned int cropH = params.crop_right + params.crop_left;
- unsigned int cropV = params.crop_bottom + params.crop_top;
- gfx::IntRect pictureRect(params.crop_left, params.crop_top,
- params.width - cropH, params.height - cropV);
-
- // If the cropping data appears invalid then use the frame data
- if (pictureRect.width <= 0 || pictureRect.height <= 0 ||
- pictureRect.x < 0 || pictureRect.y < 0) {
- pictureRect.x = 0;
- pictureRect.y = 0;
- pictureRect.width = params.width;
- pictureRect.height = params.height;
+ // to the display size. Default to the full frame and apply cropping only
+ // when it leaves a non-empty region within the frame.
+ gfx::IntRect pictureRect(0, 0, AssertedCast<int32_t>(params.width),
+ AssertedCast<int32_t>(params.height));
+ uint64_t cropH =
+ static_cast<uint64_t>(params.crop_left) + params.crop_right;
+ uint64_t cropV =
+ static_cast<uint64_t>(params.crop_top) + params.crop_bottom;
+ if (cropH < params.width && cropV < params.height) {
+ pictureRect.x = AssertedCast<int32_t>(params.crop_left);
+ pictureRect.y = AssertedCast<int32_t>(params.crop_top);
+ pictureRect.width = AssertedCast<int32_t>(params.width - cropH);
+ pictureRect.height = AssertedCast<int32_t>(params.height - cropV);
}
// Validate the container-reported frame and pictureRect sizes. This
diff --git a/gfx/layers/ImageContainer.cpp b/gfx/layers/ImageContainer.cpp
index 5cab470b982..901ced77a29 100644
--- a/gfx/layers/ImageContainer.cpp
+++ b/gfx/layers/ImageContainer.cpp
@@ -894,7 +894,13 @@ static void CopyPlane(uint8_t* aDst, const uint8_t* aSrc,
int32_t width = aSize.width;
const int32_t rowBytes = width * aBytesPerElement;
- MOZ_RELEASE_ASSERT(rowBytes <= aStride);
+ // The interleaved (aSkip != 0) path steps over skipped elements between
+ // pixels, so a row reaches further than the packed width. Computed with
+ // 64-bit arithmetic.
+ const int64_t srcRowSpan =
+ (static_cast<int64_t>(width) + static_cast<int64_t>(width - 1) * aSkip) *
+ aBytesPerElement;
+ MOZ_RELEASE_ASSERT(srcRowSpan <= aStride);
if (!aSkip) {
// Fast path: planar input.
Loading diff…
References
On This Page