Firefox · DOM
CVE-2026-16393
Logic Error in DOM
Overview
Medium
Severity
—
CVSS
No
Exploited ITW
Fixed
Fix Status
Changed Functions
| Function | Change | Notes |
|---|---|---|
fordom/webgpu/SharedTextureD3D11.cpp |
modified | |
ifdom/webgpu/SharedTextureD3D11.cpp |
modified | |
fordom/webgpu/SharedTextureDMABuf.cpp |
modified | |
ifdom/webgpu/SharedTextureDMABuf.cpp |
modified | |
fordom/webgpu/SharedTextureMacIOSurface.cpp |
modified | |
ifdom/webgpu/SharedTextureMacIOSurface.cpp |
modified | |
fordom/webgpu/ipc/WebGPUParent.cpp |
modified | |
ifdom/webgpu/ipc/WebGPUParent.cpp |
modified | |
forgfx/layers/RemoteTextureMap.cpp |
modified | |
ifgfx/layers/RemoteTextureMap.cpp |
modified |
Files Changed
dom/webgpu/SharedTextureD3D11.cppdom/webgpu/SharedTextureDMABuf.cppdom/webgpu/SharedTextureMacIOSurface.cppdom/webgpu/ipc/WebGPUParent.cppgfx/layers/RemoteTextureMap.cpp
Patch
diff --git a/dom/webgpu/SharedTextureD3D11.cpp b/dom/webgpu/SharedTextureD3D11.cpp
index e5d27e77898..87619a1c747 100644
--- a/dom/webgpu/SharedTextureD3D11.cpp
+++ b/dom/webgpu/SharedTextureD3D11.cpp
@@ -206,11 +206,15 @@ void SharedTextureD3D11::GetSnapshot(const ipc::Shmem& aDestShmem,
uint8_t* dst = aDestShmem.get<uint8_t>();
const size_t src_stride = static_cast<size_t>(map.RowPitch);
- // note that this might still copy some padding bytes
- const size_t min_stride = std::min(src_stride, aDestStride);
+ const size_t bytesPerRow = static_cast<size_t>(mWidth) * 4;
+ MOZ_RELEASE_ASSERT(src_stride >= bytesPerRow);
+ MOZ_RELEASE_ASSERT(aDestStride >= bytesPerRow);
for (uint32_t y = 0; y < mHeight; y++) {
- memcpy(dst, src, min_stride);
+ memcpy(dst, src, bytesPerRow);
+ if (bytesPerRow < aDestStride) {
+ memset(dst + bytesPerRow, 0, aDestStride - bytesPerRow);
+ }
src += src_stride;
dst += aDestStride;
}
diff --git a/dom/webgpu/SharedTextureDMABuf.cpp b/dom/webgpu/SharedTextureDMABuf.cpp
index bdd1c84886c..7ce3c967808 100644
--- a/dom/webgpu/SharedTextureDMABuf.cpp
+++ b/dom/webgpu/SharedTextureDMABuf.cpp
@@ -146,11 +146,15 @@ void SharedTextureDMABuf::GetSnapshot(const ipc::Shmem& aDestShmem,
uint8_t* dst = aDestShmem.get<uint8_t>();
const size_t src_stride = static_cast<size_t>(map.GetStride());
- // note that this might still copy some padding bytes
- const size_t min_stride = std::min(src_stride, aDestStride);
+ const size_t bytesPerRow = static_cast<size_t>(mWidth) * 4;
+ MOZ_RELEASE_ASSERT(src_stride >= bytesPerRow);
+ MOZ_RELEASE_ASSERT(aDestStride >= bytesPerRow);
for (uint32_t y = 0; y < mHeight; y++) {
- memcpy(dst, src, min_stride);
+ memcpy(dst, src, bytesPerRow);
+ if (bytesPerRow < aDestStride) {
+ memset(dst + bytesPerRow, 0, aDestStride - bytesPerRow);
+ }
src += src_stride;
dst += aDestStride;
}
diff --git a/dom/webgpu/SharedTextureMacIOSurface.cpp b/dom/webgpu/SharedTextureMacIOSurface.cpp
index 1dd14953558..874449a0f94 100644
--- a/dom/webgpu/SharedTextureMacIOSurface.cpp
+++ b/dom/webgpu/SharedTextureMacIOSurface.cpp
@@ -85,16 +85,20 @@ void SharedTextureMacIOSurface::GetSnapshot(const ipc::Shmem& aDestShmem,
return;
}
- const size_t bytesPerRow = mSurface->GetBytesPerRow();
+ const size_t src_stride = mSurface->GetBytesPerRow();
uint8_t* src = (uint8_t*)mSurface->GetBaseAddress();
uint8_t* dst = aDestShmem.get<uint8_t>();
- // note that this might still copy some padding bytes
- const size_t min_stride = std::min(bytesPerRow, aDestStride);
+ const size_t bytesPerRow = static_cast<size_t>(mWidth) * 4;
+ MOZ_RELEASE_ASSERT(src_stride >= bytesPerRow);
+ MOZ_RELEASE_ASSERT(aDestStride >= bytesPerRow);
for (uint32_t y = 0; y < mHeight; y++) {
- memcpy(dst, src, min_stride);
- src += bytesPerRow;
+ memcpy(dst, src, bytesPerRow);
+ if (bytesPerRow < aDestStride) {
+ memset(dst + bytesPerRow, 0, aDestStride - bytesPerRow);
+ }
+ src += src_stride;
dst += aDestStride;
}
diff --git a/dom/webgpu/ipc/WebGPUParent.cpp b/dom/webgpu/ipc/WebGPUParent.cpp
index 556757ee03b..660ef6a6949 100644
--- a/dom/webgpu/ipc/WebGPUParent.cpp
+++ b/dom/webgpu/ipc/WebGPUParent.cpp
@@ -1078,19 +1078,25 @@ static void ReadbackPresentCallback(uint8_t* userdata,
uint8_t* src = mapped.ptr;
uint8_t* dst = mappedData.data;
- const uint32_t dst_stride = mappedData.stride;
+ const size_t dst_stride = static_cast<size_t>(mappedData.stride);
// `mappedData.stride` is computed via
// `ImageDataSerializer::ComputeRGBStride` and returns 0 if it overflows
MOZ_RELEASE_ASSERT(dst_stride != 0);
- // note that this might still copy some padding bytes
- const uint32_t min_stride = std::min(data->mBufferStride, dst_stride);
+ const size_t src_stride = static_cast<size_t>(data->mBufferStride);
+ const size_t bytesPerRow =
+ static_cast<size_t>(data->mDesc.size().width) * 4;
+ MOZ_RELEASE_ASSERT(src_stride >= bytesPerRow);
+ MOZ_RELEASE_ASSERT(dst_stride >= bytesPerRow);
// The height is in bounds for both buffers since we just requested a new
// destination buffer with the same height of the source.
for (auto row = 0; row < size.height; ++row) {
- memcpy(dst, src, min_stride);
- src += data->mBufferStride;
+ memcpy(dst, src, bytesPerRow);
+ if (bytesPerRow < dst_stride) {
+ memset(dst + bytesPerRow, 0, dst_stride - bytesPerRow);
+ }
+ src += src_stride;
dst += dst_stride;
}
req->mRemoteTextureOwner->PushTexture(req->mTextureId, req->mOwnerId,
@@ -1176,13 +1182,17 @@ static void ReadbackSnapshotCallback(uint8_t* userdata,
uint8_t* dst = req->mDestShmem.get<uint8_t>();
const size_t src_stride = static_cast<size_t>(data->mBufferStride);
- // note that this might still copy some padding bytes
- const size_t min_stride = std::min(src_stride, req->mDestStride);
+ const size_t bytesPerRow = static_cast<size_t>(data->mDesc.size().width) * 4;
+ MOZ_RELEASE_ASSERT(src_stride >= bytesPerRow);
+ MOZ_RELEASE_ASSERT(req->mDestStride >= bytesPerRow);
// The height is in bounds for both buffers since we previously created a new
// destination buffer with the same height of the source.
for (auto row = 0; row < data->mDesc.size().height; ++row) {
- memcpy(dst, src, min_stride);
+ memcpy(dst, src, bytesPerRow);
+ if (bytesPerRow < req->mDestStride) {
+ memset(dst + bytesPerRow, 0, req->mDestStride - bytesPerRow);
+ }
src += src_stride;
dst += req->mDestStride;
}
diff --git a/gfx/layers/RemoteTextureMap.cpp b/gfx/layers/RemoteTextureMap.cpp
index 3635a685505..ae65668d34f 100644
--- a/gfx/layers/RemoteTextureMap.cpp
+++ b/gfx/layers/RemoteTextureMap.cpp
@@ -557,15 +557,20 @@ void RemoteTextureMap::GetLatestBufferSnapshot(
uint8_t* src = bufferTextureHost->GetBuffer();
uint8_t* dst = aDestShmem.get<uint8_t>();
- const Maybe<int32_t> src_stride = ImageDataSerializer::GetRGBStride(
+ const Maybe<int32_t> maybe_src_stride = ImageDataSerializer::GetRGBStride(
bufferTextureHost->GetBufferDescriptor());
- MOZ_RELEASE_ASSERT(src_stride.isSome());
- // note that this might still copy some padding bytes
- const size_t min_stride = std::min(size_t(src_stride.value()), aDestStride);
+ MOZ_RELEASE_ASSERT(maybe_src_stride.isSome());
+ const size_t src_stride = static_cast<size_t>(maybe_src_stride.value());
+ const size_t bytesPerRow = static_cast<size_t>(src_size.width) * 4;
+ MOZ_RELEASE_ASSERT(src_stride >= bytesPerRow);
+ MOZ_RELEASE_ASSERT(aDestStride >= bytesPerRow);
for (int y = 0; y < src_size.height; y++) {
- memcpy(dst, src, min_stride);
- src += src_stride.value();
+ memcpy(dst, src, bytesPerRow);
+ if (bytesPerRow < aDestStride) {
+ memset(dst + bytesPerRow, 0, aDestStride - bytesPerRow);
+ }
+ src += src_stride;
dst += aDestStride;
}
}
Loading diff…
References
On This Page