Firefox · DOM
CVE-2026-4693
Logic Error in DOM
Overview
High
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
ifdom/media/MediaData.cpp |
modified | |
ifdom/media/platforms/agnostic/VPXDecoder.cpp |
modified |
Files Changed
dom/media/MediaData.cppdom/media/platforms/agnostic/VPXDecoder.cpp
Patch
diff --git a/dom/media/MediaData.cpp b/dom/media/MediaData.cpp
index c6882efef1c..c58b60fb9ee 100644
--- a/dom/media/MediaData.cpp
+++ b/dom/media/MediaData.cpp
@@ -191,6 +191,19 @@ static bool ValidatePlane(const VideoData::YCbCrBuffer::Plane& aPlane) {
static MediaResult ValidateBufferAndPicture(
const VideoData::YCbCrBuffer& aBuffer, const IntRect& aPicture) {
+ // mChromaSubsampling describes the relationship between plane sizes.
+ if (aBuffer.mChromaSubsampling == ChromaSubsampling::FULL) {
+ MOZ_ASSERT(aBuffer.mPlanes[1].mWidth == aBuffer.mPlanes[0].mWidth);
+ } else {
+ MOZ_ASSERT(aBuffer.mPlanes[1].mWidth ==
+ (aBuffer.mPlanes[0].mWidth + 1) / 2);
+ }
+ if (aBuffer.mChromaSubsampling == ChromaSubsampling::HALF_WIDTH_AND_HEIGHT) {
+ MOZ_ASSERT(aBuffer.mPlanes[1].mHeight ==
+ (aBuffer.mPlanes[0].mHeight + 1) / 2);
+ } else {
+ MOZ_ASSERT(aBuffer.mPlanes[1].mHeight == aBuffer.mPlanes[0].mHeight);
+ }
// The following situation should never happen unless there is a bug
// in the decoder
if (aBuffer.mPlanes[1].mWidth != aBuffer.mPlanes[2].mWidth ||
@@ -198,7 +211,6 @@ static MediaResult ValidateBufferAndPicture(
return MediaResult(NS_ERROR_INVALID_ARG,
"Chroma planes with different sizes");
}
-
// The following situations could be triggered by invalid input
if (aPicture.width <= 0 || aPicture.height <= 0) {
return MediaResult(NS_ERROR_INVALID_ARG, "Empty picture rect");
@@ -208,7 +220,12 @@ static MediaResult ValidateBufferAndPicture(
!ValidatePlane(aBuffer.mPlanes[2])) {
return MediaResult(NS_ERROR_INVALID_ARG, "Invalid plane size");
}
-
+ // ConstructPlanarYCbCrData() and ConvertI420AlphaToARGB() assume Chroma
+ // planes have equal strides.
+ if (aBuffer.mPlanes[1].mStride != aBuffer.mPlanes[2].mStride) {
+ return MediaResult(NS_ERROR_INVALID_ARG,
+ "Chroma planes with different strides");
+ }
// Ensure the picture size specified in the headers can be extracted out of
// the frame we've been supplied without indexing out of bounds.
CheckedUint32 xLimit = aPicture.x + CheckedUint32(aPicture.width);
@@ -296,6 +313,7 @@ PlanarYCbCrData ConstructPlanarYCbCrData(const VideoInfo& aInfo,
data.mYSkip = AssertedCast<int32_t>(Y.mSkip);
data.mCbChannel = Cb.mData;
data.mCrChannel = Cr.mData;
+ MOZ_ASSERT(Cb.mStride == Cr.mStride);
data.mCbCrStride = AssertedCast<int32_t>(Cb.mStride);
data.mCbSkip = AssertedCast<int32_t>(Cb.mSkip);
data.mCrSkip = AssertedCast<int32_t>(Cr.mSkip);
diff --git a/dom/media/platforms/agnostic/VPXDecoder.cpp b/dom/media/platforms/agnostic/VPXDecoder.cpp
index 9bfabd6f8cc..b2cfea18250 100644
--- a/dom/media/platforms/agnostic/VPXDecoder.cpp
+++ b/dom/media/platforms/agnostic/VPXDecoder.cpp
@@ -200,13 +200,17 @@ RefPtr<MediaDataDecoder::DecodePromise> VPXDecoder::ProcessDecode(
if (img->fmt == VPX_IMG_FMT_I420) {
b.mChromaSubsampling = gfx::ChromaSubsampling::HALF_WIDTH_AND_HEIGHT;
-
+ MOZ_ASSERT(img->y_chroma_shift == 1);
b.mPlanes[1].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
+ MOZ_ASSERT(img->x_chroma_shift == 1);
b.mPlanes[1].mWidth = (img->d_w + 1) >> img->x_chroma_shift;
b.mPlanes[2].mHeight = (img->d_h + 1) >> img->y_chroma_shift;
b.mPlanes[2].mWidth = (img->d_w + 1) >> img->x_chroma_shift;
} else if (img->fmt == VPX_IMG_FMT_I444) {
+ MOZ_ASSERT(b.mChromaSubsampling == gfx::ChromaSubsampling::FULL);
+ MOZ_ASSERT(img->y_chroma_shift == 0);
+ MOZ_ASSERT(img->x_chroma_shift == 0);
b.mPlanes[1].mHeight = img->d_h;
b.mPlanes[1].mWidth = img->d_w;
Loading diff…
References
On This Page