High firefox Logic Error 🔧 Commit mapped

Overview

High
Severity
CVSS
No
Exploited ITW
Fixed
Fix Status
Impacthigh
DescriptionIncorrect boundary conditions in the Audio/Video: Playback component
ComponentDOM
Bug ClassLogic Error
Tracker2018102
Fix commitdc65876a5e48 (firefox) +25/-3
CISA KEVNot listed
CreditedSajeeb Lohani
Disclosed2026-03-24

Changed Functions

FunctionChangeNotes
if
dom/media/MediaData.cpp
modified
if
dom/media/platforms/agnostic/VPXDecoder.cpp
modified

Files Changed

  • dom/media/MediaData.cpp
  • dom/media/platforms/agnostic/VPXDecoder.cpp
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…